【问题标题】:How to authorize in ASP.NET Core 2 using jwt如何在 ASP.NET Core 2 中使用 jwt 进行授权
【发布时间】:2018-02-26 19:05:43
【问题描述】:

我在控制器中使用[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;

【问题讨论】:

  • 您是否在中间件管道中添加了app.UseAuthentication()?还有你为什么要写两次AddAuthentication
  • @Kahbazi 是的,添加了“app.UseAuthentication()”。接下来..所以,测试后它是“垃圾”,对不起,对于糟糕的代码,我将删除它。
  • 你是如何登录的?
  • @NevilleNazerane 登录成功,在我生成令牌之后。我的问题:我无法访问带有 [Authorize] 前缀的方法,我收到 500 错误。
  • 您的实际 500 错误应该显示在控制台的某处

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


【解决方案1】:

如果要使用 [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")


                    }

                }

【讨论】:

  • 没办法,我对所有授权用户都有不同的要求
【解决方案2】:

我在试用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] 前缀访问功能时,我仍然收到“错误 500”
  • 好的,在var auths = auth.Split(" ") 上放一个断点并运行它。你没在控制台上看到错误信息吗?
  • @Marc LaFleur - MSFT 没办法,我有这个错误来自 [authorize] 我无法检查和来自这个。
猜你喜欢
  • 2018-08-19
  • 2016-12-11
  • 2021-10-05
  • 2017-07-04
  • 2019-09-17
  • 1970-01-01
  • 2019-04-21
  • 2020-12-17
  • 2019-06-04
相关资源
最近更新 更多