IdentityServer Token验证
查看源码: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验证的更多相关文章
- 服务器通过微信公众号Token验证测试的代码(Python版)
我在阿里云租了一个云服务器,然后想把这个作为我的微信公众号的后台,启用微信公众号开发者需要正确的响应微信服务器的Token验证,为此把这个验证的Python代码贴出来,只要在服务器上运行这段代码,注意 ...
- php开发公众号 token验证失败 其中一个原因
断断续续,弄了好几天,索性一狠心花了三个小时,总算找出问题了. "token验证失败" 可能原因有很多种,其他网友已经几乎穷尽了,但是我所遇到的在网络上没有看到,所以这里记录下. ...
- .NET 微信Token验证和消息接收和回复
public class wxXmlModel { public string ToUserName { get; set; } public string FromUserName { get; s ...
- 【JWT】JWT+HA256加密 Token验证
目录 Token验证 传统的Token验证 JWT+HA256验证 回到顶部 Token验证 最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twi ...
- php:微信公众号token验证失败原因、验证码显示不出来的问题
ob_clean(); 问题描述: 用微信官方提供的demo验证token是成功的,但是放到自己网站的框架上进行token验证老是提示"token验证失败",经过检查(用生成日志的 ...
- 基于.Net Framework 4.0 Web API开发(4):ASP.NET Web APIs 基于令牌TOKEN验证的实现
概述: ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题, ...
- Token验证失败
Token验证失败 微信 微信公众平台开发 Token校验失败 URL Token原文 http://www.cnblogs.com/txw1958/p/token-verify.html Token ...
- 微信公众平台Token验证失败的解决办法
微信公众平台Token验证失败的解决办法 1.可查看url和token是否正确 2.查看服务器端口是否为80端口 3.你可以通过记录log日志来判断是否接受到微信提交过来的信息 1.$fp=fopen ...
- 微信订阅号开发之token验证后,自动回复消息功能做好,发送消息没有返回
相信很多人会跟我一样,token验证之后,发送消息给订阅号,没有消息返回. 以下,说一下我辛苦调试得到的解决办法: 首先,token验证: 自己写的token一直验证失败,找了好久,没有发现bug.实 ...
随机推荐
- Js学习(3) 数组
数组本质: 本质上数组是特殊的对象,因此,数组中可以放入任何类型的数据,对象,数组,函数都行 它的特殊性在于键名是按次序排列好的整数 从0开始,是固定的,不用指定键名 如果数组中的元素仍是数组,则为多 ...
- node.js 调试问题
最近打算在项目过程中使用node.js辅助解决一些问题,需要用到node.js的调试技术. 通常而言,大家都会提到debugger或者node-inspector方法. debugger方法谁用谁知道 ...
- Django之Form、ModelForm 组件
Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...
- centos查看系统版本
显示系统版本 cat /etc/redhat-release cat /proc/version uname -a 查看位数 file /bin/ls
- C++ 提取网页内容系列之三
标 题: C++ 提取网页内容系列作 者: itdef链 接: http://www.cnblogs.com/itdef/p/4171659.html 欢迎转帖 请保持文本完整并注明出处 这次继续下载 ...
- 2019.03.01 bzoj3075: [Usaco2013]Necklace(kmp+dp)
传送门 题意简述:给出S,TS,TS,T两个字串,∣S∣≤10000,∣T∣≤1000|S|\le10000,|T|\le1000∣S∣≤10000,∣T∣≤1000,问至少从SSS中删去几个字符能够 ...
- MFC字体样式和颜色设置
在编写MFC界面程序时,可能会使用不同大小或者颜色的字体,这里稍做记录. 使用方法 CFont *m_pFont;//创建新的字体 m_pFont = new CFont; m_pFont->C ...
- JAVA 8 主要新特性 ----------------(一)总纲
一.版本中数据结构的修改浅析 二.JDK1.8优点概括 三.新功能Lambda表达式入门 四.Lambda函数式接口 五.Lambda方法引用与构造器引用 六.集合Stream API 七.新时间日期 ...
- 响应式---web设计之CSS3 Media Queries
一:设置视口 (view [vju:] 看; ==看待 port [pɔ:t] 接口)==视口 <meta name="viewport" content="w ...
- 判断终端类型、微信的文章防盗链、h5页面跳转打开新的app、跳转到app市场
判断终端的类型.安卓.ios.微信.qq function GetMobelType() { var browser = { ...