官方例子中,包含三个项目,client,api,server,client请求server获取授权token,然后用token请求api,这时api是如何验证token有效性的,是不是也要访问server去验证?
identityserver 负责的是根据验证通过的账号密码后发给客户端授权token,不负责验证Token本身。
token的验证本身是本地服务器对客户端有效性验证和服务器端有效性。
如果是 access token ,应该是自包含的,直接通过从token解密出来的信息验证其有效性
但是我在api项目里没有找到密钥,那他是怎么解密的
@oldli: 我们在 .net core 项目中通过 AddSigningCredential
配置了证书
IdentityServer4
中access_token
的有效性,是需要去server
端配合验证的。在官方的 https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Quickstarts/1_ClientCredentials/src/Api/Startup.cs 中,如下代码:
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ApiName = "api1";
});
就是配置 认证服务(server
)的配置。
也就是每次请求api都要去server端验证token吗
@oldli: 是的
@oldli: 如果认证服务和api服务是分开的话,验证操作走内网,还是很快的。
@hellotim: 看了源码,没找到具体在哪里去验证的
自己找到了
在Microsoft.AspNetCore.Authentication.JwtBearer的JwtBearerHandler类的HandleAuthenticateAsync方法里面有这么一段代码
if (_configuration == null && Options.ConfigurationManager != null)
{
_configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted);
}
上面的_configuration是OpenIdConnectConfiguration实例,OpenIdConnectConfiguration类里面由一个SigningKeys属性,该属性就是前面用的密钥,该密钥实在上面的GetConfigurationAsync方法里面获取的
GetConfigurationAsync方法里面会先判断配置是否存在,存在直接返回,不存在则去授权服务器获取
DateTimeOffset now = DateTimeOffset.UtcNow;
if (_currentConfiguration != null && _syncAfter > now)
{
return _currentConfiguration;
}
await _refreshLock.WaitAsync(cancel);
try
{
if (_syncAfter <= now)
{
try
{
// Don't use the individual CT here, this is a shared operation that shouldn't be affected by an individual's cancellation.
// The transport should have it's own timeouts, etc..
_currentConfiguration = await _configRetriever.GetConfigurationAsync(_metadataAddress, _docRetriever, CancellationToken.None).ConfigureAwait(false);
Contract.Assert(_currentConfiguration != null);
_lastRefresh = now;
_syncAfter = DateTimeUtil.Add(now.UtcDateTime, _automaticRefreshInterval);
}
catch (Exception ex)
{
_syncAfter = DateTimeUtil.Add(now.UtcDateTime, _automaticRefreshInterval < _refreshInterval ? _automaticRefreshInterval : _refreshInterval);
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX20803, (_metadataAddress ?? "null")), ex));
}
}
// Stale metadata is better than no metadata
if (_currentConfiguration != null)
return _currentConfiguration;
else
{
throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX20803, (_metadataAddress ?? "null"))));
}
}
finally
{
_refreshLock.Release();
}
获取流程是先调用http://localhost:4041/.well-known/openid-configuration获取认证服务的配置信息,然后根据配置信息中的jwks_uri=http://localhost:4041/.well-known/openid-configuration/jwks接口获取到签名密钥,拿到密钥之后才会去验证token
请问一下,如果是java写的api,拿到传来的token,需要怎么验证token的有效性呢