如何使用 JWT 令牌进行授权

Posted

技术标签:

【中文标题】如何使用 JWT 令牌进行授权【英文标题】:How to Authorize Using JWT token 【发布时间】:2019-06-04 18:21:46 【问题描述】:

我有一个 Web api 端点,它给了我 JWT 令牌。它不是一个完全授权的服务器。它只是可以生成一个 JWT 令牌。

现在我有了另一个用 aspnet 核心编写的网络应用程序。在 startup.cs 中,我添加了以下几行,以便我可以使用收到的 JWT 令牌进行授权

            services.AddAuthentication(options =>
        
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

        ).AddJwtBearer(configureOptions =>
        ...);

我还有一个登录表单(在网络应用程序中),用户输入用户名和密码,我将其发送到网络 api 并获取令牌。为了保护网络应用程序中的任何控制器,我只使用了 [Authorize] 属性。

在令牌过期之前一切正常。该令牌的寿命很短,但它确实带有一个刷新令牌。

我的问题是,我怎样才能检测到令牌(来自 web api)现在已过期,我需要使用刷新令牌获取一个新令牌。我知道在 javascript 世界中我可以拦截 http 请求并使用刷新令牌更新令牌。

但是如何在 aspnet 核心客户端应用程序中执行此操作?

(注意:我不想使用任何身份验证服务器,例如 IdentityServer4 等)

提前谢谢你!!

【问题讨论】:

【参考方案1】:

你完全可以实现你想要的:

services
    .AddAuthentication()
    .AddJwtBearer("Firebase", options =>
    
        options.Authority = "https://securetoken.google.com/my-firebase-project"
        options.TokenValidationParameters = new TokenValidationParameters
        
            ValidateIssuer = true,
            ValidIssuer = "my-firebase-project"
            ValidateAudience = true,
            ValidAudience = "my-firebase-project"
            ValidateLifetime = true
        ;
    )
    .AddJwtBearer("Custom", options =>
    
        // Configuration for your custom
        // JWT tokens here
    );

services
    .AddAuthorization(options =>
    
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase", "Custom")
            .Build();
    );

让我们来看看你的代码和那个代码之间的区别。

AddAuthentication 没有参数 如果您设置默认身份验证方案,那么在每个请求中,身份验证中间件都将尝试运行与默认身份验证方案关联的身份验证处理程序。由于我们现在有两个可行的身份验证方案,因此运行其中一个是没有意义的。

使用 AddJwtBearer 的另一个重载 添加身份验证的每个 AddXXX 方法都有几个重载:

使用与身份验证方法关联的默认身份验证方案的一种,您可以在此处看到 cookie 身份验证 除了选项的配置之外,您还可以传递身份验证方案的名称,就像在这个重载中一样 现在,因为您使用了两次相同的身份验证方法,但身份验证方案必须是唯一的,所以您需要使用第二次重载。

更新默认策略 由于请求将不再自动进行身份验证,因此将 [Authorize] 属性添加到某些操作将导致请求被拒绝并发出 HTTP 401。

因为这不是我们想要的,因为我们想让身份验证处理程序有机会对请求进行身份验证,所以我们更改了授权系统的默认策略,指示应尝试使用 Firebase 和自定义身份验证方案来对请求进行身份验证。

这并不妨碍您对某些操作更加严格; [Authorize] 属性有一个 AuthenticationSchemes 属性,允许您覆盖哪些身份验证方案是有效的。

如果您有更复杂的场景,您可以使用基于策略的授权。我觉得官方文档很棒。

假设某些操作仅适用于 Firebase 发布的 JWT 令牌,并且必须具有特定值的声明;你可以这样做:

services
    .AddAuthorization(options =>
    
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase", "Custom")
            .Build();

        options.AddPolicy("FirebaseAdministrators", new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes("Firebase")
            .RequireClaim("role", "admin")
            .Build());
    );

然后您可以在某些操作上使用[Authorize(Policy = "FirebaseAdministrators")]

【讨论】:

哇非常有趣的方法。我对此完全不熟悉。但我会试一试,如果我遇到困难,我希望你能提供进一步的帮助。无论如何,我将您的回答标记为问题的答案。谢谢! 您不应将答案标记为已接受,除非它确实解决了您的问题。它会误导未来的人。

以上是关于如何使用 JWT 令牌进行授权的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义策略模式实现 jwt 令牌基础身份验证以在 .net 核心中进行授权?

如何在 Node JS 中使用 jwt 授权具有不同令牌的所有用户

OAuth授权后如何向客户端发送jwt令牌?

JWT:如何在标头中发送授权?

如何使用 Apache Shiro 实现基于 JWT 令牌的身份验证机制?

如何执行 Auth0 JWT 令牌用户基于角色的授权