首页新闻找找看学习计划

identityserver的api是如何验证token有效性的?

0
悬赏园豆:10 [已解决问题] 解决于 2018-10-23 18:00

官方例子中,包含三个项目,client,api,server,client请求server获取授权token,然后用token请求api,这时api是如何验证token有效性的,是不是也要访问server去验证?

oldli的主页 oldli | 初学一级 | 园豆:189
提问于:2018-10-18 11:37
< >
分享
最佳答案
0

identityserver 负责的是根据验证通过的账号密码后发给客户端授权token,不负责验证Token本身。

token的验证本身是本地服务器对客户端有效性验证和服务器端有效性。

  • 客户端有效性验证:就是单向加密对比验证,验证客户端是否被篡改
  • 服务器端验证:token在服务器端对应信息是否存在过期
收获园豆:10
慧☆星 | 大侠五级 |园豆:5384 | 2018-10-19 14:40
其他回答(3)
0

如果是 access token ,应该是自包含的,直接通过从token解密出来的信息验证其有效性

dudu | 园豆:40882 (高人七级) | 2018-10-18 11:40

但是我在api项目里没有找到密钥,那他是怎么解密的

支持(0) 反对(0) oldli | 园豆:189 (初学一级) | 2018-10-18 11:41

@oldli: 我们在 .net core 项目中通过 AddSigningCredential 配置了证书

支持(0) 反对(0) dudu | 园豆:40882 (高人七级) | 2018-10-18 11:55
0

IdentityServer4access_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)的配置。

hellotim | 园豆:1442 (小虾三级) | 2018-10-18 12:01

也就是每次请求api都要去server端验证token吗

支持(0) 反对(0) oldli | 园豆:189 (初学一级) | 2018-10-18 12:18

@oldli: 是的

支持(0) 反对(1) fangq | 园豆:377 (菜鸟二级) | 2018-10-18 13:52

@oldli: 如果认证服务和api服务是分开的话,验证操作走内网,还是很快的。

支持(0) 反对(0) hellotim | 园豆:1442 (小虾三级) | 2018-10-18 15:30

@hellotim: 看了源码,没找到具体在哪里去验证的

支持(0) 反对(0) oldli | 园豆:189 (初学一级) | 2018-10-19 08:31
0

自己找到了
在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

oldli | 园豆:189 (初学一级) | 2018-10-23 17:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册