繁体   English   中英

如何使用Identity Server 4(JWT)进行基于角色的Web API授权

[英]How to do Role-based Web API Authorization using Identity Server 4 (JWT)

这对我来说是全新的,我仍在努力解决。 我已经设置了IDP(Identity Server 4),并且能够配置客户端以对其进行身份验证(Angular 6 App),并且还可以配置客户端以进行API身份验证(Asp.Net Core 2.0)。 一切似乎都正常。

这是IDP中的客户端定义:

new Client
            {
                ClientId = "ZooClient",
                ClientName = "Zoo Client",
                AllowedGrantTypes = GrantTypes.Implicit,
                AllowAccessTokensViaBrowser = true,
                RequireConsent = true,

                RedirectUris           = { "http://localhost:4200/home" },
                PostLogoutRedirectUris = { "http://localhost:4200/home" },
                AllowedCorsOrigins = { "http://localhost:4200" },

                AllowedScopes =
                {
                    IdentityServerConstants.StandardScopes.OpenId,
                    IdentityServerConstants.StandardScopes.Profile,
                    IdentityServerConstants.StandardScopes.Email,
                    IdentityServerConstants.StandardScopes.Phone,
                    IdentityServerConstants.StandardScopes.Address,
                    "roles",
                    "ZooWebAPI"
                }
            }

我在客户端请求以下范围:'openid个人资料电子邮件角色ZooWebAPI'

WebAPI的设置如下:

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddMvcCore()
            .AddJsonFormatters()
            .AddAuthorization();

        services.AddCors();
        services.AddDistributedMemoryCache();

        services.AddAuthentication("Bearer")
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = "https://localhost:44317";
                options.RequireHttpsMetadata = false;
                options.ApiName = "ZooWebAPI";    
            });


    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(policy =>
        {
            policy.WithOrigins("http://localhost:4200");
            policy.AllowAnyHeader();
            policy.AllowAnyMethod();
            policy.AllowCredentials();
            policy.WithExposedHeaders("WWW-Authenticate");
        });

        app.UseAuthentication();
        app.UseMvc();
    }

通过使用[授权],我成功地保护了API:

[Route("api/[controller]")]
    [Authorize]
    public class ValuesController : Controller
    {
        // GET api/values
        [HttpGet]
        public ActionResult Get()
        {
            return new JsonResult(User.Claims.Select(
                c => new { c.Type, c.Value }));
        }
    }

一切正常,如果客户端未通过身份验证,浏览器将转到IDP,需要身份验证,使用访问令牌重定向回去,然后将访问令牌用于成功进行的API调用。

如果查看User对象中的Claims,可以看到一些信息,但没有任何用户信息。 我可以看到范围等,但是没有角色。 从我所读的内容中可以预料到,API不应该在乎用户正在调用什么,但是如何通过基于角色的API调用来限制我呢? 还是完全违反规格?

IDP有一个userinfo端点,该端点返回所有用户信息,我认为可以在WebAPI中使用它,但是再次从阅读中可以看出,它的意图是仅从客户端调用该端点。

无论如何,我想基于特定用户的角色来限制Web API调用。 有人有任何建议,意见吗? 另外,我想知道是什么用户在拨打电话,我该怎么办?

JWT示例:

在此处输入图片说明

谢谢

从我可以从您的信息中学到的东西,我可以告诉以下内容。

您正在通过外部提供程序登录:Windows身份验证。 您正在定义一些范围,以将某些内容传递给令牌,以指示对特定资源的访问。

您所说的User对象是从访问令牌中填充的User类。 由于访问令牌默认情况下不包括用户个人资料声明,因此您不会在User对象上使用它们。 这与直接使用Windows身份验证(在用户原则上提供用户名)不同。

您需要采取其他措施来基于用户登录提供授权。您可以在以下几点添加授权逻辑:

您可以根据在Identityserver的配置中定义的自定义范围来定义声明。 恕我直言,这是不可取的,因为它是固定于登录方法而不是用户登录的。

您可以使用ClaimsTransformation(请参见下面的链接)。 这使您可以将声明添加到方法开始时可用的声明列表中。 这有一个缺点(对某些人来说是肯定的),这些额外的声明不会被添加到访问令牌本身中,只有在评估令牌的后端,才可以在您的代码处理请求之前添加这些声明。 。

您如何检索这些声明取决于您的业务需求。

如果需要用户信息,则必须调用Identityserver的userinfo端点至少知道用户名。 这就是该端点的目的。 基于此,您可以使用自己的逻辑来确定该用户拥有的“角色”。

例如,我们创建了一个单独的服务,可以根据用户和访问令牌中包含的范围来配置和返回“角色”声明。

UseClaimsTransformation .NET Core

UseClaimsTransformation .NET完整框架

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM