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.实 ...
随机推荐
- [leetcode]87. Scramble String字符串树形颠倒匹配
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrin ...
- Less入门及知识点整理
LESS « 一种动态样式语言 文档链接:http://www.bootcss.com/p/lesscss/ 百科 Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合( ...
- JS中的offset scroll event client
一.offset 一般用来检测盒子的偏移.位移,都是只读属性,不能赋值 offsetWidth和offsetHeight表示的是:调用者盒子的宽和高,包括盒子自身的padding和border off ...
- 编译UNITY的MONO模块记录
起因 接收到一个UNITY文件处理的任务(c#逻辑代码存放的Assembly-CSharp.dll可热更等需求) 需要重新编译UNITY的mono模块 用于安卓环境下对DLL的定制处理 上网查阅了一些 ...
- Java多线程系列3 synchronized 关键词
先来看一个线程安全的例子 ,两个线程对count进行累加,共累加10万次. public class AddTest { public static void main(String[] args) ...
- java多线程系列14 设计模式 Master-Worker
Master-Worker模式是常用的并行设计模式,可以将大任务划分为小任务,是一种分而治之的设计理念. 系统由两个角色组成,Master和Worker,Master负责接收和分配任务,Worker负 ...
- [uboot] (第五章)uboot流程——uboot启动流程
http://blog.csdn.net/ooonebook/article/details/53070065 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...
- 别人的Linux私房菜(11)认识与学习BASH
Linux下使用BASH Bourne Again Shell 另外一种由用于Unix的伯克利大学的Bill Joy设计的C Shell 系统中合法的shell会写入到/etc/sh ...
- jQuery三级联动
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- MySQL缓存参数优化(转)
MySQL 数据库性能优化之缓存参数优化 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在 ...