虽然我很高兴IdentityServer4存在并且在许多方面使我在身份验证方面的生活变得更加容易,但我偶然发现了问题以及在社区中为声明添加角色的许多讨论。
我的要求很简单:
我花了无数个小时尝试不同的配置,以便在身份验证后将asp.net Identity角色传递给我的MVC应用程序,但没有运气。目的如第6点所述。
我也花了无数个小时阅读,但我感觉自版本v1.0.0以来,角色的实现IdentityServer4.AspIdentity已经发生了很大的变化。
在阅读了很多相关内容后,仍然不清楚如何实际实现这一点,因为似乎仅在2个月前描述的某些解决方案不再有效。
所以,现在我相信有两条路径:
无论如何,这是我的假设。
那么,请详细帮助解释/记录,以便我们能够以持久的方式开始实施吗?一些可行的例子也很棒。
答案 0 :(得分:9)
因此,经过调查,我提出了两种方法来做到这一点:
包含在Identity Server端
ravi punjwani在“如何使用带有IdentityServer4的ASP.Net标识添加要包含在access_token中的其他声明”中提供了答案。他的解决方案仍在草案中,但解决方案允许您在令牌发送回客户端之前添加任何声明。这是链接:How to add additional claims to be included in the access_token using ASP.Net Identity with IdentityServer4
包含在客户端
这个问题有点困难,因为它涉及在客户端的请求管道中添加“IClaimsTransformer”。结果是,每个请求,Claimstransformer将检索用户的声明并将其添加到用户身份声明(令牌)。 Claimstransformer的设置并不容易,因为让DI工作很棘手,但经过大量研究后,celow解决方案为我做了。
Custom ClaimsTransformer类在中间件中进行转换: 公共类KarekeClaimsTransformer:IClaimsTransformer { private readonly UserManager _userManager;
public KarekeClaimsTransformer(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
if (context.Principal.Identity.IsAuthenticated)
{
Claim userId = context.Principal.FindFirst("sub");
if (context.Principal.FindFirst("role") == null && userId != null)
{
ApplicationUser user = await _userManager.FindByIdAsync(userId.Value);
var roles = await _userManager.GetRolesAsync(user);
foreach (var role in roles)
{
((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim(JwtClaimTypes.Role, role,
"http://schemas.microsoft.com/ws/2008/06/identity/claims/role"));
}
}
}
return Task.FromResult(context.Principal).Result;
}
}
在Client启动类中,您需要将其添加到ConfigureServices
中的范围public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
...
services.AddScoped<IClaimsTransformer, KarekeClaimsTransformer>();
// Add framework services.
services.AddMvc();
}
最后,添加配置:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
RequireHttpsMetadata = false,
ApiName = "api1"
});
app.UseClaimsTransformation((context) =>
{
IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>();
return transformer.TransformAsync(context);
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "api/{controller}/{action?}/{id?}");
});
}