asp.net-mvc – 如何将ASP.net身份角色放入Identityserver4身份令牌

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – 如何将ASP.net身份角色放入Identityserver4身份令牌前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
虽然我很高兴IdentityServer4存在并且在许多方面使我在身份验证方面的生活变得更加容易,但我偶然发现了问题以及在社区中为声明添加角色的许多讨论.

我的要求很简单:

>我开发需要身份验证和授权的应用程序(xamarin表单)
>我需要一个系统来存储我的用户的身份(名称,密码,角色,电话……) – > ASP.net身份
>我需要一个系统来验证我的用户 – > IdentityServer 4
>每个用户的角色非常有限(用户/管理员),不会更改
>我需要一个API后端和一个MVC管理站点(asp.net核心)
>我想使用[Authorize(Roles =“Admin”)]限制对某些API / MVC控制器的访问

我花了无数个小时尝试不同的配置,以便在认证后将asp.net Identity角色传递给我的MVC应用程序,但没有运气.目的如第6点所述.

我也花了无数个小时阅读,但我感觉自版本v1.0.0以来,角色的实现IdentityServer4.AspIdentity已经发生了很大的变化.

在阅读了很多关于这一点后,仍然不清楚如何实际实现这一点,因为似乎仅在2个月前描述的一些解决方案不再有效.

所以,现在我相信有两条路:

>仅通过请求身份令牌将角色置于身份令牌中
并使用AlwaysIncludeInIdToken?
>让客户端检索角色
使用userinfo端点并以某种方式将它们注入到
httpcontext(?)允许mvc使用[Authorize(Roles =.)进行检查
“管理”)?

无论如何,这是我的假设.

那么,请详细帮助解释/记录,以便我们能够以持久的方式开始实施吗?一些可行的例子也很棒.

解决方法

因此,经过调查,我提出了两种方法来做到这一点:

>在Identity Server端包含角色/其他声明
>在客户端包含角色/其他声明

包含在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?}");
        });
    }
原文链接:https://www.f2er.com/aspnet/248658.html

猜你在找的asp.Net相关文章