Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

namespace WebApp_Authentication_API.Infrastructure.Configuration
{
Expand All @@ -23,4 +22,4 @@ public static IServiceCollection AddCustomApiVersioning(this IServiceCollection
return services;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Identity.Web;
using Jwt = Microsoft.AspNetCore.Authentication.JwtBearer;
using JwtDefaults = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults;

namespace WebApp_Authentication_API.Infrastructure.Configuration
Expand All @@ -13,12 +14,82 @@ public static class AuthenticationConfiguration
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
{
// Add services to the container.
services
.AddAuthentication(JwtDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(configuration, Constants.AzureAd);
.AddMicrosoftIdentityWebApi(configuration, "Azure:AD");

//services.Configure<Jwt.JwtBearerOptions>(JwtDefaults.AuthenticationScheme, options =>
//{
// options.Events = new Jwt.JwtBearerEvents
// {
// // Handle the token validated event
// OnTokenValidated = OnTokenValidated
// };
//});

return services;
}

/// <summary>
/// Called after the auth token is validated.
/// </summary>
//private static async Task OnTokenValidated(Jwt.TokenValidatedContext context)
//{
// var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();

// // Get user email from claims
// var uniqueId = context.Principal?.GetUniqueId();
// var email = context.Principal?.GetEmail();
// var name = context.Principal?.GetName();

// if (uniqueId is null)
// {
// var unknownUniqueIdentifierException = new UnknownUniqueIdentifierAuthenticationException("User does not have object identifier");
// context.Fail(unknownUniqueIdentifierException);
// }
// else
// {
// if (string.IsNullOrEmpty(email))
// {
// var unknownMailException = new UnknownEmailAuthenticationException($"User with object identifier '{uniqueId}' does not have an email.");
// context.Fail(unknownMailException);
// }
// else if (string.IsNullOrEmpty(name))
// {
// var unknownNameException = new UnknownNameAuthenticationException($"User with object identifier '{uniqueId}' does not have a name.");
// context.Fail(unknownNameException);
// }
// else
// {
// // Check if user exists in database
// var user = await userService.GetUser(uniqueId.Value);

// var identity = GetUserClaimsIdentity(user);
// context.Principal?.AddIdentity(identity);
// }
// }
//}

//private static ClaimsIdentity GetUserClaimsIdentity(User? user)
//{
// var claims = new List<Claim>();

// if (user is not null && user.IsActive)
// {
// var nameClaim = new Claim(ClaimTypes.Name, user.Name ?? "");
// claims.Add(nameClaim);

// var userIdClaim = new Claim(CustomClaimTypes.UserId, user.UserId.ToString("d"));
// claims.Add(userIdClaim);

// var isGlobalAdministratorClaim = new Claim(CustomClaimTypes.UserIsGlobalAdministrator, user.IsGlobalAdministrator.ToString());
// claims.Add(isGlobalAdministratorClaim);

// var permissionsClaim = new Claim(CustomClaimTypes.UserPermissions, JsonSerializer.Serialize(user.Permissions));
// claims.Add(permissionsClaim);
// }

// return new ClaimsIdentity(claims);
//}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public ConfigureSwaggerOptions(IOptions<AzureAdOptions> azureAdOptions)
public void Configure(SwaggerGenOptions options)
{
#region OAuth2 Implicit

options.AddSecurityDefinition("OAuth2 Implicit", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Expand All @@ -33,7 +34,7 @@ public void Configure(SwaggerGenOptions options)
{
{ azureAdOptions.CustomScopeApi, azureAdOptions.CustomScopeApi },
}
}
},
}
});

Expand All @@ -53,9 +54,11 @@ public void Configure(SwaggerGenOptions options)
new List<string>()
}
});
#endregion

#endregion OAuth2 Implicit

#region Bearer

options.AddSecurityDefinition(name: "Bearer", securityScheme: new OpenApiSecurityScheme
{
Name = "Authorization",
Expand All @@ -81,9 +84,11 @@ public void Configure(SwaggerGenOptions options)
new List<string>()
}
});
#endregion

#endregion Bearer

#region OAuth Client Credentials

options.AddSecurityDefinition("OAuth Client Credentials", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Expand Down Expand Up @@ -116,7 +121,49 @@ public void Configure(SwaggerGenOptions options)
new List<string>()
}
});
#endregion

#endregion OAuth Client Credentials

#region Authorization code

options.AddSecurityDefinition("OAuth2 autorization code", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Scheme = "oauth2_auth_code",
In = ParameterLocation.Header,
Name = "Authorization",
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(azureAdOptions.AuthorizationUrl),
TokenUrl = new Uri(azureAdOptions.TokenUrl),
Scopes = new Dictionary<string, string>
{
{ "openid", "OpenID" },
{ azureAdOptions.CustomScopeApi, "Your API Scope" },
}
}
}
});

options.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Reference = new OpenApiReference
{
Id = "OAuth2 autorization code",
Type = ReferenceType.SecurityScheme
}
},
new[] { "openid", azureAdOptions.CustomScopeApi }
}
});

#endregion Authorization code
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public class AzureAdOptions

public string? ClientId { get; set; }

public string? SwaggerClientId { get; set; }

public string? ClientSecret { get; set; }

public string? CallbackPath { get; set; }
Expand All @@ -24,4 +26,4 @@ public class AzureAdOptions

public string CustomScopeApi => $"api://{ClientId}/{CustomScope}";
}
}
}
11 changes: 9 additions & 2 deletions WebApp-Authentication-API/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
using Swashbuckle.AspNetCore.SwaggerGen;
Expand Down Expand Up @@ -33,7 +34,13 @@
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
app.UseSwaggerUI(c =>
{
c.OAuthUsePkce();
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Your API V1");
c.OAuthClientId(azureAD.Value.SwaggerClientId);
c.OAuthScopes("openid", azureAD.Value.CustomScopeApi);
});
}

app.UseHttpsRedirection();
Expand All @@ -44,4 +51,4 @@

app.MapControllers();

app.Run();
app.Run();
13 changes: 8 additions & 5 deletions WebApp-Authentication-API/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com",
"Domain": "expertime365.onmicrosoft.com",
"TenantId": "6494460e-8600-4edc-850f-528e8faad290",
"ClientId": "fe9ef5ee-4a63-4d56-81e1-16ff4ba2eb3e",
"Instance": "https://login.microsoftonline.com/",
"Domain": "sdioumobertysoutlook.onmicrosoft.com",
"TenantId": "1b47abca-7f45-4ff8-9a9f-6ae33216768b",
"ClientId": "095cdf77-8dad-4ec1-a3f7-9db43f77ec3d",
"SwaggerClientId": "0bd89ded-6926-454d-a969-e04b8540dae6",
"CallbackPath": "/signin-oidc",
"CustomScope": "access_as_user"
"Scopes": "user.read",
"ClientCertificates": [],
"CustomScope": "EmployerManagement.Read"
},
"Logging": {
"LogLevel": {
Expand Down