ASP.NET Core: How to validate a JWT without access to the internet
这就是我在后端验证JWT承载令牌的方式:
1 2 3 4 5 6 7 8 9 | services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.Authority = $"https://{Configuration["Auth0:Authority"]}"; options.Audience = Configuration["Auth0:Audience"]; }); |
当.Net核心咨询权威机构以获取所需的信息(例如签名密钥)时,它可以正常工作。在我的情况下,它通过https://
问题是我的应用程序在无法访问Internet的Intranet中部署时无法与Auth0服务器通信。这是我得到的错误:
1 | System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'https://< My TENANT >.auth0.com/.well-known/openid-configuration'. |
我尝试手动输入RSA密钥,但不走运,出现相同错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | AddJwtBearer(options => { options.Authority = $"https://{Configuration["Auth0:Domain"]}"; options.Audience = Configuration["Auth0:Audience"]; options.TokenValidationParameters = new TokenValidationParameters { ValidateLifetime = true, RequireSignedTokens = true, ValidateIssuerSigningKey = true, IssuerSigningKey = GetRsaKey(), }; }); private SecurityKey GetRsaKey() { byte[] modulus = Decode("r5cpJ....-fUGjJCH1QQ"); byte[] exponent = Decode("A...AB"); var rsaParameters = new RSAParameters { Modulus = modulus, Exponent = exponent }; using var rsaProvider = new RSACryptoServiceProvider(); rsaProvider.ImportParameters(rsaParameters); return new RsaSecurityKey(rsaProvider); } |
有什么解决方法吗?
Nan Yu的答案非常准确,您可以使用以下高级选项:
-
配置一个固定密钥,并在后端使用它来验证令牌。这将工作一段时间,但是如果密钥不能可靠地同步,将来可能会严重损坏,并且Auth0更新令牌签名密钥,这可能会给您的公司带来严重的问题。
-
请确保您的后端具有作为可信提供者的Auth0的出站连接,以便系统可以以最简单,最标准的方式可靠地运行。
这感觉像是人员和流程问题,而不是技术问题。我不会尝试通过代码更改来解决它。
我怀疑IT管理员正在尝试实施过时的无互联网政策,这不利于您公司的利益。在IT级别,很容易仅将Auth0 URL列入白名单并阻止其他URL。
下一步,我将尝试说服您的涉众/老板支持标准设置-也许将其转发给他们。
但是问题是因为您无法与Auth0对话,这意味着您无法获取最新的公钥来验证Auth0发行的令牌,因此您应确认本地公钥与最新的公钥同步。通过Auth0。如果身份验证也由您控制,则可以考虑使用Identity Server4(它是本地身份验证/ SSO框架),或者可以实现JWT身份验证,如下所示。
因为您是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | private JwtSecurityToken GetJwtSecurityToken(List<Claim> user_claims) { string privateKey ="YOUR_PRIVATE_KEY"; var symmetricKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(privateKey)); var credentials = new SigningCredentials(symmetricKey, SecurityAlgorithms.HmacSha256); return new JwtSecurityToken ( issuer:"ISSUER_NAME", audience:"AUDIENCE", claims: user_claims, signingCredentials: credentials ); } |
1 | var token = new JwtSecurityTokenHandler().WriteToken(jwtToken); |
将令牌发送给用户或将其添加到cookie。
在您的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | services.AddAuthentication() .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, config => { config.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer ="ISSUER", ValidAudience ="AUDIENCE", IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("YOUR_PRIVATE_KEY")) }; }); |
1 | [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] |
仅此而已。希望有人能告诉我们是否有更好的解决方案。
更新1(添加参考):
检查本文,以使用JWT保护ASP.NET Core 2.0应用程序。