本文共 1987 字,大约阅读时间需要 6 分钟。
如果使用 IdentityServer4 做授权服务的负载均衡,默认情况下是不可以的,比如有两个授权服务站点,一个资源服务绑定其中一个授权服务(Authority
配置),如果通过另外一个授权服务获取access_token
,然后拿这个access_token
去访问资源服务,会报 401 未授权错误,为什么?原因在这:
By default an access token will contain claims about the scope, lifetime (nbf and exp), the client ID (client_id) and the issuer name (iss).
归纳一下,生成access_token
受影响的因素:
access_token
,才能访问本服务。access_token
,无效访问。access_token
。access_token
。要让负载均衡下的两个授权服务,可以正常使用的话,需要确保两台授权服务以上五种因素完全一致,除了 issuer name (iss),其他因素都是一样的。
IdentityServer4 怎么设置 issuer name (iss)呢?答案是通过IssuerUri
:
IssuerUri
:Set the issuer name that will appear in the discovery document and the issued JWT tokens. It is recommended to not set this property, which infers the issuer name from the host name that is used by the clients, If not set, the issuer name is inferred from the request.说明中不建议我们进行设置,默认情况下,IdentityServer4 会从客户端的主机名中获取,可以认为,默认情况下,issuer name(IssuerUri
)就是授权服务的主机名(比如http://10.9.1.1:5000
)。
手动设置IssuerUri
代码:
var builder = services.AddIdentityServer(x => x.IssuerUri = "http://111.12.2.21:8000"); //slb 地址
资源服务授权配置修改:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions{ Authority = "http://111.12.2.21:8000", //slb 地址 ApiName = "trade_refund", RequireHttpsMetadata = false});
获取access_token
示例代码:
var client = new DiscoveryClient("http://111.12.2.21:8000"); //必须是 slb 地址,如果是单独的授权服务地址,会报错误(Value cannot be null. Parameter name: address)client.Policy.RequireHttps = false;var disco = await client.GetAsync();var tokenClient = new TokenClient(disco.TokenEndpoint, clientId, clientSecret);var tokenResponse = tokenClient.RequestClientCredentialsAsync(scope);var accessToken = tokenResponse.AccessToken;
通过 HTTP Post 获取access_token
(不通过 slb,直接请求单独的授权服务),可以授权访问资源服务,获取access_token
示例:
本文转自田园里的蟋蟀博客园博客,原文链接:http://www.cnblogs.com/xishuai/p/identityserver4-slb.html,如需转载请自行联系原作者