IDX10503:签名验证失败 [英] IDX10503: Signature validation failed

查看:238
本文介绍了IDX10503:签名验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I getting the following error with a valid token after the application re-start or publish

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();

这是我的控制器上的动作

and this is the action on my controller

// 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();
    }

}

推荐答案

如果每次(重新)启动服务器时都在生成一个新的RSA密钥,那也就不足为奇了:无法验证使用KEY A签名的令牌使用KEY B.为了使方案正常工作,您需要将RSA密钥存储在某个位置,并在启动过程中使用相同的密钥.

If you're generating a new RSA key each time you (re)start your server, then it's not surprising: tokens signed with KEY A cannot be validated using KEY B. For your scenario to work, you need to store your RSA key somewhere and use the same one during startup.

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

One way is to call rsa.ExportParameters(true) and store the different parameters somewhere, so you can easily retrieve and import them using rsa.ImportParameters(...).

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

But your best option is to use AspNet.Security.OpenIdConnect.Server, that will automatically generate and store a RSA key for you in the last version:

    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"
      }
    }

这篇关于IDX10503:签名验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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