查看源码:https://github.com/IdentityServer/IdentityServer4/tree/release

API使用Client Credentials的token验证是使用jwt验证的

找到JwtBearerClientAssertionSecretParser 类

public async Task<ParsedSecret> ParseAsync(HttpContext context)
        {
            _logger.LogDebug("Start parsing for JWT client assertion in post body");

            if (!context.Request.HasFormContentType)
            {
                _logger.LogDebug("Content type is not a form");
                return null;
            }

            var body = await context.Request.ReadFormAsync();

            if (body != null)
            {
                var clientAssertionType = body[OidcConstants.TokenRequest.ClientAssertionType].FirstOrDefault();
                var clientAssertion = body[OidcConstants.TokenRequest.ClientAssertion].FirstOrDefault();

                if (clientAssertion.IsPresent()
                    && clientAssertionType == OidcConstants.ClientAssertionTypes.JwtBearer)
                {
                    if (clientAssertion.Length > _options.InputLengthRestrictions.Jwt)
                    {
                        _logger.LogError("Client assertion token exceeds maximum lenght.");
                        return null;
                    }

                    var clientId = GetClientIdFromToken(clientAssertion);
                    if (!clientId.IsPresent())
                    {
                        return null;
                    }

                    if (clientId.Length > _options.InputLengthRestrictions.ClientId)
                    {
                        _logger.LogError("Client ID exceeds maximum lenght.");
                        return null;
                    }

                    var parsedSecret = new ParsedSecret
                    {
                        Id = clientId,
                        Credential = clientAssertion,
                        Type = IdentityServerConstants.ParsedSecretTypes.JwtBearer
                    };

                    return parsedSecret;
                }
            }

            _logger.LogDebug("No JWT client assertion found in post body");
            return null;
        }

首先从Context中拿到token信息

然后从中解析出ClientId

private string GetClientIdFromToken(string token)
        {
            try
            {
                var jwt = new JwtSecurityToken(token);
                return jwt.Subject;
            }
            catch (Exception e)
            {
                _logger.LogWarning("Could not parse client assertion", e);
                return null;
            }
        }

获取到ClientId后进行判断

public async Task<ClientSecretValidationResult> ValidateAsync(HttpContext context)
        {
            _logger.LogDebug("Start client validation");

            var fail = new ClientSecretValidationResult
            {
                IsError = true
            };

            var parsedSecret = await _parser.ParseAsync(context);
            if (parsedSecret == null)
            {
                await RaiseFailureEventAsync("unknown", "No client id found");

                _logger.LogError("No client identifier found");
                return fail;
            }

            // load client
            var client = await _clients.FindEnabledClientByIdAsync(parsedSecret.Id);
            if (client == null)
            {
                await RaiseFailureEventAsync(parsedSecret.Id, "Unknown client");

                _logger.LogError("No client with id '{clientId}' found. aborting", parsedSecret.Id);
                return fail;
            }

            if (!client.RequireClientSecret || client.IsImplicitOnly())
            {
                _logger.LogDebug("Public Client - skipping secret validation success");
            }
            else
            {
                var result = await _validator.ValidateAsync(parsedSecret, client.ClientSecrets);
                if (result.Success == false)
                {
                    await RaiseFailureEventAsync(client.ClientId, "Invalid client secret");
                    _logger.LogError("Client secret validation failed for client: {clientId}.", client.ClientId);

                    return fail;
                }
            }

            _logger.LogDebug("Client validation success");

            var success = new ClientSecretValidationResult
            {
                IsError = false,
                Client = client,
                Secret = parsedSecret
            };

            await RaiseSuccessEventAsync(client.ClientId, parsedSecret.Type);
            return success;
        }

验证

public async Task<SecretValidationResult> ValidateAsync(ParsedSecret parsedSecret, IEnumerable<Secret> secrets)
        {
            var secretsArray = secrets as Secret[] ?? secrets.ToArray();

            var expiredSecrets = secretsArray.Where(s => s.Expiration.HasExpired(_clock.UtcNow.UtcDateTime)).ToList();
            if (expiredSecrets.Any())
            {
                expiredSecrets.ForEach(
                    ex => _logger.LogWarning("Secret [{description}] is expired", ex.Description ?? "no description"));
            }

            var currentSecrets = secretsArray.Where(s => !s.Expiration.HasExpired(_clock.UtcNow.UtcDateTime)).ToArray();

            // see if a registered validator can validate the secret
            foreach (var validator in _validators)
            {
                var secretValidationResult = await validator.ValidateAsync(currentSecrets, parsedSecret);

                if (secretValidationResult.Success)
                {
                    _logger.LogDebug("Secret validator success: {0}", validator.GetType().Name);
                    return secretValidationResult;
                }
            }

            _logger.LogDebug("Secret validators could not validate secret");
            return new SecretValidationResult { Success = false };
        }

