【问题标题】:How to put ASP.net Identity Roles into the Identityserver4 Identity token如何将 ASP.net 身份角色放入 Identityserver4 身份令牌
【发布时间】:2017-01-16 18:03:03
【问题描述】:

虽然我很高兴 IdentityServer4 的存在并在许多方面使我在身份验证方面的工作变得更加轻松,但我偶然发现了这个问题以及社区内关于向声明中添加角色的许多讨论。

我的要求很简单:

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

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

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

在阅读了很多关于这方面的内容后,目前还不清楚如何实际实施这一点,因为似乎仅在 2 个月前描述的一些解决方案不再有效。

所以,目前我认为有两条路径:

  1. 仅通过请求身份令牌来参与身份令牌 并使用 AlwaysIncludeInIdToken?
  2. 让客户端检索角色 使用 userinfo 端点并以某种方式将它们注入 httpcontext(?) 允许 mvc 使用 [Authorize(Roles = “管理员”)]?

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

所以,请帮忙并详细解释/记录,以便我们可以开始以持久的方式实施它?一些可行的例子也很棒。

【问题讨论】:

  • 您能确认角色存在于令牌中吗?如果他们这样做了,那么我可能知道是什么导致了你的痛苦。
  • 不,我无法添加任何声明(角色、自定义声明...)。所以我研究了很多,发现了下面描述的2个解决方案。我现在可以在身份服务器级别和客户端级别添加声明。当然,我们欢迎任何可以改善这一点的建议。

标签: asp.net-mvc asp.net-core identityserver4


【解决方案1】:

所以,经过调查,我想出了两种方法来做到这一点:

  1. 在身份服务器端包含角色/其他声明
  2. 在客户端包含角色/其他声明

包含在身份服务器端

ravi punjwani 在“如何使用带有 IdentityServer4 的 ASP.Net Identity 添加附加声明以包含在 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 { 私有只读 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?}");
        });
    }

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 2018-10-05
    • 1970-01-01
    • 2016-09-05
    • 2020-09-30
    • 2018-07-19
    • 1970-01-01
    • 2015-04-06
    • 2023-04-07
    相关资源
    最近更新 更多