【问题标题】:IDX10503: Signature validation failedIDX10503:签名验证失败
【发布时间】:2016-01-13 08:24:41
【问题描述】:

在应用程序重新启动或发布后,我使用有效令牌收到以下错误

IDX10503: Signature validation failed. Keys tried: 'System.IdentityModel.Tokens.RsaSecurityKey
Exceptions caught:
token: '{"typ":"JWT","alg":"RS256","kid":null}.{"unique_name":"test@test.com","iss":"XXXXXX","aud":"XXXXX","exp":1444876186}'

这是生成KEY的函数

private void generateRsaKeys()
{
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
    {

        key = new RsaSecurityKey(rsa.ExportParameters(true));
        credentials = new SigningCredentials (key,SecurityAlgorithms.RsaSha256Signature, SecurityAlgorithms.Sha256Digest);
        rsa.PersistKeyInCsp = true;
    }
}

这样配置就完成了

services.ConfigureOAuthBearerAuthentication(options =>
{
    options.AutomaticAuthentication = true;
    options.TokenValidationParameters.IssuerSigningKey = generateRsaKeys();
    options.TokenValidationParameters.ValidAudience = audience;
    options.TokenValidationParameters.ValidIssuer = issuer;

});

app.UseStaticFiles();
app.UseOAuthBearerAuthentication();

// Add MVC to the request pipeline.
app.UseMvc();

这是我控制器上的操作

// POST: /token
[HttpPost()]
public async Task<IActionResult> Token([FromBody] LoginModel model)
{
    if (!ModelState.IsValid)
        return HttpBadRequest();

    JwtSecurityTokenHandler handler = _bearerOptions.SecurityTokenValidators.OfType<JwtSecurityTokenHandler>().First();

    try
    {
        var user = await _Repo.GetDetailAsync(model.Email);
        if (!model.Password.Equals(user.Password))
            return HttpUnauthorized();

        JwtSecurityToken securityToken = handler.CreateToken
        (
            issuer: _bearerOptions.TokenValidationParameters.ValidIssuer,
            audience: _bearerOptions.TokenValidationParameters.ValidAudience,
            signingCredentials: _signingCredentials,
            subject: new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, user.Email) }),
            expires: DateTime.Now.AddMinutes(2)
        );

        string token = handler.WriteToken(securityToken);

        return new ObjectResult(new TokenModel() { AccessToken = token, TokenType = "bearer" });

    }
    catch (Exception ex)
    {
        // TODO: add loggin logic here 
        return HttpUnauthorized();
    }

}

【问题讨论】:

    标签: oauth-2.0 asp.net-core


    【解决方案1】:

    如果您每次(重新)启动服务器时都生成一个新的 RSA 密钥,那么这并不奇怪:使用 KEY A 签名的令牌无法使用 KEY B 进行验证。为了使您的方案正常工作,您需要将 RSA 密钥存储在某处并在启动期间使用相同的密钥。

    一种方法是调用rsa.ExportParameters(true) 并将不同的参数存储在某处,这样您就可以使用rsa.ImportParameters(...) 轻松检索和导入它们。


    但您最好的选择是使用AspNet.Security.OpenIdConnect.Server,它会在最新版本中自动为您生成并存储一个 RSA 密钥:

    Startup.cs

        public class Startup {
            public void ConfigureServices(IServiceCollection services) {
                services.AddAuthentication();
                services.AddCaching();
            }
    
            public void Configure(IApplicationBuilder app) {
                // Add a new middleware validating access tokens issued by the OIDC server.
                app.UseJwtBearerAuthentication(options => {
                    options.AutomaticAuthentication = true;
                    options.Authority = "resource_server_1";
                    options.RequireHttpsMetadata = false;
                });
    
                // Add a new middleware issuing tokens.
                app.UseOpenIdConnectServer(options => {
                    options.AllowInsecureHttp = true;
    
                    options.Provider = new OpenIdConnectServerProvider {
                        // Override OnValidateClientAuthentication to skip client authentication.
                        OnValidateClientAuthentication = context => {
                            // Call Skipped() since JS applications cannot keep their credentials secret.
                            context.Skipped();
    
                            return Task.FromResult<object>(null);
                        },
    
                        // Override OnGrantResourceOwnerCredentials to support grant_type=password.
                        OnGrantResourceOwnerCredentials = context => {
                            // Do your credentials validation here.
                            // Note: you can call Rejected() with a message
                            // to indicate that authentication failed.
    
                            var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
                            identity.AddClaim(ClaimTypes.NameIdentifier, "todo");
    
                            // By default, claims are not serialized in the access and identity tokens.
                            // Use the overload taking a "destination" to make sure your claims
                            // are correctly inserted in the appropriate tokens.
                            identity.AddClaim("urn:customclaim", "value", "token id_token");
    
                            var ticket = new AuthenticationTicket(
                                new ClaimsPrincipal(identity),
                                new AuthenticationProperties(),
                                context.Options.AuthenticationScheme);
    
                            // Call SetResources with the list of resource servers
                            // the access token should be issued for.
                            ticket.SetResources(new[] { "resource_server_1" });
    
                            // Call SetScopes with the list of scopes you want to grant
                            // (specify offline_access to issue a refresh token).
                            ticket.SetScopes(new[] { "profile", "offline_access" });
    
                            context.Validated(ticket);
    
                            return Task.FromResult<object>(null);
                        }
                    }
                });
    
                app.UseMvc();
            }
        }
    

    project.json

        {
          "dependencies": {
            "Microsoft.AspNet.Server.WebListener": "1.0.0-rc1-final",
            "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
            "Microsoft.AspNet.Authentication.JwtBearer": "1.0.0-rc1-final",
            "AspNet.Security.OpenIdConnect.Server": "1.0.0-beta4"
          }
        }
    

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 2018-01-03
      • 2021-08-12
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 2017-11-28
      相关资源
      最近更新 更多