我有两组api应用程序(第1组:api11,api12;第2组:api21,api22),两个不同的组使用了javascript应用程序(第1组和第2组)。每个api组具有不同的域并使用不同的Identity Server实例(每个身份服务器也有不同的域)。业务要求是,从第1组登录到任何应用程序的用户可以使用该组中的任何应用程序,但无法使用第2组中的app或api。
在引擎盖下,api1和api2经常需要与相同的微服务交谈。我想要实现的是通过从任何身份服务器(由第1组或第2组应用程序使用)发出的访问令牌来访问微服务。有没有办法实现这个目标?对于一个身份服务器,我可以使用UseIdentityServerBearerTokenAuthentication,但作为参数,我只能在那里传递一个权限。
答案 0 :(得分:0)
不可直接(见this issue)
但您可能需要重新考虑您的架构。假设业务要求(业务要求是登录到组1中的任何应用程序的用户可以使用该组中的任何应用程序但不能使用来自组2的app或api。)是不可协商的,您要实现的目标可能是如果这些微服务正在处理一个或另一个群体非常特殊的东西(例如,我在这里谈论多租户),那就很危险了
在您的情况下,正确的方法是拥有独立的微服务实例,专用于不同的组,最好在自己的容器或虚拟机中运行
答案 1 :(得分:0)
所以我认为这应该是可能的,尽管你是否真的想要这样做是另一个问题!我没有试过这个,但你需要做一些事情:
使用IdentityServers中的相同签名证书
要验证您的JWT,请使用Microsoft扩展"UseJwtBearerAuthentication"而不是使用IdentityServer验证程序(使用UseIdentityServerAuthentication扩展而不是UseIdentityServerBearerTokenAuthentication设置 - 我认为后者是IdentityServer3)。 IdentityServer始终使用Microsoft验证器,code和docs:
我们的身份验证中间件与上述中间件的用途相同(事实上它在内部使用Microsoft JWT中间件)
直接使用Microsoft验证器的原因是,现在您可以避免在设置时设置权限,这通常用于验证" iss" (发行人)作为验证JWT的一部分。相反,您可以配置多个有效的颁发者(即您的两个IdentityServers),并将验证器直接指向您在步骤1中使用的签名证书:
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidIssuers = new[]
{
"http://my_first_IdentityServer/",
"http://my_second_IdentityServer/"
},
IssuerSigningKey = new X509SecurityKey(new X509Certificate2(certLocation))
};
app.UseJwtBearerAuthentication(new JwtBearerOptions()
{
Audience = "http://localhost:5001/",
AutomaticAuthenticate = true,
TokenValidationParameters = tokenValidationParameters
});
以上内容改编自文章here。正如文章中所说,您可以同样(并且最好)使用证书存储而不是证书文件。
顺便说一下,我们显然在这里谈论身份验证,你如何通过API授权用户无疑会增加额外的复杂性。