在Web API项目中可以直接从Request中拿到token

var bearer = (((Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameRequestHeaders)Request.Headers).HeaderAuthorization);
            var token = bearer.ToString().Replace("Bearer ", "");
            JwtSecurityToken jwt = new JwtSecurityToken(token);
            var clientId = jwt.Claims.FirstOrDefault(x => x.Type == "client_id").Value;

IdentityServer Token验证的更多相关文章

  1. 服务器通过微信公众号Token验证测试的代码(Python版)

    我在阿里云租了一个云服务器,然后想把这个作为我的微信公众号的后台,启用微信公众号开发者需要正确的响应微信服务器的Token验证,为此把这个验证的Python代码贴出来,只要在服务器上运行这段代码,注意 ...

  2. php开发公众号 token验证失败 其中一个原因

    断断续续,弄了好几天,索性一狠心花了三个小时,总算找出问题了. "token验证失败" 可能原因有很多种,其他网友已经几乎穷尽了,但是我所遇到的在网络上没有看到,所以这里记录下. ...

  3. .NET 微信Token验证和消息接收和回复

    public class wxXmlModel { public string ToUserName { get; set; } public string FromUserName { get; s ...

  4. 【JWT】JWT+HA256加密 Token验证

    目录 Token验证 传统的Token验证 JWT+HA256验证 回到顶部 Token验证 最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twi ...

  5. php:微信公众号token验证失败原因、验证码显示不出来的问题

    ob_clean(); 问题描述: 用微信官方提供的demo验证token是成功的,但是放到自己网站的框架上进行token验证老是提示"token验证失败",经过检查(用生成日志的 ...

  6. 基于.Net Framework 4.0 Web API开发(4):ASP.NET Web APIs 基于令牌TOKEN验证的实现

    概述:  ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题, ...

  7. Token验证失败

    Token验证失败 微信 微信公众平台开发 Token校验失败 URL Token原文 http://www.cnblogs.com/txw1958/p/token-verify.html Token ...

  8. 微信公众平台Token验证失败的解决办法

    微信公众平台Token验证失败的解决办法 1.可查看url和token是否正确 2.查看服务器端口是否为80端口 3.你可以通过记录log日志来判断是否接受到微信提交过来的信息 1.$fp=fopen ...

  9. 微信订阅号开发之token验证后,自动回复消息功能做好,发送消息没有返回

    相信很多人会跟我一样,token验证之后,发送消息给订阅号,没有消息返回. 以下,说一下我辛苦调试得到的解决办法: 首先,token验证: 自己写的token一直验证失败,找了好久,没有发现bug.实 ...

随机推荐

  1. Springboot学习05-自定义错误页面完整分析

    Springboot学习06-自定义错误页面完整分析 前言 接着上一篇博客,继续分析Springboot错误页面问题 正文 1-自定义浏览器错误页面(只要将自己的错误页面放在指定的路径下即可) 1-1 ...

  2. 386. Lexicographical Numbers 输出1到n之间按lexico排列的数字序列

    [抄题]: Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,1 ...

  3. PHP并发之Swoole

    <?php /** * Created by PhpStorm. * User: zhezhao * Date: 2016/10/20 * Time: 10:51 */ $url_arr = a ...

  4. Java集合:LinkedList源码解析

    Java集合---LinkedList源码解析   一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...

  5. JDK源码核心包

    一.核心包有哪些? Jdk的包中,除开了lang包下面的类,用得最多的应该要属于util包下面的类了, 本篇文章主要针对Jdk的util包下面的类(util目录下面的类,暂时不包括util 包下面的子 ...

  6. async/await让你的代码更加优雅

    一. 回调地狱:回调函数里面嵌套着回调函数嵌套着回调函数”,这就是被传说中的“回调地狱callbackHell () { const api = new Api() let user, friends ...

  7. MySQL insert语句锁分析

    最近对insert的锁操作比较费解,所以自己动手,一看究竟.主要是通过一下三个sql来看一下执行中的sql的到底使用了什么锁. select * from information_schema.INN ...

  8. C#顺序表 & 单向链表(无头)

    C# 顺序表 非常标准的顺序表结构,等同于C#中的List<T>,但是List<T>在排错查询和数据结构替换上存在缺陷,一些情况会考虑使用自己定义的数据结构 1.优化方向 下表 ...

  9. 关于UIScrollView不能响应UITouch事件的解决办法

    原因是:UIView的touch事件被UIScrollView捕获了. 解决办法:让UIScrollView将事件传递过去.于是最简单的解决办法就是加一个UIScrollView的category.这 ...

  10. Mac 下 Java 多版本切换

    Step 1: 安装 jdk1.7 jdk1.8 路径如下: + /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk + /Library/Java/J ...