diff --git a/Core.Thalos.BuildingBlocks/Adapters/Base/BaseAdapterResponse.cs b/Core.Thalos.BuildingBlocks/Adapters/Base/BaseAdapterResponse.cs index aa41634..c5e1fca 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/Base/BaseAdapterResponse.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/Base/BaseAdapterResponse.cs @@ -1,11 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Threading.Tasks; +using System.Text.Json; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { public class BaseAdapterResponse { diff --git a/Core.Thalos.BuildingBlocks/Adapters/ModuleAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/ModuleAdapter.cs index de5c66d..9dbbb54 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/ModuleAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/ModuleAdapter.cs @@ -5,12 +5,11 @@ // *********************************************************************** using Core.Blueprint.Mongo; -using Core.Thalos.Adapters.Common.Enums; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { /// /// Adapter for representing a module. diff --git a/Core.Thalos.BuildingBlocks/Adapters/PermissionAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/PermissionAdapter.cs index 99907f2..3c2dccf 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/PermissionAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/PermissionAdapter.cs @@ -5,12 +5,11 @@ // *********************************************************************** using Core.Blueprint.Mongo; -using Core.Thalos.Adapters.Common.Constants; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { /// /// Adapter for representing a permission. diff --git a/Core.Thalos.BuildingBlocks/Handlers/Adapters/PermissionsAuthorizationAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/PermissionsAuthorizationAdapter.cs similarity index 86% rename from Core.Thalos.BuildingBlocks/Handlers/Adapters/PermissionsAuthorizationAdapter.cs rename to Core.Thalos.BuildingBlocks/Adapters/PermissionsAuthorizationAdapter.cs index 1a057b9..44d19d9 100644 --- a/Core.Thalos.BuildingBlocks/Handlers/Adapters/PermissionsAuthorizationAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/PermissionsAuthorizationAdapter.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Authorization; -namespace Core.Thalos.Adapters.Handlers.Adapters +namespace Core.Thalos.BuildingBlocks { public class PermissionsAuthorizationAdapter : IAuthorizationRequirement { diff --git a/Core.Thalos.BuildingBlocks/Adapters/RoleAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/RoleAdapter.cs index 75e7441..6164721 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/RoleAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/RoleAdapter.cs @@ -5,12 +5,11 @@ // *********************************************************************** using Core.Blueprint.Mongo; -using Core.Thalos.Adapters.Common.Enums; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { /// /// Adapter representing a role. diff --git a/Core.Thalos.BuildingBlocks/Adapters/TokenAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/TokenAdapter.cs index 665d20c..c8e5da5 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/TokenAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/TokenAdapter.cs @@ -4,7 +4,7 @@ // // *********************************************************************** -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { public class TokenAdapter { diff --git a/Core.Thalos.BuildingBlocks/Adapters/UserAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/UserAdapter.cs index 9a90a64..4c033bf 100644 --- a/Core.Thalos.BuildingBlocks/Adapters/UserAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/UserAdapter.cs @@ -8,7 +8,7 @@ using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { /// /// Adapter representing a user. diff --git a/Core.Thalos.BuildingBlocks/UserExistenceAdapter.cs b/Core.Thalos.BuildingBlocks/Adapters/UserExistenceAdapter.cs similarity index 93% rename from Core.Thalos.BuildingBlocks/UserExistenceAdapter.cs rename to Core.Thalos.BuildingBlocks/Adapters/UserExistenceAdapter.cs index de35a4f..25a7c60 100644 --- a/Core.Thalos.BuildingBlocks/UserExistenceAdapter.cs +++ b/Core.Thalos.BuildingBlocks/Adapters/UserExistenceAdapter.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { /// /// Adapter representing a user. diff --git a/Core.Thalos.BuildingBlocks/Attributes/Permission.cs b/Core.Thalos.BuildingBlocks/Attributes/Permission.cs index 5ec6723..effdc17 100644 --- a/Core.Thalos.BuildingBlocks/Attributes/Permission.cs +++ b/Core.Thalos.BuildingBlocks/Attributes/Permission.cs @@ -1,4 +1,4 @@ -namespace Core.Thalos.Adapters +namespace Core.Thalos.BuildingBlocks { public class Permission { diff --git a/Core.Thalos.BuildingBlocks/Attributes/PermissionAttribute.cs b/Core.Thalos.BuildingBlocks/Attributes/PermissionAttribute.cs index dce03f9..2346767 100644 --- a/Core.Thalos.BuildingBlocks/Attributes/PermissionAttribute.cs +++ b/Core.Thalos.BuildingBlocks/Attributes/PermissionAttribute.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; -namespace Core.Thalos.Adapters.Attributes +namespace Core.Thalos.BuildingBlocks { /// /// Custom authorization attribute that checks if the user has any of the required permissions. diff --git a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/GoogleAuthorization.cs b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/GoogleAuthorization.cs index 199a870..df52cc1 100644 --- a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/GoogleAuthorization.cs +++ b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/GoogleAuthorization.cs @@ -1,9 +1,8 @@ -using Core.Thalos.BuildingBlocks.Authentication.Helpers; -using Google.Apis.Auth.OAuth2; +using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2.Flows; using Microsoft.Extensions.Configuration; -namespace Core.Thalos.BuildingBlocks.Authentication.Authorization.Google +namespace Core.Thalos.BuildingBlocks { public class GoogleAuthorization( IGoogleAuthHelper googleHelper, IConfiguration config) : IGoogleAuthorization diff --git a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/IGoogleAuthorization.cs b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/IGoogleAuthorization.cs index 9827aab..a8a6bf5 100644 --- a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/IGoogleAuthorization.cs +++ b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Google/IGoogleAuthorization.cs @@ -1,6 +1,6 @@ using Google.Apis.Auth.OAuth2; -namespace Core.Thalos.BuildingBlocks.Authentication.Authorization.Google +namespace Core.Thalos.BuildingBlocks { public interface IGoogleAuthorization { diff --git a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionAuthorizationAdapter.cs b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionAuthorizationAdapter.cs deleted file mode 100644 index 0bbb5d0..0000000 --- a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionAuthorizationAdapter.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Microsoft.AspNetCore.Authorization; - -namespace Core.Thalos.BuildingBlocks.Authentication.Authorization.Jwt -{ - public class PermissionAuthorizationAdapter(string[] permission) : IAuthorizationRequirement - { - public string[] Permission { get; } = permission ?? throw new ArgumentNullException(nameof(permission)); - } -} diff --git a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionsAuthorizationHandler.cs b/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionsAuthorizationHandler.cs deleted file mode 100644 index eaca04c..0000000 --- a/Core.Thalos.BuildingBlocks/Authentication/Authorization/Jwt/PermissionsAuthorizationHandler.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.AspNetCore.Authorization; - -namespace Core.Thalos.BuildingBlocks.Authentication.Authorization.Jwt -{ - public class PermissionsAuthorizationHandler : AuthorizationHandler - { - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionAuthorizationAdapter requirement) - { - PermissionAuthorizationAdapter requirement2 = requirement; - if (context.User.Claims.Any((x) => x.Type == "roleId" && requirement2.Permission.Contains(x.Value))) - { - context.Succeed(requirement2); - } - - return Task.CompletedTask; - } - } -} diff --git a/Core.Thalos.BuildingBlocks/Authentication/Extensions/AuthenticationExtension.cs b/Core.Thalos.BuildingBlocks/Authentication/Extensions/AuthenticationExtension.cs deleted file mode 100644 index f2b1daf..0000000 --- a/Core.Thalos.BuildingBlocks/Authentication/Extensions/AuthenticationExtension.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Options; -using Core.Thalos.BuildingBlocks.Authentication.Authorization.Google; -using Core.Thalos.BuildingBlocks.Authentication.Authorization.Jwt; -using Core.Thalos.BuildingBlocks.Authentication.Handlers; -using Core.Thalos.BuildingBlocks.Authentication.Helpers; -using Core.Thalos.BuildingBlocks.Common.Constants; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.IdentityModel.Tokens; -using System.Text; - -namespace Core.Thalos.BuildingBlocks.Authentication.Extensions -{ - /// - /// Extension methods for configuring authentication with various Google and JWT setups. - /// - public static class AuthenticationExtension - { - /// - /// Configures authentication using Google Auth for an API that requires downstream API access. - /// - /// The to add the services to. - /// The containing Google Auth configuration settings. - public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration) - { - var secretKey = configuration.GetSection("SecretKey").Value ?? string.Empty; - var _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey)); - var jwtAppSettingsOptions = configuration.GetSection(nameof(JwtIssuerOptions)); - var jwtIssuerOptions = jwtAppSettingsOptions.Get(); - - var googleClientId = configuration["Authentication:Google:ClientId"]; - var googleClientSecret = configuration["Authentication:Google:ClientSecret"]; - var redirectUri = configuration["Authentication:Google:RedirectUri"]; - - services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = Schemes.GoogleScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddScheme(Schemes.GoogleScheme, null) - .AddGoogle(options => - { - options.ClientId = googleClientId!; - options.ClientSecret = googleClientSecret!; - //options.SaveTokens = true; - options.CallbackPath = $"/{redirectUri}"; - }) - .AddJwtBearer(Schemes.DefaultScheme, x => - { - x.TokenValidationParameters = new TokenValidationParameters - { - ValidIssuer = jwtIssuerOptions?.Issuer, - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - ValidAudience = jwtIssuerOptions?.Audience, - IssuerSigningKey = new SymmetricSecurityKey( - Encoding.UTF8.GetBytes(configuration["SecretKey"] ?? string.Empty)) - }; - }); - - services.Configure(options => - { - options.Issuer = jwtAppSettingsOptions[nameof(jwtIssuerOptions.Issuer)] ?? string.Empty; - options.Audience = jwtAppSettingsOptions[nameof(jwtIssuerOptions.Audience)] ?? string.Empty; - options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256); - }); - - services.AddSingleton(jwtAppSettingsOptions); - - string[] roles = { Roles.Guest, Roles.Admin }; - - services.AddAuthorization(options => - { - options.AddPolicy(Policies.Read, policy => policy.Requirements.Add(new PermissionAuthorizationAdapter(roles))); - options.AddPolicy(Policies.Write, policy => policy.Requirements.Add(new PermissionAuthorizationAdapter(roles))); - }); - - services.AddTransient(); - - services.AddAuthorization(); - services.AddScoped(); - services.AddScoped(); - } - } -} diff --git a/Core.Thalos.BuildingBlocks/Authentication/Extensions/SwaggerExtension.cs b/Core.Thalos.BuildingBlocks/Authentication/Extensions/SwaggerExtension.cs deleted file mode 100644 index e6b9379..0000000 --- a/Core.Thalos.BuildingBlocks/Authentication/Extensions/SwaggerExtension.cs +++ /dev/null @@ -1,84 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Interfaces; -using Microsoft.OpenApi.Models; - -namespace Core.Thalos.BuildingBlocks.Authentication.Extensions -{ - public static class SwaggerExtension - { - public static void AddSwaggerGen(this IServiceCollection services, IConfiguration configuration) - { - services.AddSwaggerGen(opts => - { - const string schemeName = "oauth2"; - - opts.AddSecurityDefinition(schemeName, new OpenApiSecurityScheme - { - Type = SecuritySchemeType.OAuth2, - Scheme = "bearer", - BearerFormat = "JWT", - Name = "Authorization", - In = ParameterLocation.Header, - - Extensions = new Dictionary - { - ["x-tokenName"] = new OpenApiString("id_token") - }, - - Flows = new OpenApiOAuthFlows - { - AuthorizationCode = new OpenApiOAuthFlow - { - AuthorizationUrl = new Uri("https://accounts.google.com/o/oauth2/v2/auth"), - TokenUrl = new Uri("https://oauth2.googleapis.com/token"), - Scopes = new Dictionary - { - { "openid", "OpenID Connect" }, - { "email", "Access email" }, - { "profile", "Access profile" } - } - } - } - }); - - // every operation requires the scheme - opts.AddSecurityRequirement(new OpenApiSecurityRequirement - { - [new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { Type = ReferenceType.SecurityScheme, Id = schemeName } - } - ] = new[] { "openid", "email", "profile" } - }); - - opts.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - Description = "JWT Authorization header using the Bearer scheme", - Name = "Authorization", - In = ParameterLocation.Header, - Type = SecuritySchemeType.Http, - Scheme = "bearer", - BearerFormat = "JWT" - }); - - opts.AddSecurityRequirement(new OpenApiSecurityRequirement - { - { - new OpenApiSecurityScheme - { - Reference = new OpenApiReference - { - Type = ReferenceType.SecurityScheme, - Id = "Bearer" - } - }, - Array.Empty() - } - }); - }); - } - } -} diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/AccessLevelEnum.cs b/Core.Thalos.BuildingBlocks/Common/Constants/AccessLevelEnum.cs index efee073..f812e95 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/AccessLevelEnum.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/AccessLevelEnum.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Specifies different access level for a permission. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/AzureAd.cs b/Core.Thalos.BuildingBlocks/Common/Constants/AzureAd.cs index f93804e..bc12fda 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/AzureAd.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/AzureAd.cs @@ -3,7 +3,7 @@ // AgileWebs // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for Azure Active Directory. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Claims.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Claims.cs index 410edab..b50ac6c 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Claims.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Claims.cs @@ -3,7 +3,7 @@ // AgileWebs // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for claims used in JWT tokens. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/CollectionNames.cs b/Core.Thalos.BuildingBlocks/Common/Constants/CollectionNames.cs index ce4d39b..47f87c0 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/CollectionNames.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/CollectionNames.cs @@ -1,4 +1,4 @@ -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { public static class CollectionNames { diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/EnvironmentVariables.cs b/Core.Thalos.BuildingBlocks/Common/Constants/EnvironmentVariables.cs index 85a1fc1..d7a19dc 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/EnvironmentVariables.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/EnvironmentVariables.cs @@ -4,7 +4,7 @@ // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants of the environment variables for this service. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/KeyVaultConfiguration.cs b/Core.Thalos.BuildingBlocks/Common/Constants/KeyVaultConfiguration.cs index ea6b590..d3efbc5 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/KeyVaultConfiguration.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/KeyVaultConfiguration.cs @@ -3,7 +3,7 @@ // AgileWebs // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for Key Vault configuration. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/MimeTypes.cs b/Core.Thalos.BuildingBlocks/Common/Constants/MimeTypes.cs index 97e79ee..10c9130 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/MimeTypes.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/MimeTypes.cs @@ -6,7 +6,7 @@ using System.Globalization; -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for the mime types. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Policies.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Policies.cs index aa7c248..edcb784 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Policies.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Policies.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -namespace Core.Thalos.BuildingBlocks.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for policy. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Roles.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Roles.cs index 023b651..58e968d 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Roles.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Roles.cs @@ -1,4 +1,4 @@ -namespace Core.Thalos.BuildingBlocks.Common.Constants +namespace Core.Thalos.BuildingBlocks { public class Roles { diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Routes.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Routes.cs index d6628b1..dea1289 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Routes.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Routes.cs @@ -4,7 +4,7 @@ // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants of the routes of this service. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Schemes.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Schemes.cs index 268a42a..750d62b 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Schemes.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Schemes.cs @@ -1,4 +1,4 @@ -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for schemes. diff --git a/Core.Thalos.BuildingBlocks/Common/Constants/Secrets.cs b/Core.Thalos.BuildingBlocks/Common/Constants/Secrets.cs index 94f911e..4a221ee 100644 --- a/Core.Thalos.BuildingBlocks/Common/Constants/Secrets.cs +++ b/Core.Thalos.BuildingBlocks/Common/Constants/Secrets.cs @@ -3,7 +3,7 @@ // AgileWebs // // *********************************************************************** -namespace Core.Thalos.Adapters.Common.Constants +namespace Core.Thalos.BuildingBlocks { /// /// Constants for secrets in azure key vault. @@ -23,12 +23,12 @@ namespace Core.Thalos.Adapters.Common.Constants /// /// The Issuer parameter for JWT settings. /// - public const string Issuer = "Issuer"; + public const string Issuer = "JWTIssuer"; /// /// The Audience parameter for JWT settings. /// - public const string Audience = "Audience"; + public const string Audience = "JWTAudience"; /// /// The TokenExpirationInMinutes parameter for JWT settings. @@ -55,5 +55,8 @@ namespace Core.Thalos.Adapters.Common.Constants public const string ThalosAppScope = "Swagger:Scope"; public const string PrivateKey = "JwtTokenPrivateKey"; public const string PublicKey = "JwtTokenPublicKey"; + public const string GoogleClientId = "GoogleClientId"; + public const string GoogleClientSecret = "GoogleClientSecret"; + public const string GoogleRedirectUri = "GoogleRedirectUri"; } } diff --git a/Core.Thalos.BuildingBlocks/Common/Enums/ApplicationsEnum.cs b/Core.Thalos.BuildingBlocks/Common/Enums/ApplicationsEnum.cs index b1dac37..0c83e40 100644 --- a/Core.Thalos.BuildingBlocks/Common/Enums/ApplicationsEnum.cs +++ b/Core.Thalos.BuildingBlocks/Common/Enums/ApplicationsEnum.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters.Common.Enums +namespace Core.Thalos.BuildingBlocks { /// /// Defines the applications associated with the role. diff --git a/Core.Thalos.BuildingBlocks/Common/Enums/StatusEnum.cs b/Core.Thalos.BuildingBlocks/Common/Enums/StatusEnum.cs index 1e70864..da9c7ea 100644 --- a/Core.Thalos.BuildingBlocks/Common/Enums/StatusEnum.cs +++ b/Core.Thalos.BuildingBlocks/Common/Enums/StatusEnum.cs @@ -6,7 +6,7 @@ using System.Text.Json.Serialization; -namespace Core.Thalos.Adapters.Common.Enums +namespace Core.Thalos.BuildingBlocks { /// /// Defines the status of an entity. diff --git a/Core.Thalos.BuildingBlocks/Authentication/Helpers/IGoogleAuthHelper.cs b/Core.Thalos.BuildingBlocks/Contracts/IGoogleAuthHelper.cs similarity index 76% rename from Core.Thalos.BuildingBlocks/Authentication/Helpers/IGoogleAuthHelper.cs rename to Core.Thalos.BuildingBlocks/Contracts/IGoogleAuthHelper.cs index cac6350..e862cfa 100644 --- a/Core.Thalos.BuildingBlocks/Authentication/Helpers/IGoogleAuthHelper.cs +++ b/Core.Thalos.BuildingBlocks/Contracts/IGoogleAuthHelper.cs @@ -1,6 +1,6 @@ using Google.Apis.Auth.OAuth2; -namespace Core.Thalos.BuildingBlocks.Authentication.Helpers +namespace Core.Thalos.BuildingBlocks { public interface IGoogleAuthHelper { diff --git a/Core.Thalos.BuildingBlocks/Contracts/ITokenProvider.cs b/Core.Thalos.BuildingBlocks/Contracts/ITokenProvider.cs index 14c4564..55931ec 100644 --- a/Core.Thalos.BuildingBlocks/Contracts/ITokenProvider.cs +++ b/Core.Thalos.BuildingBlocks/Contracts/ITokenProvider.cs @@ -4,7 +4,7 @@ // // *********************************************************************** -namespace Core.Thalos.Adapters.Contracts +namespace Core.Thalos.BuildingBlocks { /// /// Interface for token provider. diff --git a/Core.Thalos.BuildingBlocks/Contracts/ITokenService.cs b/Core.Thalos.BuildingBlocks/Contracts/ITokenService.cs index 4c50048..7793572 100644 --- a/Core.Thalos.BuildingBlocks/Contracts/ITokenService.cs +++ b/Core.Thalos.BuildingBlocks/Contracts/ITokenService.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -namespace Core.Thalos.Adapters.Contracts +namespace Core.Thalos.BuildingBlocks { /// /// Interface for authenticacion service. diff --git a/Core.Thalos.BuildingBlocks/Core.Thalos.BuildingBlocks.csproj b/Core.Thalos.BuildingBlocks/Core.Thalos.BuildingBlocks.csproj index cf01555..081207a 100644 --- a/Core.Thalos.BuildingBlocks/Core.Thalos.BuildingBlocks.csproj +++ b/Core.Thalos.BuildingBlocks/Core.Thalos.BuildingBlocks.csproj @@ -14,12 +14,14 @@ + + @@ -33,4 +35,8 @@ + + + + diff --git a/Core.Thalos.BuildingBlocks/Extensions/AuthenticationExtension.cs b/Core.Thalos.BuildingBlocks/Extensions/AuthenticationExtension.cs index ced7b87..7f4b403 100644 --- a/Core.Thalos.BuildingBlocks/Extensions/AuthenticationExtension.cs +++ b/Core.Thalos.BuildingBlocks/Extensions/AuthenticationExtension.cs @@ -4,20 +4,17 @@ // // *********************************************************************** -using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Contracts; -using Core.Thalos.Adapters.Handlers; -using Core.Thalos.Adapters.Options; -using Core.Thalos.Adapters.Services; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Microsoft.Identity.Web; using Microsoft.IdentityModel.Tokens; using System.Security.Cryptography; -namespace Core.Thalos.Adapters.Extensions +namespace Core.Thalos.BuildingBlocks.Configuration { /// /// Extension methods for configuring authentication with various Azure AD setups. @@ -33,36 +30,38 @@ namespace Core.Thalos.Adapters.Extensions { var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; - var azureAdInMemorySettings = new Dictionary - { - { "AzureAdB2C:Instance", authSettings.AzureADInstance ?? string.Empty }, - { "AzureAdB2C:TenantId", authSettings.AzureADTenantId ?? string.Empty }, - { "AzureAdB2C:ClientId", authSettings.AzureADClientId ?? string.Empty }, - { "AzureAdB2C:ClientSecret", authSettings.AzureADClientSecret ?? string.Empty } - }; + var identityProviders = new IdentityProviders(); + configuration.GetSection("IdentityProviders").Bind(identityProviders); - var configurationBuilder = new ConfigurationBuilder() - .AddConfiguration(configuration) - .AddInMemoryCollection(azureAdInMemorySettings); + AddCustomAuthentication(services, authSettings.Token); - var combinedConfiguration = configurationBuilder.Build(); + if (identityProviders.Azure) + AddAzureAuthentication(authSettings, configuration, services); - services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) - .AddMicrosoftIdentityWebApi(combinedConfiguration.GetSection("AzureAdB2C"), Schemes.AzureScheme) - .EnableTokenAcquisitionToCallDownstreamApi() - .AddMicrosoftGraph(configuration.GetSection("MicrosoftGraph")) - .AddInMemoryTokenCaches(); + if (identityProviders.Google) + AddGoogleAuthentication(services, authSettings.Google); + services.AddAuthorization(); + services.AddTransient(); + services.AddTransient(); + } + + public static void AddCustomAuthentication(IServiceCollection services, TokenAuthSettings tokenAuthSettings) + { var rsa = RSA.Create(); - rsa.ImportFromPem(authSettings.PrivateKey?.ToCharArray()); + rsa.ImportFromPem(tokenAuthSettings.PrivateKey?.ToCharArray()); var rsaPrivateKey = new RsaSecurityKey(rsa); var rsaPublic = RSA.Create(); - rsaPublic.ImportFromPem(authSettings.PublicKey?.ToCharArray()); + rsaPublic.ImportFromPem(tokenAuthSettings.PublicKey?.ToCharArray()); var rsaPublicKey = new RsaSecurityKey(rsaPublic); - var jwtAppSettingOptions = configuration.GetSection("B2C:JwtIssuerOptions"); - var jwtIssuerOptions = jwtAppSettingOptions.Get(); + + var jwtIssuerOptions = new JwtIssuerOptions + { + Audience = tokenAuthSettings.Audience, + Issuer = tokenAuthSettings.Issuer, + }; if (string.IsNullOrEmpty(jwtIssuerOptions?.Issuer) || string.IsNullOrEmpty(jwtIssuerOptions.Audience)) throw new InvalidOperationException("JwtIssuerOptions are not configured correctly."); @@ -89,9 +88,51 @@ namespace Core.Thalos.Adapters.Extensions options.SigningCredentials = new SigningCredentials(rsaPrivateKey, SecurityAlgorithms.RsaSha256); }); - services.AddSingleton(jwtAppSettingOptions); - services.AddTransient(); - services.AddTransient(); + services.AddSingleton>(Microsoft.Extensions.Options.Options.Create(jwtIssuerOptions)); + } + + public static void AddAzureAuthentication(AuthSettings authSettings, IConfiguration configuration, IServiceCollection services) + { + var azureAdInMemorySettings = new Dictionary + { + { "AzureAdB2C:Instance", authSettings.Azure.Instance ?? string.Empty }, + { "AzureAdB2C:TenantId", authSettings.Azure.TenantId ?? string.Empty }, + { "AzureAdB2C:ClientId", authSettings.Azure.ClientId ?? string.Empty }, + { "AzureAdB2C:ClientSecret", authSettings.Azure.ClientSecret ?? string.Empty } + }; + + var configurationBuilder = new ConfigurationBuilder() + .AddConfiguration(configuration) + .AddInMemoryCollection(azureAdInMemorySettings); + + var combinedConfiguration = configurationBuilder.Build(); + + services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddMicrosoftIdentityWebApi(combinedConfiguration.GetSection("AzureAdB2C"), Schemes.AzureScheme) + .EnableTokenAcquisitionToCallDownstreamApi() + .AddMicrosoftGraph(configuration.GetSection("MicrosoftGraph")) + .AddInMemoryTokenCaches(); + } + + public static void AddGoogleAuthentication(IServiceCollection services, GoogleAuthSettings googleAuthSettings) + { + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = Schemes.GoogleScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddScheme(Schemes.GoogleScheme, null) + .AddGoogle(options => + { + options.ClientId = googleAuthSettings.ClientId!; + options.ClientSecret = googleAuthSettings.ClientSecret!; + //options.SaveTokens = true; + options.CallbackPath = $"/{googleAuthSettings.RedirectUri}"; + }); + + services.AddScoped(); + services.AddScoped(); } } } diff --git a/Core.Thalos.BuildingBlocks/Extensions/SwaggerExtensions.cs b/Core.Thalos.BuildingBlocks/Extensions/SwaggerExtensions.cs index d4b7ecd..1f73ba5 100644 --- a/Core.Thalos.BuildingBlocks/Extensions/SwaggerExtensions.cs +++ b/Core.Thalos.BuildingBlocks/Extensions/SwaggerExtensions.cs @@ -5,8 +5,6 @@ // *********************************************************************** using Asp.Versioning.ApiExplorer; -using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Extensions; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -16,7 +14,7 @@ using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Swashbuckle.AspNetCore.SwaggerUI; -namespace Core.Thalos.Adapters.Extensions +namespace Core.Thalos.BuildingBlocks.Configuration { /// /// Extension methods for configuring Swagger documentation and UI. @@ -40,71 +38,115 @@ namespace Core.Thalos.Adapters.Extensions /// /// The to add the services to. /// The containing Swagger and OAuth2 configuration settings. - public static void AddSwaggerGen(this IServiceCollection services, IConfiguration configuration, string DocumentationFile, AuthSettings authSettings) + public static void AddSwaggerGen( + this IServiceCollection services, + IConfiguration configuration, + string documentationFile, + AuthSettings authSettings) { + var identityProviders = new IdentityProviders(); + configuration.GetSection("IdentityProviders").Bind(identityProviders); + services.AddSwaggerGen(c => + { + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { - c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme + Description = "JWT Authorization header using the Bearer scheme", + Name = "Authorization", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + Scheme = "bearer", + BearerFormat = "JWT" + }); + + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { - Description = "OAuth2.0 Authorization Code flow", - Name = "oauth2.0", + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + Array.Empty() + } + }); + + if (identityProviders.Azure) + { + const string azureScheme = "oauth2-Azure"; + + c.AddSecurityDefinition(azureScheme, new OpenApiSecurityScheme + { + Description = "Azure OAuth2 Authorization Code flow", Type = SecuritySchemeType.OAuth2, Flows = new OpenApiOAuthFlows { AuthorizationCode = new OpenApiOAuthFlow { - AuthorizationUrl = new Uri(authSettings.ThalosAppAuthorizationUrl ?? string.Empty), - TokenUrl = new Uri(authSettings.ThalosAppTokenUrl ?? string.Empty), + AuthorizationUrl = new Uri(authSettings.Azure?.ThalosAppAuthorizationUrl ?? + "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"), + TokenUrl = new Uri(authSettings.Azure?.ThalosAppTokenUrl ?? + "https://login.microsoftonline.com/common/oauth2/v2.0/token"), Scopes = new Dictionary - { - { authSettings.ThalosAppScope ?? string.Empty, "Access API as User" } - } + { + { authSettings.Azure?.ThalosAppScope ?? "access_as_user", "Access API as User" } + } } } }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme + [new OpenApiSecurityScheme { - Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" } - }, - new[] { authSettings.ThalosAppScope } - } + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = azureScheme } + }] = new[] { authSettings.Azure?.ThalosAppScope ?? "access_as_user" } }); + } - c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + if (identityProviders.Google) + { + const string googleScheme = "oauth2-Google"; + + c.AddSecurityDefinition(googleScheme, new OpenApiSecurityScheme { - Description = "JWT Authorization header using the Bearer scheme", - Name = "Authorization", - In = ParameterLocation.Header, - Type = SecuritySchemeType.Http, - Scheme = "bearer", - BearerFormat = "JWT" + Type = SecuritySchemeType.OAuth2, + Flows = new OpenApiOAuthFlows + { + AuthorizationCode = new OpenApiOAuthFlow + { + AuthorizationUrl = new Uri("https://accounts.google.com/o/oauth2/v2/auth"), + TokenUrl = new Uri("https://oauth2.googleapis.com/token"), + Scopes = new Dictionary + { + { "openid", "OpenID Connect" }, + { "email", "Access email" }, + { "profile", "Access profile" } + } + } + } }); c.AddSecurityRequirement(new OpenApiSecurityRequirement { - { - new OpenApiSecurityScheme + [new OpenApiSecurityScheme { - Reference = new OpenApiReference - { - Type = ReferenceType.SecurityScheme, - Id = "Bearer" - } - }, - Array.Empty() - } + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = googleScheme } + }] = new[] { "openid", "email", "profile" } }); + } - var filePath = Path.Combine(AppContext.BaseDirectory, DocumentationFile); - c.IncludeXmlComments(filePath); - c.SchemaFilter(); - }); + // ✅ XML Comments + var filePath = Path.Combine(AppContext.BaseDirectory, documentationFile); + c.IncludeXmlComments(filePath); + c.SchemaFilter(); + }); } + /// /// Configures Swagger and Swagger UI for the application. /// @@ -129,15 +171,36 @@ namespace Core.Thalos.Adapters.Extensions /// /// The instance. /// The containing Swagger UI and OAuth2 configuration settings. - public static void UseSwaggerUI(this WebApplication app, IConfiguration configuration, AuthSettings authSettings) + public static void UseSwaggerUI( + this WebApplication app, + IConfiguration configuration, + AuthSettings authSettings) { - app.UseSwaggerUI(options => + var identityProviders = new IdentityProviders(); + configuration.GetSection("IdentityProviders").Bind(identityProviders); + + app.UseSwagger(); + + if (identityProviders.Google) { - options.SwaggerEndpoint("/swagger/v1/swagger.json", "Custom Auth API with Azure AD v1"); - options.OAuthClientId(authSettings.ThalosAppClientId); - options.OAuthUsePkce(); - options.OAuthScopeSeparator(" "); - }); + app.UseSwaggerUI(options => + { + options.OAuthUsePkce(); + options.OAuthScopeSeparator(" "); + options.OAuthClientId(authSettings.Google?.ClientId); + options.OAuthClientSecret(authSettings.Google?.ClientSecret); + }); + } + + if (identityProviders.Azure) + { + app.UseSwaggerUI(options => + { + options.OAuthUsePkce(); + options.OAuthScopeSeparator(" "); + options.OAuthClientId(authSettings.Azure?.ThalosAppClientId); + }); + } } /// diff --git a/Core.Thalos.BuildingBlocks/Extensions/TelemetryExtensions.cs b/Core.Thalos.BuildingBlocks/Extensions/TelemetryExtensions.cs index 9eb757c..55180ca 100644 --- a/Core.Thalos.BuildingBlocks/Extensions/TelemetryExtensions.cs +++ b/Core.Thalos.BuildingBlocks/Extensions/TelemetryExtensions.cs @@ -4,15 +4,15 @@ using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; -namespace Core.Thalos.Adapters.Extensions +namespace Core.Thalos.BuildingBlocks.Configuration { public static class TelemetryExtensions { - public static void AddTelemetry(this IServiceCollection services) + public static void AddTelemetry(this IServiceCollection services, string apiName) { // Add OpenTelemetry Tracing services.AddOpenTelemetry() - .ConfigureResource(resource => resource.AddService("lsa.dashboard.bff.api")) + .ConfigureResource(resource => resource.AddService($"{apiName}")) .WithTracing(tracing => tracing.AddAspNetCoreInstrumentation().AddConsoleExporter()) .WithMetrics(metrics => metrics.AddAspNetCoreInstrumentation().AddConsoleExporter()). WithLogging(logs => logs.AddConsoleExporter()); diff --git a/Core.Thalos.BuildingBlocks/Extensions/TrackingMechanismExtension.cs b/Core.Thalos.BuildingBlocks/Extensions/TrackingMechanismExtension.cs index ecda0a5..a516027 100644 --- a/Core.Thalos.BuildingBlocks/Extensions/TrackingMechanismExtension.cs +++ b/Core.Thalos.BuildingBlocks/Extensions/TrackingMechanismExtension.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Http; -namespace Core.Thalos.Adapters.Extensions +namespace Core.Thalos.BuildingBlocks.Extensions { public sealed class TrackingMechanismExtension : DelegatingHandler { diff --git a/Core.Thalos.BuildingBlocks/Handlers/AuthenticatedHttpClientHandler.cs b/Core.Thalos.BuildingBlocks/Handlers/AuthenticatedHttpClientHandler.cs index e6b5517..1fef572 100644 --- a/Core.Thalos.BuildingBlocks/Handlers/AuthenticatedHttpClientHandler.cs +++ b/Core.Thalos.BuildingBlocks/Handlers/AuthenticatedHttpClientHandler.cs @@ -4,9 +4,8 @@ // // *********************************************************************** -using Core.Thalos.Adapters.Contracts; -namespace Core.Thalos.Adapters.Handlers +namespace Core.Thalos.BuildingBlocks { /// /// Class to inject the token in all requests. diff --git a/Core.Thalos.BuildingBlocks/Authentication/Handlers/GoogleAccessTokenAuthenticationHandler.cs b/Core.Thalos.BuildingBlocks/Handlers/GoogleAccessTokenAuthenticationHandler.cs similarity index 94% rename from Core.Thalos.BuildingBlocks/Authentication/Handlers/GoogleAccessTokenAuthenticationHandler.cs rename to Core.Thalos.BuildingBlocks/Handlers/GoogleAccessTokenAuthenticationHandler.cs index 83361a2..86eb33d 100644 --- a/Core.Thalos.BuildingBlocks/Authentication/Handlers/GoogleAccessTokenAuthenticationHandler.cs +++ b/Core.Thalos.BuildingBlocks/Handlers/GoogleAccessTokenAuthenticationHandler.cs @@ -1,5 +1,4 @@ -using Core.Thalos.Adapters.Common.Constants; -using Google.Apis.Auth; +using Google.Apis.Auth; using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; @@ -7,7 +6,7 @@ using Microsoft.Extensions.Options; using System.Security.Claims; using System.Text.Encodings.Web; -namespace Core.Thalos.BuildingBlocks.Authentication.Handlers +namespace Core.Thalos.BuildingBlocks { public class GoogleAccessTokenAuthenticationHandler(IOptionsMonitor options, ILoggerFactory logger, diff --git a/Core.Thalos.BuildingBlocks/Handlers/PermissionsAuthorizationHandler.cs b/Core.Thalos.BuildingBlocks/Handlers/PermissionsAuthorizationHandler.cs index c4ef719..19af8c9 100644 --- a/Core.Thalos.BuildingBlocks/Handlers/PermissionsAuthorizationHandler.cs +++ b/Core.Thalos.BuildingBlocks/Handlers/PermissionsAuthorizationHandler.cs @@ -1,7 +1,6 @@ -using Core.Thalos.Adapters.Handlers.Adapters; -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; -namespace Core.Thalos.Adapters.Handlers +namespace Core.Thalos.BuildingBlocks { public class PermissionsAuthorizationHandler : AuthorizationHandler { diff --git a/Core.Thalos.BuildingBlocks/Helpers/AuthHelper.cs b/Core.Thalos.BuildingBlocks/Helpers/AuthHelper.cs index 653d52c..87ae68f 100644 --- a/Core.Thalos.BuildingBlocks/Helpers/AuthHelper.cs +++ b/Core.Thalos.BuildingBlocks/Helpers/AuthHelper.cs @@ -1,11 +1,12 @@ using Azure.Identity; -using Core.Thalos.Adapters.Common.Constants; +using Core.Blueprint.KeyVault; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.AzureAppConfiguration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -namespace Core.Thalos.Adapters.Helpers +namespace Core.Thalos.BuildingBlocks { public static class AuthHelper { @@ -15,9 +16,16 @@ namespace Core.Thalos.Adapters.Helpers }).CreateLogger("AuthHelper"); - public static AuthSettings GetAuthSettings(WebApplicationBuilder builder, string appConfigLabel) + public static async Task GetAuthSettings(this IServiceCollection services, WebApplicationBuilder builder, string appConfigLabel) { var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; + var authSettings = new AuthSettings(); + + var identityProviders = new IdentityProviders(); + builder.Configuration.GetSection("IdentityProviders").Bind(identityProviders); + + using var serviceProvider = services.BuildServiceProvider(); + var keyVaultProvider = serviceProvider.GetRequiredService(); if (environment != "Local") { @@ -39,19 +47,82 @@ namespace Core.Thalos.Adapters.Helpers }); } - return new AuthSettings + if (identityProviders.Google) + authSettings.Google = await GetGoogleSettings(keyVaultProvider, builder); + + if (identityProviders.Azure) + authSettings.Azure = GetAzureSettings(builder); + + authSettings.Token = await GetTokenSettings(keyVaultProvider, builder); + + return authSettings; + } + + private async static ValueTask GetTokenSettings(IKeyVaultProvider keyVaultProvider, WebApplicationBuilder builder) + { + var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty; + + var tokenSettings = new TokenAuthSettings(); + + if (environment == "Local") { - AzureADInstance = builder.Configuration.GetSection(Secrets.AzureADInstance).Value, - AzureADTenantId = builder.Configuration.GetSection(Secrets.AzureADTenantId).Value, - AzureADClientId = builder.Configuration.GetSection(Secrets.AzureADClientId).Value, - AzureADClientSecret = builder.Configuration.GetSection(Secrets.AzureADClientSecret).Value, + tokenSettings.PublicKey = (await keyVaultProvider.GetSecretAsync(Secrets.PublicKey, new CancellationToken { })).Secret.Value; + tokenSettings.PrivateKey = (await keyVaultProvider.GetSecretAsync(Secrets.PrivateKey, new CancellationToken { })).Secret.Value; + tokenSettings.Issuer = (await keyVaultProvider.GetSecretAsync(Secrets.Issuer, new CancellationToken { })).Secret.Value; + tokenSettings.Audience = (await keyVaultProvider.GetSecretAsync(Secrets.Audience, new CancellationToken { })).Secret.Value; + } + else + { + tokenSettings.PrivateKey = builder.Configuration.GetSection(Secrets.PrivateKey).Value; + tokenSettings.PublicKey = builder.Configuration.GetSection(Secrets.PublicKey).Value; + tokenSettings.Issuer = builder.Configuration.GetSection(Secrets.Issuer).Value; + tokenSettings.Audience = builder.Configuration.GetSection(Secrets.Audience).Value; + } + + if (string.IsNullOrEmpty(tokenSettings.PrivateKey) || string.IsNullOrEmpty(tokenSettings.PublicKey)) + { + logger.LogError("Settings for token creation are missing or incorrectly formatted."); + throw new InvalidOperationException("Invalid public or private key."); + } + + return tokenSettings; + } + + private static AzureAuthSettings GetAzureSettings(WebApplicationBuilder builder) + { + return new AzureAuthSettings + { + Instance = builder.Configuration.GetSection(Secrets.AzureADInstance).Value, + TenantId = builder.Configuration.GetSection(Secrets.AzureADTenantId).Value, + ClientId = builder.Configuration.GetSection(Secrets.AzureADClientId).Value, + ClientSecret = builder.Configuration.GetSection(Secrets.AzureADClientSecret).Value, ThalosAppAuthorizationUrl = builder.Configuration.GetSection(Secrets.ThalosAppAuthorizationUrl).Value, ThalosAppTokenUrl = builder.Configuration.GetSection(Secrets.ThalosAppTokenUrl).Value, ThalosAppClientId = builder.Configuration.GetSection(Secrets.ThalosAppClientId).Value, ThalosAppScope = builder.Configuration.GetSection(Secrets.ThalosAppScope).Value, - PrivateKey = builder.Configuration.GetSection(Secrets.PrivateKey).Value, - PublicKey = builder.Configuration.GetSection(Secrets.PublicKey).Value, }; } + + private static async ValueTask GetGoogleSettings(IKeyVaultProvider keyVaultProvider, WebApplicationBuilder builder) + { + var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); + var googleSettings = new GoogleAuthSettings(); + + if (environment == "Local") + { + googleSettings.ClientId = (await keyVaultProvider.GetSecretAsync(Secrets.GoogleClientId, new CancellationToken { })).Secret.Value; ; + googleSettings.ClientSecret = (await keyVaultProvider.GetSecretAsync(Secrets.GoogleClientSecret, new CancellationToken { })).Secret.Value; + googleSettings.RedirectUri = (await keyVaultProvider.GetSecretAsync(Secrets.GoogleRedirectUri, new CancellationToken { })).Secret.Value; + } + else + { + googleSettings.ClientId = builder.Configuration.GetSection(Secrets.GoogleClientId).Value; + googleSettings.ClientSecret = builder.Configuration.GetSection(Secrets.GoogleClientSecret).Value; + googleSettings.RedirectUri = builder.Configuration.GetSection(Secrets.GoogleRedirectUri).Value; + } + + return googleSettings; + } } } + diff --git a/Core.Thalos.BuildingBlocks/Authentication/Helpers/GoogleAuthHelper.cs b/Core.Thalos.BuildingBlocks/Helpers/GoogleAuthHelper.cs similarity index 93% rename from Core.Thalos.BuildingBlocks/Authentication/Helpers/GoogleAuthHelper.cs rename to Core.Thalos.BuildingBlocks/Helpers/GoogleAuthHelper.cs index 9470ef2..3acaa37 100644 --- a/Core.Thalos.BuildingBlocks/Authentication/Helpers/GoogleAuthHelper.cs +++ b/Core.Thalos.BuildingBlocks/Helpers/GoogleAuthHelper.cs @@ -2,7 +2,7 @@ using Google.Apis.Oauth2.v2; using Microsoft.Extensions.Configuration; -namespace Core.Thalos.BuildingBlocks.Authentication.Helpers +namespace Core.Thalos.BuildingBlocks { public class GoogleAuthHelper(IConfiguration config) : IGoogleAuthHelper { diff --git a/Core.Thalos.BuildingBlocks/Helpers/RsaHelper.cs b/Core.Thalos.BuildingBlocks/Helpers/RsaHelper.cs index bb849fc..cc55a32 100644 --- a/Core.Thalos.BuildingBlocks/Helpers/RsaHelper.cs +++ b/Core.Thalos.BuildingBlocks/Helpers/RsaHelper.cs @@ -10,7 +10,7 @@ using Org.BouncyCastle.Security; using System.Security.Cryptography; using System.Text; -namespace Core.Thalos.Adapters.Helpers +namespace Core.Thalos.BuildingBlocks { /// /// Handles all methods related to RSA encryption"/>. diff --git a/Core.Thalos.BuildingBlocks/Options/JwtIssuerOptions.cs b/Core.Thalos.BuildingBlocks/Options/JwtIssuerOptions.cs index 470b856..c0375dd 100644 --- a/Core.Thalos.BuildingBlocks/Options/JwtIssuerOptions.cs +++ b/Core.Thalos.BuildingBlocks/Options/JwtIssuerOptions.cs @@ -1,6 +1,6 @@ using Microsoft.IdentityModel.Tokens; -namespace Core.Thalos.Adapters.Options +namespace Core.Thalos.BuildingBlocks { /// /// JWT token Issuer options (used for JWT Factory) diff --git a/Core.Thalos.BuildingBlocks/Services/TokenService.cs b/Core.Thalos.BuildingBlocks/Services/TokenService.cs index c268d14..790ff37 100644 --- a/Core.Thalos.BuildingBlocks/Services/TokenService.cs +++ b/Core.Thalos.BuildingBlocks/Services/TokenService.cs @@ -3,9 +3,6 @@ // AgileWebs // // *********************************************************************** -using Core.Thalos.Adapters.Common.Constants; -using Core.Thalos.Adapters.Contracts; -using Core.Thalos.Adapters.Options; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; @@ -16,7 +13,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text.Json; -namespace Core.Thalos.Adapters.Services +namespace Core.Thalos.BuildingBlocks { /// /// Service responsible for manage authenticacion. diff --git a/Core.Thalos.BuildingBlocks/Settings/AuthSettings.cs b/Core.Thalos.BuildingBlocks/Settings/AuthSettings.cs index 94bf189..79693ce 100644 --- a/Core.Thalos.BuildingBlocks/Settings/AuthSettings.cs +++ b/Core.Thalos.BuildingBlocks/Settings/AuthSettings.cs @@ -4,22 +4,39 @@ // // *********************************************************************** +namespace Core.Thalos.BuildingBlocks; public class AuthSettings { - // Azure AD Settings - public string? AzureADInstance { get; set; } - public string? AzureADTenantId { get; set; } - public string? AzureADClientId { get; set; } - public string? AzureADClientSecret { get; set; } + public AzureAuthSettings? Azure { get; set; } + public TokenAuthSettings Token { get; set; } = null!; + public GoogleAuthSettings? Google { get; set; } +} - //Thalos App Settings +public class AzureAuthSettings +{ + public string? Instance { get; set; } + public string? TenantId { get; set; } + public string? ClientId { get; set; } + public string? ClientSecret { get; set; } public string? ThalosAppAuthorizationUrl { get; set; } public string? ThalosAppTokenUrl { get; set; } public string? ThalosAppClientId { get; set; } public string? ThalosAppScope { get; set; } - - // Token Keys - public string? PrivateKey { get; set; } - public string? PublicKey { get; set; } +} + +public class GoogleAuthSettings +{ + public string? ClientId { get; set; } + public string? ClientSecret { get; set; } + public string? RedirectUri { get; set; } + +} + +public class TokenAuthSettings +{ + public string? PrivateKey { get; set; } + public string? PublicKey { get; set; } + public string? Audience { get; set; } + public string? Issuer { get; set; } } diff --git a/Core.Thalos.BuildingBlocks/Settings/IdentityProviders.cs b/Core.Thalos.BuildingBlocks/Settings/IdentityProviders.cs new file mode 100644 index 0000000..073ca66 --- /dev/null +++ b/Core.Thalos.BuildingBlocks/Settings/IdentityProviders.cs @@ -0,0 +1,8 @@ +namespace Core.Thalos.BuildingBlocks +{ + public class IdentityProviders + { + public bool Google { get; set; } + public bool Azure { get; set; } + } +} diff --git a/Core.Thalos.BuildingBlocks/TokenProvider/HttpContextTokenProvider.cs b/Core.Thalos.BuildingBlocks/TokenProvider/HttpContextTokenProvider.cs index ba1e901..b880deb 100644 --- a/Core.Thalos.BuildingBlocks/TokenProvider/HttpContextTokenProvider.cs +++ b/Core.Thalos.BuildingBlocks/TokenProvider/HttpContextTokenProvider.cs @@ -4,10 +4,9 @@ // // *********************************************************************** -using Core.Thalos.Adapters.Contracts; using Microsoft.AspNetCore.Http; -namespace Core.Thalos.Adapters.TokenProvider +namespace Core.Thalos.BuildingBlocks { /// /// Class to return the access token to controllers.