.Net Core 3.1 API 中的刷新令牌 Azure 广告身份验证
Posted
技术标签:
【中文标题】.Net Core 3.1 API 中的刷新令牌 Azure 广告身份验证【英文标题】:Refresh Token Azure Ad authentication in .Net Core 3.1 API 【发布时间】:2021-10-19 03:59:36 【问题描述】:问题:- 我有一个不同的微服务,我使用了 Azure 广告身份验证。 前端使用https://login.microsoftonline.com/common/oauth2/v2.0/token 创建令牌并发送到.net core api。 问题是令牌超时时间为 1 小时,并且某些进程在后台运行,因此某些时间进程停止。 如果令牌过期,我需要在 api 端找出刷新令牌。
ConfigureServices 方法中的启动代码
services.AddAuthorization(options =>
options.DefaultPolicy = new AuthorizationPolicyBuilder(
"Bearer")
.RequireAuthenticatedUser()
.Build();
);
配置方法
app.UseCustomSwagger(Configuration, provider);
app.UseHealthChecks("/health");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSerilogRequestLogging();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseApiVersioning();
app.UseCors("CorsPolicy");
我在控制器上添加了 [Authorize] 属性。 我们还有一个用于令牌添加到声明的中间件
public async Task InvokeAsync(HttpContext httpContext)
if (httpContext.User != null && httpContext.User.Identity.IsAuthenticated)
//string sPreferredUserName = httpContext.User.Claims.FirstOrDefault(x => x.Type.Equals("preferred_username", StringComparison.OrdinalIgnoreCase))?.Value;
//if (string.IsNullOrEmpty(sPreferredUserName))
// ((ClaimsIdentity)httpContext.User.Identity).AddClaim(new Claim("preferred_username", httpContext.User.Identity.Name, ClaimValueTypes.String));
((ClaimsIdentity)httpContext.User.Identity).AddClaim(new Claim("Token", httpContext.Request.Headers["Authorization"], ClaimValueTypes.String));
await _next(httpContext);
else
string result1 = "UnAuthorized";
byte[] bytes = Encoding.ASCII.GetBytes(result1);
await httpContext.Response.Body.WriteAsync(bytes, 0, bytes.Length);
我想要从前端检查令牌验证接收令牌和刷新令牌时,如果过期使用刷新令牌生成新令牌。 请帮忙 提前致谢
【问题讨论】:
some process running in background so some time process stop
这是否意味着您有一个需要持续使用访问令牌的长时间进程,并且每当令牌过期时,该进程就会停止?或者您的进程总是收到存储在某个地方的相同访问令牌,而您的客户端不知道令牌何时过期,因此您需要您的 api 检查令牌并让客户端知道令牌何时过期?或者是其他东西?您能否添加有关您的方案或处理进度流程的更多详细信息。
【参考方案1】:
解决方案 1:使用 System.IdentityModel.Tokens.Jwt
类。调用此方法检查token是否有效
public bool _isEmptyOrInvalid (string token)
if (string.IsNullOrEmpty(token))
return true;
var jwtToken = new JwtSecurityToken(token);
return (jwtToken == null) || (jwtToken.ValidFrom > DateTime.UtcNow) || (jwtToken.ValidTo < DateTime.UtcNow);
解决方案2:尝试从Base64格式解码令牌,您可以看到到期日期,然后您可以将其与现在的日期进行比较。
如果您想检查此方法是否有效,您可以使用this website 来解码令牌。
public static bool isExpired(String token)
if (token == null || ("").Equals(token))
return true;
/***
* Make string valid for FromBase64String
* FromBase64String cannot accept '.' characters and only accepts stringth whose length is a multitude of 4
* If the string doesn't have the correct length trailing padding '=' characters should be added.
*/
int indexOfFirstPoint = token.IndexOf('.') + 1;
String toDecode = token.Substring(indexOfFirstPoint, token.LastIndexOf('.') - indexOfFirstPoint);
while (toDecode.Length % 4 != 0)
toDecode += '=';
//Decode the string
string decodedString = Encoding.ASCII.GetString(Convert.FromBase64String(toDecode));
//Get the "exp" part of the string
String beginning = "\"exp\":\"";
int startPosition = decodedString.LastIndexOf(beginning) + beginning.Length;
decodedString = decodedString.Substring(startPosition);
int endPosition = decodedString.IndexOf("\"");
decodedString = decodedString.Substring(0, endPosition);
long timestamp = Convert.ToInt64(decodedString);
DateTime date = new DateTime(1970, 1, 1).AddMilliseconds(timestamp);
DateTime compareTo = DateTime.Now.AddMinutes(1);
int result = DateTime.Compare(date, compareTo);
return result < 0;
更多详情请参考thread
【讨论】:
以上是关于.Net Core 3.1 API 中的刷新令牌 Azure 广告身份验证的主要内容,如果未能解决你的问题,请参考以下文章
NET Core 3.1 MVC 授权/身份验证,带有在单独的 Net Core 3.1 Web Api 中从外部获取的令牌 (JWT)
使用 AspNetUserTokens 表在 ASP.NET Core Web Api 中存储刷新令牌
如何撤销存储在 Identity Server 数据库中的 asp net core 中的刷新令牌