How to add token validation only for protected act

2019-05-02 01:13发布

问题:

I have added a JWT middleware to my application:

app.UseJwtBearerAuthentication(options => { options.AutomaticAuthenticate = true;} )

Now if my token does not validate (e.g. expired), I still get an error that lifetime validation did not pass. Is there a way to make the middleware validate the token only for protected resources? And if not, then how and where should I call what middleware does myself (reading the token into HttpContext.User)?

P.S This is how I add protection:

services.AddMvc(config =>
{
    var policy = new AuthorizationPolicyBuilder()
                     .RequireAuthenticatedUser()
                     .Build();

    config.Filters.Add(new AuthorizeFilter(policy));
});

And this is how I allow public access:

[HttpGet]
[AllowAnonymous]
public string Get(int id)
{
}

To clarify: without the token this will work, but if the token is not valid (e.g. expired) even the public resource won't be accessible and 500 will be thrown (due to some internal bug cause 401 should be there really).

回答1:

First, you need to disable automatic authentication by setting AutomaticAuthentication to false in your JWT bearer options.

To ensure the JWT bearer middleware is called for specific actions, you can create your own authorization policy using AddAuthenticationSchemes:

public void ConfigureServices(IServiceCollection services) {
    services.AddAuthorization(options => {
        options.AddPolicy("API", policy => {
            policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
            policy.RequireAuthenticatedUser();
        });
    });
}

Then, decorate your controller actions with the Authorize attribute:

[Authorize(Policy = "API")]
[HttpGet("your-action")]
public IActionResult Action() {
    ...
}