在 .net core 3.1 中,如何从不记名令牌返回数据?
Posted
技术标签:
【中文标题】在 .net core 3.1 中,如何从不记名令牌返回数据?【英文标题】:In .net core 3.1 how can I return data from a bearer token? 【发布时间】:2020-08-12 18:28:30 【问题描述】:我正在尝试从不记名令牌返回一些数据,以用作我在端点中调用的函数中的参数。目前,当我测试代码时,我需要作为参数的两个字符串 userName 和 applicationName 返回 null,所以我得到一个 500。这很好,但我需要 userName 和 applicationName 来存储数据以用作函数 GetAbsoluteTimeout() 中的参数; 我怎样才能做到这一点?
端点:
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(StatusCodeResult), StatusCodes.Status401Unauthorized)]
[ProducesResponseType(typeof(StatusCodeResult), StatusCodes.Status500InternalServerError)]
[Consumes(MediaTypeNames.Application.Json)]
[Produces(MediaTypeNames.Application.Json)]
[IDMAuthorize]
public IActionResult GetAbsoluteTimeoutForClaimsPrincipal()
DateTime startTime = DateTime.Now;
try
string logText = LogFormatter.Format(
WebUtilities.GetUser((ClaimsIdentity)HttpContext.User.Identity),
startTime, DateTime.Now, Privilege.NotApplicable,
"Get Absolute Timeout For Claims Principal", "Attempting to get the absolute timeout for the current user.");
logger.LogInfo(logText);
string userName = Convert.ToString(JsonConvert.DeserializeObject(HttpContext.Request.Headers["email"]));
string applicationName = Convert.ToString(JsonConvert.DeserializeObject(HttpContext.Request.Headers["client_id"]));
int timeout = 0;
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(applicationName))
timeout = GetAbsoluteTimeout(userName, applicationName);
logText = LogFormatter.Format(
WebUtilities.GetUser((ClaimsIdentity)HttpContext.User.Identity),
startTime, DateTime.Now, Privilege.NotApplicable,
"Get Absolute Timeout For Claims Principal", "Successful retrieval of the absolute timeout for the current user.");
logger.LogInfo(logText);
return Ok(timeout);
catch (Exception ex)
string logText = LogFormatter.Format(
WebUtilities.GetUser((ClaimsIdentity)HttpContext.User.Identity),
startTime, DateTime.Now, Privilege.ViewIMUData,
"Get Absolute Timeout For Claims Principal", ex.ToString());
logger.LogError(logText, ex);
return StatusCode(Constants.InternalServerErrorCode, "Failed to get absolute timeout for claims principal. Please check logs for more details. ");
这是来自 JWT 不记名令牌的数据:
"client_id": "JITWebAdmin",
"scope": [
"openid",
"profile",
"email",
"jitwebapi"
],
"sub": "dd458da9-5de6-4f79-8756-e4756fef63a3",
"auth_time": 1588098606,
"idp": "idm-JadenCCE21-8a9fa4f4-62c2-4c8f-afe6-4ffb740e2327",
"updated_at": 1566433758,
"tenant": "default",
"preferred_username": "admin",
"email": "admin@email.com",
"email_verified": "true",
"login_attempt": "\"LoginDate\":\"2020-04-28 18:28:46Z\",\"WasSuccessful\":true,\"IpAddress\":\"10.160.176.79\"",
"name": "admin",
"amr": [
"external"
]
【问题讨论】:
【参考方案1】:我使用此代码向jwt
添加声明并颁发令牌:
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(EncryptionKey);
var tokenDescriptor = new SecurityTokenDescriptor
Subject = new ClaimsIdentity(new Claim[]
new Claim(ClaimTypes.Name, user.Username),
new Claim(ClaimTypes.NameIdentifier , user.Id.ToString()),
),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
;
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
例如,在new Claim(ClaimTypes.NameIdentifier , user.Id.ToString())
这行代码中,您可以在令牌中放入任何您想要的东西。
当您想在控制器中读取该数据时,只需使用以下代码:
var userId = HttpContext.User.Claims.SingleOrDefault(x => x.Type == ClaimTypes.NameIdentifier).Value;
【讨论】:
以上是关于在 .net core 3.1 中,如何从不记名令牌返回数据?的主要内容,如果未能解决你的问题,请参考以下文章
不记名令牌出现 401 错误 - asp.net core 3.1
JWT 不记名令牌不适用于 ASP.Net Core 3.1 + Identity Server 4
如何在 Asp .Net Core SignalR Hub 中获取不记名令牌?
如何诊断尝试在 c# .NET Core 中获取 OAuth2 不记名令牌的 401 错误?