如何使用jwt在ASP.NET Core 2中进行授权

时间:2018-02-26 19:05:44

标签: c# asp.net-mvc asp.net-core asp.net-core-2.0

我在我的控制器中使用[Authorize]属性进行身份验证,但当我收到TestMethod的请求时,我收到错误:" 500内部..&#34 ;。

我做错了什么?

我的代码来自StartUp.cs

services.AddAuthorization(options =>
{
    options.DefaultPolicy =
        new AuthorizationPolicyBuilder("Identity.Application")
        .RequireAuthenticatedUser()
        .Build();
});

services
    .AddAuthentication(option =>
    {
        option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.TokenValidationParameters =
            new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                SaveSigninToken = true,
                ValidateIssuer = true,
                ValidIssuer = "http://blabla/",
                ValidateAudience = true,
                ValidAudience = "http://blabla/",
                ValidateLifetime = true,
                IssuerSigningKey = blabla.bla(),
                ValidateIssuerSigningKey = true,
            };
    });

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme);
services.AddMvc();

还有来自Controller的代码

[Route("test"), HttpPost]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public void Test() { }

你有想法吗?

我使用这些库来生成令牌:

System.IdentityModel.Tokens.Jwt;
Microsoft.IdentityModel.Tokens;

1 个答案:

答案 0 :(得分:0)

我在试用AddJwtBearer时遇到了很多问题。最后,我发现手动登录并不是那么难,工作轻松,也更容易调试。

基本上,我首先创建了一个用于创建和验证令牌的辅助类。以下是该类的源代码:https://github.com/neville-nazerane/netcore-jwt-sample/blob/master/website/TokenGenerator.cs。您在TokenValidationParameters中添加的所有内容都可以进入此课程。

一旦你有了这个,这是一个锅炉板认证方案:

public class TokenAuthenticationOptions : AuthenticationSchemeOptions
{
}

public class TokenAuthentication : AuthenticationHandler<TokenAuthenticationOptions>
{

    public const string SchemeName = "TokenAuth";

    public TokenAuthentication(IOptionsMonitor<TokenAuthenticationOptions> options, ILoggerFactory logger, 
                                UrlEncoder encoder, ISystemClock clock) 
                                    : base(options, logger, encoder, clock)
    {
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        return Task.Run(() => Authenticate());
    }

    private AuthenticateResult Authenticate()
    {
        string auth, token;
        auth = Context.Request.Headers["Authorization"];
        if (auth == null) return AuthenticateResult.Fail("No JWT token provided");
        var auths = auth.Split(" ");
        if (auths[0].ToLower() != "bearer") return AuthenticateResult.Fail("Invalid authentication");
        token = auths[1];

        try
        {
            var generator = new TokenGenerator();
            var principal = generator.Validate(token);
            return AuthenticateResult.Success(new AuthenticationTicket(principal, SchemeName));
        }
        catch
        {
            return AuthenticateResult.Fail("Failed to validate token");
        }
    }
}

最后,在你的启动中,你可以这样使用这个方案:

services.AddAuthentication(TokenAuthentication.SchemeName)
    .AddScheme<TokenAuthenticationOptions, TokenAuthentication>
            (TokenAuthentication.SchemeName, o => { });