【问题标题】:ASP.Net 5 - OAuth bearer token (JWT) validation errorASP.Net 5 - OAuth 持有者令牌 (JWT) 验证错误
【发布时间】:2015-07-14 04:00:20
【问题描述】:

我一直在开发一个系统,以使用 JSON Web 令牌对我的网站上的用户进行身份验证和授权。我的系统即将完成,但是当我尝试在代码中使用 [Authorize("Bearer")] 属性时遇到错误。错误如下:

System.IdentityModel.Tokens.SecurityTokenInvalidSignatureException 发生 消息:抛出异常:Microsoft.IdentityModel.Logging.dll 中的“System.IdentityModel.Tokens.SecurityTokenInvalidSignatureException” 附加信息:IDX10503:签名验证失败。尝试的键:''。 捕获的异常: ''。 令牌:'{"typ":"JWT","alg":"RS256","kid":null}.{"nameid":"6581f5a0-1775-4ce4-8650-a3d7e613b216","unique_name":"alex ","AspNet.Identity.SecurityStamp":"8da933c3-0f88-42ea-876d-c07e99d1eecc","iss":"Uniti","aud":"Uniti","exp":1436849284,"nbf":1436845684} '

我不明白为什么它不使用 JWT 测试任何密钥。我的启动文件中定义了一个 RSA 密钥。在没有进一步拖延的情况下,我在下面提供了解决此错误可能需要的代码。

我的启动代码(生成密钥和 OAuthBearer 选项):

#region RSA Key Generation

        var rsa = new RSACryptoServiceProvider(2048);
        var rsaKey = rsa.ExportParameters(true);
        var key = new RsaSecurityKey(rsaKey);

        services.AddInstance(new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest));

        #endregion

        services.AddInstance(new OAuthBearerAuthenticationOptions
        {
            SecurityTokenValidators = new List<ISecurityTokenValidator>
            {
                new JwtSecurityTokenHandler()
            },
            TokenValidationParameters = new TokenValidationParameters
            {
                IssuerSigningKey = key,
                ValidIssuer = "Uniti",
                ValidAudience = "Uniti"
            },
        });

        services.AddAuthorization();
        services.ConfigureAuthorization(auth =>
        {
            auth.AddPolicy("Bearer", builder =>
            {
                builder.AddAuthenticationSchemes(OAuthBearerAuthenticationDefaults.AuthenticationScheme);
                builder.RequireAuthenticatedUser();
            });
        });

我的令牌生成代码:

var claimsIdentity = (ClaimsIdentity) User.Identity;

            var handler = BearerOptions.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();
            var securityToken = handler.CreateToken(
                issuer: "Uniti",
                audience: "Uniti",
                signingCredentials: BearerCredentials,
                subject: claimsIdentity
                );

            var token = handler.WriteToken(securityToken);

我是否忘记在某处添加某些内容,或者我是否错误地生成了密钥?如果您能帮助我,请提前感谢!

【问题讨论】:

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


    【解决方案1】:

    我敢打赌这是由于注册 OAuth2 不记名选项的不正确方式,正如我之前的回答中已经解释的那样:https://stackoverflow.com/a/31322654/542757

    services.AddInstance(new OAuthBearerAuthenticationOptions());
    

    当您使用 services.AddInstance 时,OAuth2 承载中间件无法检索选项(因此也无法检索密钥),因为它在内部使用 IOptions&lt;OAuthBearerAuthenticationOptions&gt; 而不是 OAuthBearerAuthenticationOptions

    这是注册 OAuth2 不记名选项的正确方法:

    services.ConfigureOAuthBearerAuthentication(options => {
        // Configure the options used by the OAuth2 bearer middleware.
    });
    

    【讨论】:

    • 当我使用 ConfigureOAuthBearer 功能时,它不会将服务添加到服务集合中。我必须添加它,然后配置它吗?
    • 不应该尝试手动添加OAuthBearerAuthenticationOptions。如果您需要从自己的代码中解析OAuthBearerAuthenticationOptions,请改用IOptions&lt;OAuthBearerAuthenticationOptions&gt;context.RequestServices.GetRequiredService&lt;IOptions&lt;OAuthBearerAuthenticationOptions&gt;&gt;().Options
    • 那只是返回 null
    • 那你做错了,因为默认选项管理器不能返回空值:github.com/aspnet/Options/blob/dev/src/…
    • 不客气!作为旁注,您真的应该考虑使用 OAuth2 或 OpenID Connect 服务器,而不是直接依赖 JwtSecurityTokenHandler 来创建您的令牌,因为它会提供一种标准化且更安全的方法。
    猜你喜欢
    • 2015-06-04
    • 2019-10-20
    • 2016-05-17
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2019-06-14
    • 2018-08-30
    • 2020-09-04
    相关资源
    最近更新 更多