如何从单个服务端点发出和验证 jwt?
Posted
技术标签:
【中文标题】如何从单个服务端点发出和验证 jwt?【英文标题】:How to issue and validate jwt from single service endpoint? 【发布时间】:2019-03-03 20:35:51 【问题描述】:我已在 Angular 前端 Web 应用程序和 .Net Core Web API 后端(用于获取数据)之间成功连接了一个基于令牌的授权系统。
现在,我想将 JWT Logic(生成和验证)整合到第三个 Web API .Net Core 项目中。
如何将以下逻辑“移动”到单独的 Web API 中以进行令牌验证?
在 Startup.cs 中:
public void ConfigureServices(IServiceCollection services)
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
options.TokenValidationParameters = new TokenValidationParameters
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidAudiences = new List<string> "Audience1", "Audience2" ,
ValidIssuer = "Credit Card oAuth Web API",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"))
;
); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
在控制器中:
[Authorize (Roles = "Credit Card Administrator")]
public ActionResult<string> Get(int id)
return "value";
我想保留 Roles 的逻辑(因为在 JWT 中设置了这样的声明,所以它正在工作):
var userClaims = new List<Claim>()
new Claim(JwtRegisteredClaimNames.Sub, name),
new Claim(JwtRegisteredClaimNames.Email, "user.name@company.com"),
new Claim(JwtRegisteredClaimNames.GivenName, "User Name"),
new Claim(ClaimTypes.Role, "Customer Administrator"),
new Claim(ClaimTypes.Role, "Credit Card Administrator"),
new Claim(ClaimTypes.Role, "Counter Administrator")
;
// TODO: Refactor The Following: Get token from oAuth Service (pass in Audience and Claims)
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokenOptions = new JwtSecurityToken(
issuer: "http://localhost:58726",
audience: "http://localhost:58726",
claims: userClaims,
expires: DateTime.Now.AddMinutes(20),
signingCredentials: signinCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
我希望这是有道理的,并感谢任何帮助。
【问题讨论】:
不确定“想要将 JWT 逻辑(生成和验证)整合到第三个 Web API .Net Core 项目中”是什么意思。 .您是想设置一个作为不同 Web 服务器运行的 OpenAuth,还是创建另一个在同一个网站上运行的解决方案子项目? 这正是 IdentityServer4 所做的。它将您的身份验证服务器分开。 @itminus 我认为你是正确的,我正在尝试创建一个将在另一台服务器上运行的 oauth 项目。我想将发送到数据控制器的 JWT 传递给 oath 服务进行验证。 @Sasan 谢谢。我会看看 Identity Server 4。它是一个框架还是一个 3rd 方服务? 【参考方案1】:如何将以下逻辑“移动”到单独的 Web API 中以进行令牌验证?
您要移动的逻辑是 ASP.NET Core 身份验证中间件的一部分,其中包括这些职责。
-
从 HTTP 请求的
Authorize
标头中读取访问令牌(不记名令牌),
验证访问令牌,
将访问令牌的声明显示为Authorize
属性。
在这种情况下,访问令牌被编码为 JWT。
听起来您想在单独的服务器上执行步骤 (2)。如果是这种情况,您可能正在寻找 OAuth Introspection。
GitHub 上有一些extensions for that here。此外,AspNet.Security.OAuth.Extensions Error while introspection 问题和答案将帮助您为 OAuth Introspection 配置这些扩展。
【讨论】:
谢谢肖恩。这似乎是我想要做的。我希望 OAth 服务将接受 JWT 令牌进行验证,并且我现有的“数据”Web api 项目将能够传递它。我快速检查了链接(还没有完全消化其中的内容),我没有看到任何对 JWT 的引用......但我保证我会很快完整阅读它们。 “秘密”应该存储在哪里?它应该存储在两个地方吗?我有三个“项目”:oAuth Web 服务、Web 应用程序(客户端)和 Web API(数据的来源)。秘密是否应该只存储在 oAuth Web 服务器中?还是应该同时存储在客户端和 oAuth 项目中? 你具体指的是什么秘密? 有一个秘密用于加密 JWT 中的凭证。它也是客户端和认证服务器之间共享的秘密。但是,就我而言,因为我可以控制所有三个项目,所以我不确定该密钥是否应该仅存储在 oAuth 服务或客户端中。 据我所知,如果我们使用自省,那么只有授权服务器需要 JWT 密码。验证/解密/解析 JWT 成为自省端点的工作。确认我在这里说的话oauth.com/oauth2-servers/token-introspection-endpoint不要相信我的话,因为我有一段时间没有深入研究内省了。以上是关于如何从单个服务端点发出和验证 jwt?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JwtSecurityTokenHandler 和 JWKS 端点验证 JWT?
来自 C# HttpClient 针对 Spring 服务器 JWT 令牌的身份验证