无法验证 UseJwtBearerAuthentication 中的令牌.授权被拒绝 [英] Cannot validate token in UseJwtBearerAuthentication. Authorization has been denied

查看:21
本文介绍了无法验证 UseJwtBearerAuthentication 中的令牌.授权被拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用单个 asp.net(4.6.1) Web 项目,显然我无法验证在同一服务器上生成的 jwt 令牌.
Startup.cs:

Using a single asp.net(4.6.1) web project, apparently I'm unable to validate the jwt token that was generated on the same server.
Startup.cs:

        var secret = Encoding.UTF8.GetBytes("12341234123412341234");
        var jwtFormatter = new CustomJwtFormat("Any", "local", secret);

        // This part checks the tokens
        app.UseJwtBearerAuthentication(new JwtBearerAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
            AuthenticationMode = AuthenticationMode.Active, // Block requests
            AllowedAudiences = new []{"Any"},
            TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKey = new InMemorySymmetricSecurityKey(secret),
                ValidAudience = "Any",
                ValidIssuer = "local"
            }
        });
        
        // This part issues tokens
        app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = false,
            TokenEndpointPath = new PathString("/auth"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = new CustomOAuthProvider(),
            AccessTokenFormat = jwtFormatter,
            RefreshTokenFormat = jwtFormatter
            
        });

        app.UseWebApi(config);

生成令牌的类看起来像

public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
{
    private readonly string _allowedAudience;
    private readonly string _issuer;
    private readonly byte[] _jwtTokenSignKey;

    public CustomJwtFormat(string allowedAudience, string issuer, byte[] jwtTokenSignKey)
    {
        _allowedAudience = allowedAudience;
        _issuer = issuer;
        _jwtTokenSignKey = jwtTokenSignKey;
    }

    public string Protect(AuthenticationTicket data)
    {
        if (data == null) throw new ArgumentNullException(nameof(data));
        
        var signingCredentials = new SigningCredentials
        (
            new InMemorySymmetricSecurityKey(_jwtTokenSignKey),
            "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256",
            "http://www.w3.org/2001/04/xmlenc#sha256"
        );

        return new JwtSecurityTokenHandler().WriteToken(new JwtSecurityToken(
            _issuer, 
            _allowedAudience, 
            data.Identity.Claims, 
            DateTime.UtcNow, DateTime.UtcNow.AddMinutes(10), 
            signingCredentials
        ));
        
    }

    public AuthenticationTicket Unprotect(string protectedText)
    {
        throw new NotImplementedException();
    }
}

我从 /auth 收到的令牌看起来有效,并在 jwt.io 上通过调试器(没有标记 base64 进行签名)

The tokens I receive from /auth look valid and pass the debugger on jwt.io (without marking base64 for signature)

但是 UseJwtBearerAuthentication 拒绝验证令牌.

However UseJwtBearerAuthentication refuses to validate the token.

这可能是什么原因?

此外,我尝试在没有 [Authorize] 的情况下手动验证控制器中的相同令牌,它会完美验证:

Moreover, I've tried manually validating the same token in a controller without [Authorize] and it would perfectly validate:

<代码>变种T =" eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEiLCJpc3MiOiJsb2NhbCIsImF1ZCI6IkFueSIsImV4cCI6MTQ3MjkxMDcwMSwibmJmIjoxNDcyOTEwMTAxfQ.ipSrRSGmje7wfzERsd-M1IDFJnN99AIC4Hs7YX4FIeI英寸;var TokenHandler = new JwtSecurityTokenHandler();;var key = Encoding.UTF8.GetBytes("12341234123412341234");SecurityToken 验证令牌;TokenValidationParameters paras = new TokenValidationParameters(){IssuerSigningKey = new InMemorySymmetricSecurityKey(key),ValidAudience =任何",ValidIssuer =本地"};TokenHandler.ValidateToken(t, paras, out validToken);

欧文 3.0.1.0System.IdentityModel.Tokens.Jwt 4.0.3.308261200

Owin 3.0.1.0 System.IdentityModel.Tokens.Jwt 4.0.3.308261200

推荐答案

问题不在于令牌验证,而在于声明没有传递给 Thread.CurrentPrincipal[Authorize] 属性正在读取.

The problem wasn't in the token validation, but rather the that the claims were not passed on to Thread.CurrentPrincipal that the [Authorize] attribute was reading from.

在 webapi 配置中:

config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(DefaultAuthenticationTypes.ExternalBearer));

在启动配置中:

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
    ...
});

app.UseJwtBearerAuthentication1(new JwtBearerAuthenticationOptions()
{
    AuthenticationType = DefaultAuthenticationTypes.ExternalBearer,
    ..
});

在 OAuthAuthorizationServerProvider 的 GrantResourceOwnerCredentials 中:
使用相同的身份验证类型,您可以从 context.Options

var identity = new ClaimsIdentity(youClaimsList, context.Options.AuthenticationType);
context.Validated(identity);

并确保所有 四个 位置都具有与 AuthenticationType 相同的字符串.如果 HostAuthenticationFilter 将具有不同的 authenticationType 作为输入,它不会将声明从 owin 传递到 webapi.

And ensure all four places have the same string as AuthenticationType. If the HostAuthenticationFilter will have a different authenticationType as input, it will not pass on the claims from owin to webapi.

这篇关于无法验证 UseJwtBearerAuthentication 中的令牌.授权被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