How to Authorize Using JWT token

时间:2019-01-09 22:19:39

标签: c# asp.net-core jwt

I have a web api end point that give me JWT token. It is not an fully authorization server. It just can generate a JWT token.

Now I have another web app written in aspnet core. In which inside the startup.cs I have added the following lines so that I can authorize using the JWT token I receive

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

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

I also have a login form (in the web app) where user enters username and password that I send to web api and get the token. And to protect any controller in the web app I just use the [Authorize] attribute.

Everything works fine until the token expires. The token is very short lived but it does come with a refresh token.

My question is that , how can I detect that the Token (from the web api) is now expired and I need to get a new one using the refresh token. I know that in javascript world I can intercept the http request and renew the token with the refresh token.

But how do I do this in an aspnet core client app??

(NOTE: I do not want to use any authentication server like IdentityServer4 etc)

Thank you in advance!!

1 个答案:

答案 0 :(得分: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和Custom身份验证方案进行身份验证来更改授权系统的默认策略。

这不会阻止您对某些操作施加更多限制; [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")]