98 lines
4.5 KiB
C#
98 lines
4.5 KiB
C#
// ***********************************************************************
|
|
// <copyright file="AuthExtension.cs">
|
|
// Heath
|
|
// </copyright>
|
|
// ***********************************************************************
|
|
|
|
using Core.Cerberos.Adapters.Common.Constants;
|
|
using Core.Cerberos.Adapters.Contracts;
|
|
using Core.Cerberos.Adapters.Handlers;
|
|
using Core.Cerberos.Adapters.Options;
|
|
using Core.Cerberos.Adapters.Services;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Identity.Web;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace Core.Cerberos.Adapters.Extensions
|
|
{
|
|
/// <summary>
|
|
/// Extension methods for configuring authentication with various Azure AD setups.
|
|
/// </summary>
|
|
public static class AuthenticationExtension
|
|
{
|
|
/// <summary>
|
|
/// Configures authentication using Azure AD for an API that requires downstream API access.
|
|
/// </summary>
|
|
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
|
|
/// <param name="configuration">The <see cref="IConfiguration"/> containing Azure AD configuration settings.</param>
|
|
public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration, AuthSettings authSettings)
|
|
{
|
|
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? string.Empty;
|
|
|
|
var azureAdInMemorySettings = new Dictionary<string, string?>
|
|
{
|
|
{ "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 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();
|
|
|
|
var rsa = RSA.Create();
|
|
rsa.ImportFromPem(authSettings.PrivateKey?.ToCharArray());
|
|
var rsaPrivateKey = new RsaSecurityKey(rsa);
|
|
|
|
var rsaPublic = RSA.Create();
|
|
rsaPublic.ImportFromPem(authSettings.PublicKey?.ToCharArray());
|
|
var rsaPublicKey = new RsaSecurityKey(rsaPublic);
|
|
|
|
var jwtAppSettingOptions = configuration.GetSection("B2C:JwtIssuerOptions");
|
|
var jwtIssuerOptions = jwtAppSettingOptions.Get<JwtIssuerOptions>();
|
|
|
|
if (string.IsNullOrEmpty(jwtIssuerOptions?.Issuer) || string.IsNullOrEmpty(jwtIssuerOptions.Audience))
|
|
throw new InvalidOperationException("JwtIssuerOptions are not configured correctly.");
|
|
|
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
.AddJwtBearer(Schemes.HeathScheme, x =>
|
|
{
|
|
x.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidIssuer = jwtIssuerOptions?.Issuer,
|
|
ValidateIssuer = true,
|
|
ValidateAudience = true,
|
|
ValidateLifetime = true,
|
|
ValidateIssuerSigningKey = true,
|
|
ValidAudience = jwtIssuerOptions?.Audience,
|
|
IssuerSigningKey = rsaPublicKey
|
|
};
|
|
});
|
|
|
|
services.Configure<JwtIssuerOptions>(options =>
|
|
{
|
|
options.Issuer = jwtIssuerOptions?.Issuer;
|
|
options.Audience = jwtIssuerOptions?.Audience;
|
|
options.SigningCredentials = new SigningCredentials(rsaPrivateKey, SecurityAlgorithms.RsaSha256);
|
|
});
|
|
|
|
services.AddSingleton(jwtAppSettingOptions);
|
|
services.AddTransient<IAuthorizationHandler, PermissionsAuthorizationHandler>();
|
|
services.AddTransient<ITokenService, TokenService>();
|
|
}
|
|
}
|
|
}
|