簡體   English   中英

如何使用 jwt 在 ASP.NET Core 2 中授權

[英]How to authorize in ASP.NET Core 2 using jwt

我在控制器中使用[Authorize]屬性進行身份驗證,但是當我收到對TestMethod的請求時,出現錯誤:“500 Internal..”。

我究竟做錯了什么??

我來自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();

還有來自控制器的代碼

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

你有想法嗎?

我正在使用這些庫來生成令牌:

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

我在試用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 => { });

如果要使用 [Authorize] 屬性,則需要制定策略:

     //new policy makes [Authorize] availible by claims

  services.AddAuthorization((options) => {
                options.AddPolicy("MyNewPolicy", policybuilder =>
                {               
                    policybuilder.RequireAuthenticatedUser();
                    policybuilder.RequireClaim("role", "someClaim");

                });
            });

//usage

        [Authorize(Roles = "someClaim")]
        public async Task<IActionResult> About(){


}

//to awnsr your comment add a list of claims to your user class ex:

   new TestUser
                {
                    SubjectId="1001",
                    Username="Frank",
                    Password="password",

                    Claims= new List<Claim>
                    {
                        new Claim("given_name","Frank"),
                        new Claim("family_name","Underwood"),
                        new Claim("address","1 addy rd unit 233"),                
                        new Claim("role", "someClaim")


                    }

                }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM