我已经使用以下答案设置了资源所有者密码凭据授予:
https://stackoverflow.com/a/67324222/3850405
然后,我按照本指南设置了名称和角色声明:
https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-identity-server?view=aspnetcore-6.0&tabs=visualstudio#具有api授权的名称和角色声明
一切都很好,但使用正常的授权代码授予,但使用ROPC,我既不会得到姓名也不会得到角色声明。
我们不使用客户端凭据授予的原因可以在这里看到:
https://github.com/dotnet/aspnetcore/issues/44122
ProfileService.cs:
using IdentityModel;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Services;
using System.Threading.Tasks;
public class ProfileService : IProfileService
{
public ProfileService()
{
}
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var nameClaim = context.Subject.FindAll(JwtClaimTypes.Name);
context.IssuedClaims.AddRange(nameClaim);
var roleClaims = context.Subject.FindAll(JwtClaimTypes.Role);
context.IssuedClaims.AddRange(roleClaims);
await Task.CompletedTask;
}
public async Task IsActiveAsync(IsActiveContext context)
{
await Task.CompletedTask;
}
}
Startup.cs(.NET6中的Program.cs(:
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
options.Clients.AddIdentityServerSPA("WebApplication4.Client", builder =>
{
builder.WithRedirectUri("/authentication/login-callback");
builder.WithLogoutRedirectUri("/authentication/logout-callback");
});
//Or Duende.IdentityServer.Models.Client
options.Clients.Add(new IdentityServer4.Models.Client
{
ClientId = "WebApplication4.Integration",
AllowedGrantTypes = { GrantType.ResourceOwnerPassword },
//Use Configuration.GetSection("MySecretValue").Value; to get a value from appsettings.json
ClientSecrets = { new Secret("MySecretValue".Sha256()) },
AllowedScopes = { "WebApplication4.ServerAPI", "openid", "profile" }
});
});
services.AddTransient<IProfileService, ProfileService>();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
结果是一个配置问题。
https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/hosted-with-identity-server?view=aspnetcore-6.0&tabs=visualstudio#配置身份服务器
微软表示Use one of the following approaches:
,但使用像public class ProfileService : IProfileServic
这样的配置文件服务只能使用授权代码授予,而不能使用资源所有者密码凭据。删除ProfileService
并使用此代码一切正常:
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");