JWT 如何添加自定义声明和解码声明
Posted
技术标签:
【中文标题】JWT 如何添加自定义声明和解码声明【英文标题】:JWT How to add custom claims and decode claims 【发布时间】:2019-02-26 23:44:27 【问题描述】:我正在尝试检索我在创建令牌时所做的一些自定义声明。但是,我不确定我应该写什么来检索这些声明。
这是我的令牌创建函数
public String createToken(AuthenticationDTO Input)
//Set issued at date
DateTime issuedAt = DateTime.UtcNow;
//set the time when it expires
DateTime expires = DateTime.UtcNow.AddDays(7);
//http://***.com/questions/18223868/how-to-encrypt-jwt-security-token
var tokenHandler = new JwtSecurityTokenHandler();
//create a identity and add claims to the user which we want to log in
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new[]
new Claim("UserName", Input.UserName),
new Claim("Email",Input.Email),
new Claim("PhoneNumber",Input.PhoneNumber),
new Claim("FirstName",Input.FirstName),
new Claim("LastName",Input.LastName),
new Claim("Id",Input.Id)
);
const string sec = HostConfig.SecurityKey;
var now = DateTime.UtcNow;
var securityKey = new SymmetricSecurityKey(System.Text.Encoding.Default.GetBytes(sec));
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
//create the jwt
var token =(JwtSecurityToken)
tokenHandler.CreateJwtSecurityToken(issuer: HostConfig.Issuer, audience: HostConfig.Audience,
subject: claimsIdentity, notBefore: issuedAt, expires: expires, signingCredentials: signingCredentials);
var tokenString = tokenHandler.WriteToken(token);
return tokenString;
我决定命名我自己的声明,而不是使用提供的标准声明。但是,我不知道如何检索它们。这是我目前拥有的:
public AuthenticationDTO DecodeToken(String Input)
var key = Encoding.ASCII.GetBytes(HostConfig.SecurityKey);
var handler = new JwtSecurityTokenHandler();
var tokenSecure = handler.ReadToken(Input) as SecurityToken;
var validations = new TokenValidationParameters
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
;
var claims = handler.ValidateToken(Input, validations, out tokenSecure);
return null;
编辑:
我注意到我的索赔是这样来的
如何提取它们?
EDIT2:
添加了 AuthentcationDTO
public class AuthenticationDTO
public String Id get; set;
public String UserName get; set;
public String Email get; set;
public String FirstName get; set;
public String LastName get; set;
public String PhoneNumber get; set;
【问题讨论】:
使用 ClaimsPrincipal 你也可以提供AuthenticationDTO
类吗?
添加了 AuthenticationDTO
【参考方案1】:
如果您想获得声明,即preferred_username
,您可以从 ClaimsPrincipal 获得。
var user = User as ClaimsPrincipal;
string username = user.Claims.Where(c => c.Type == "preferred_username")
.Select(x => x.Value).FirstOrDefault();
User
将来自Claims
。对于那个写
using System.Security.Claims;
似乎User
并非在所有版本中都可用。获得索赔的另一种方法是类似的。
var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var email = prinicpal.Claims.Where(c => c.Type == ClaimTypes.Email)
.Select(c => c.Value).SingleOrDefault();
为AuthenticationDTO
分配所有值。
public AuthenticationDTO DecodeToken(String Input)
var key = Encoding.ASCII.GetBytes(HostConfig.SecurityKey);
var handler = new JwtSecurityTokenHandler();
var tokenSecure = handler.ReadToken(Input) as SecurityToken;
var validations = new TokenValidationParameters
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
;
var claims = handler.ValidateToken(Input, validations, out tokenSecure);
var prinicpal = (ClaimsPrincipal)Thread.CurrentPrincipal;
if (principal is ClaimsPrincipal claims)
return new ApplicationDTO
Id = claims.Claims.FirstOrDefault(x => x.Type == "sub")?.Value ?? "",
UserName = claims.Claims.FirstOrDefault(x => x.Type == "preferred_username")?.Value ?? "",
Email = claims.Claims.FirstOrDefault(x => x.Type == "email")?.Value ?? ""
;
return null;
【讨论】:
抱歉,您是从哪里获得 User as ClaimsPrincipal 的?我无法让用户出现User
来自使用System.Security.Claims
由于某种原因我在 System.Security.Claims 中没有用户
如果您查看我在问题中添加的图像,看来我必须循环遍历并将它们拆分为键值项?
您可以使用 linq 获取所有值。您可以使用principal
接收电子邮件吗?以上是关于JWT 如何添加自定义声明和解码声明的主要内容,如果未能解决你的问题,请参考以下文章