map the roles in the JWToken
This commit is contained in:
parent
b2db9a1647
commit
43b289886e
4 changed files with 88 additions and 12 deletions
|
|
@ -39,6 +39,7 @@ public static class Config
|
||||||
{
|
{
|
||||||
new IdentityResources.OpenId(),
|
new IdentityResources.OpenId(),
|
||||||
new IdentityResources.Profile(),
|
new IdentityResources.Profile(),
|
||||||
|
new IdentityResources.Email()
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IEnumerable<ApiScope> ApiScopes =>
|
public static IEnumerable<ApiScope> ApiScopes =>
|
||||||
|
|
@ -79,7 +80,7 @@ public static class Config
|
||||||
AllowedScopes = {
|
AllowedScopes = {
|
||||||
IdentityServerConstants.StandardScopes.OpenId,
|
IdentityServerConstants.StandardScopes.OpenId,
|
||||||
IdentityServerConstants.StandardScopes.Profile,
|
IdentityServerConstants.StandardScopes.Profile,
|
||||||
"scope2" }
|
IdentityServerConstants.StandardScopes.Email }
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ using System.Globalization;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using Google.Apis.Util.Store;
|
using Google.Apis.Util.Store;
|
||||||
using IdentityServer8;
|
using IdentityServer8;
|
||||||
|
using IdentityServer8.Services;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
|
|
@ -33,6 +34,7 @@ namespace Yavsc.Extensions;
|
||||||
|
|
||||||
internal static class HostingExtensions
|
internal static class HostingExtensions
|
||||||
{
|
{
|
||||||
|
#region files config
|
||||||
public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app,
|
public static IApplicationBuilder ConfigureFileServerApp(this IApplicationBuilder app,
|
||||||
bool enableDirectoryBrowsing = false)
|
bool enableDirectoryBrowsing = false)
|
||||||
{
|
{
|
||||||
|
|
@ -83,6 +85,9 @@ internal static class HostingExtensions
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public static void ConfigureWorkflow()
|
public static void ConfigureWorkflow()
|
||||||
{
|
{
|
||||||
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
|
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
|
@ -163,6 +168,7 @@ internal static class HostingExtensions
|
||||||
services.Configure<PayPalSettings>(paypalSection);
|
services.Configure<PayPalSettings>(paypalSection);
|
||||||
services.Configure<GoogleAuthSettings>(googleAuthSettings);
|
services.Configure<GoogleAuthSettings>(googleAuthSettings);
|
||||||
|
|
||||||
|
|
||||||
services.AddRazorPages();
|
services.AddRazorPages();
|
||||||
services.AddSignalR(o =>
|
services.AddSignalR(o =>
|
||||||
{
|
{
|
||||||
|
|
@ -197,12 +203,15 @@ services
|
||||||
|
|
||||||
// see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/
|
// see https://docs.duendesoftware.com/identityserver/v6/fundamentals/resources/
|
||||||
options.EmitStaticAudienceClaim = true;
|
options.EmitStaticAudienceClaim = true;
|
||||||
|
options.EmitScopesAsSpaceDelimitedStringInJwt = true;
|
||||||
|
options.Endpoints.EnableUserInfoEndpoint = true;
|
||||||
})
|
})
|
||||||
.AddInMemoryIdentityResources(Config.IdentityResources)
|
.AddInMemoryIdentityResources(Config.IdentityResources)
|
||||||
.AddInMemoryClients(Config.Clients)
|
.AddInMemoryClients(Config.Clients)
|
||||||
.AddInMemoryApiScopes(Config.ApiScopes)
|
.AddInMemoryApiScopes(Config.ApiScopes)
|
||||||
.AddAspNetIdentity<ApplicationUser>()
|
.AddAspNetIdentity<ApplicationUser>()
|
||||||
;
|
;
|
||||||
|
services.AddScoped<IProfileService, ProfileService>();
|
||||||
|
|
||||||
if (builder.Environment.IsDevelopment())
|
if (builder.Environment.IsDevelopment())
|
||||||
{
|
{
|
||||||
|
|
@ -317,6 +326,7 @@ services
|
||||||
_ = services.AddTransient<IBillingService, BillingService>();
|
_ = services.AddTransient<IBillingService, BillingService>();
|
||||||
_ = services.AddTransient<IDataStore, FileDataStore>((sp) => new FileDataStore("googledatastore", false));
|
_ = services.AddTransient<IDataStore, FileDataStore>((sp) => new FileDataStore("googledatastore", false));
|
||||||
_ = services.AddTransient<ICalendarManager, CalendarManager>();
|
_ = services.AddTransient<ICalendarManager, CalendarManager>();
|
||||||
|
services.AddTransient<IProfileService, ProfileService>();
|
||||||
|
|
||||||
|
|
||||||
// TODO for SMS: services.AddTransient<ISmsSender, AuthMessageSender>();
|
// TODO for SMS: services.AddTransient<ISmsSender, AuthMessageSender>();
|
||||||
|
|
@ -333,9 +343,7 @@ services
|
||||||
{
|
{
|
||||||
options.AddPolicy("ApiScope", policy =>
|
options.AddPolicy("ApiScope", policy =>
|
||||||
{
|
{
|
||||||
policy
|
policy.RequireAuthenticatedUser();
|
||||||
.RequireAuthenticatedUser()
|
|
||||||
.RequireClaim("scope", "scope2");
|
|
||||||
});
|
});
|
||||||
options.AddPolicy("AdministratorOnly", policy =>
|
options.AddPolicy("AdministratorOnly", policy =>
|
||||||
{
|
{
|
||||||
|
|
@ -343,14 +351,11 @@ services
|
||||||
});
|
});
|
||||||
|
|
||||||
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
|
options.AddPolicy("FrontOffice", policy => policy.RequireRole(Constants.FrontOfficeGroupName));
|
||||||
options.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
|
|
||||||
.AddAuthenticationSchemes("Bearer")
|
|
||||||
.RequireAuthenticatedUser().Build());
|
|
||||||
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
// options.AddPolicy("EmployeeId", policy => policy.RequireClaim("EmployeeId", "123", "456"));
|
||||||
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
|
// options.AddPolicy("BuildingEntry", policy => policy.Requirements.Add(new OfficeEntryRequirement()));
|
||||||
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
options.AddPolicy("Authenticated", policy => policy.RequireAuthenticatedUser());
|
||||||
options.AddPolicy("IsTheAuthor", policy =>
|
options.AddPolicy("IsTheAuthor", policy => policy.Requirements.Add(new EditPermission()));
|
||||||
policy.Requirements.Add(new EditPermission()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
|
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
|
||||||
|
|
|
||||||
56
src/Yavsc/Services/ProfileService.cs
Normal file
56
src/Yavsc/Services/ProfileService.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
using IdentityModel;
|
||||||
|
using IdentityServer8.Models;
|
||||||
|
using IdentityServer8.Services;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Yavsc.Models;
|
||||||
|
|
||||||
|
namespace Yavsc.Services
|
||||||
|
{
|
||||||
|
public class ProfileService : IProfileService
|
||||||
|
{
|
||||||
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
private readonly RoleManager<IdentityRole> _roleManager;
|
||||||
|
public ProfileService(
|
||||||
|
UserManager<ApplicationUser> userManager,
|
||||||
|
RoleManager<IdentityRole> roleManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_roleManager = roleManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Claim>> GetClaimsFromUserAsync(ApplicationUser user)
|
||||||
|
{
|
||||||
|
var claims = new List<Claim> {
|
||||||
|
new Claim(JwtClaimTypes.Subject,user.Id.ToString()),
|
||||||
|
new Claim(JwtClaimTypes.PreferredUserName,user.UserName)
|
||||||
|
};
|
||||||
|
|
||||||
|
var role = await _userManager.GetRolesAsync(user);
|
||||||
|
role.ToList().ForEach(f =>
|
||||||
|
{
|
||||||
|
claims.Add(new Claim(JwtClaimTypes.Role, f));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return claims;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
|
||||||
|
{
|
||||||
|
var subjectId = context.Subject.Claims.FirstOrDefault(c => c.Type == "sub").Value;
|
||||||
|
var user = await _userManager.FindByIdAsync(subjectId);
|
||||||
|
context.IssuedClaims = await GetClaimsFromUserAsync(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task IsActiveAsync(IsActiveContext context)
|
||||||
|
{
|
||||||
|
var subjectId = context.Subject.Claims.FirstOrDefault(c => c.Type == "sub").Value;
|
||||||
|
var user = await _userManager.FindByIdAsync(subjectId);
|
||||||
|
context.IsActive = user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
|
||||||
public class Startup
|
public class Startup
|
||||||
|
|
@ -25,10 +27,22 @@ using System.IdentityModel.Tokens.Jwt;
|
||||||
options.ClientId = "mvc";
|
options.ClientId = "mvc";
|
||||||
options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
|
options.ClientSecret = "49C1A7E1-0C79-4A89-A3D6-A37998FB86B0";
|
||||||
options.ResponseType = "code";
|
options.ResponseType = "code";
|
||||||
|
options.UsePkce = true;
|
||||||
options.Scope.Add("scope2");
|
options.Scope.Clear();
|
||||||
|
options.Scope.Add("openid");
|
||||||
|
options.Scope.Add("profile");
|
||||||
|
options.Scope.Add("email");
|
||||||
|
|
||||||
options.SaveTokens = true;
|
options.GetClaimsFromUserInfoEndpoint = true;
|
||||||
|
options.SaveTokens = true;
|
||||||
|
|
||||||
|
options.ClaimActions.MapUniqueJsonKey("role", "role");
|
||||||
|
options.ClaimActions.MapUniqueJsonKey("roles", "role");
|
||||||
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
NameClaimType = "name",
|
||||||
|
RoleClaimType = "role"
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue