/// <summary> /// 保存token /// </summary> /// <param name="context"></param> /// <param name="next"></param> /// <returns></returns> private async Task SaveToken(HttpContext context, RequestDelegate next) { string responseContent; var originalBodyStream = context.Response.Body; using (var fakeResponseBody = new MemoryStream()) { context.Response.Body = fakeResponseBody; await next(context); fakeResponseBody.Seek(0, SeekOrigin.Begin); using (var reader = new StreamReader(fakeResponseBody)) { responseContent = await reader.ReadToEndAsync(); fakeResponseBody.Seek(0, SeekOrigin.Begin); await fakeResponseBody.CopyToAsync(originalBodyStream); } } if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { var tokenTxt = JObject.Parse(responseContent).GetValue("token")?.ToString(); if (tokenTxt.IsNullOrWhiteSpace()) { return; } //refreshTokenTxt = JObject.Parse(responseContent).GetValue("refreshToken").ToString(); var claimsInfo = GetClaimsInfo(tokenTxt); if (claimsInfo.Account.IsNotNullOrWhiteSpace()) { var tokenKey = $"{tokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; _cache.Set(tokenKey, claimsInfo.Token, claimsInfo.Expire - DateTime.Now); //var refreshTokenKey = $"{refreshTokenPrefx}:{claimsInfo.Account}:{claimsInfo.Id}"; //_cache.Set(refreshTokenKey, refreshTokenTxt, TimeSpan.FromSeconds(_jwtConfig.RefreshTokenExpire)); } } }
public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var endpoint = context.GetEndpoint(); if (endpoint == null) { await _next(context); return; } var requiredValues = ((RouteEndpoint)endpoint).RoutePattern.RequiredValues; if (!requiredValues.Any()) { await _next(context); return; } var controller = requiredValues["controller"]?.ToString().ToLower(); var action = requiredValues["action"]?.ToString().ToLower(); if (controller.IsNullOrWhiteSpace()) { await _next(context); return; } //判断Api是否需要认证 bool isNeedAuthentication = endpoint.Metadata.GetMetadata <IAllowAnonymous>() == null; //Api不需要认证 if (!isNeedAuthentication) { //如果是调用登录API、刷新token的Api,并且调用成功,需要保存accesstoken到cache if (controller == "account" && (action == "login" || action == "refreshaccesstoken")) { await SaveToken(context, _next); return; } //其他Api await _next(context); return; } //API需要认证 if (isNeedAuthentication) { //是修改密码,需要从cahce移除Token if (controller == "account" && action == "password") { await _next(context); if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { await RemoveToken(context); } return; } //是注销,需要判断是否主动注销 if (controller == "account" && action == "logout") { await _next(context); if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { //主动注销,从cahce移除token if (await CheckToken(context)) { await RemoveToken(context); } return; } } } //API需要认证,并且验证成功,需要检查accesstoken是否在缓存中。 if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { //需要先检查token是否是最新的,再走其它中间件 var result = await CheckToken(context); if (result) { try { await _next(context); } catch (Exception ex) { throw new Exception(ex.Message, ex); } return; } else { var status = (int)HttpStatusCode.Unauthorized; var hostAndPort = context.Request.Host.HasValue ? context.Request.Host.Value : string.Empty; var requestUrl = string.Concat(hostAndPort, context.Request.Path); var type = string.Concat("https://httpstatuses.com/", status); var title = "Token已经过期"; var detial = "Token已经过期,请重新登录"; var problemDetails = new ProblemDetails { Title = title , Detail = detial , Type = type , Status = status , Instance = requestUrl }; context.Response.StatusCode = status; context.Response.ContentType = "application/problem+json"; var stream = context.Response.Body; await JsonSerializer.SerializeAsync(stream, problemDetails); return; } } await _next(context); }
public async Task Invoke(HttpContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var endpoint = context.GetEndpoint(); if (endpoint == null) { await _next(context); return; } var requiredValues = ((RouteEndpoint)endpoint).RoutePattern.RequiredValues; if (requiredValues.Count() == 0) { await _next(context); return; } var controller = requiredValues["controller"]?.ToString().ToLower(); var action = requiredValues["action"]?.ToString().ToLower(); if (controller.IsNullOrWhiteSpace()) { await _next(context); return; } //判断Api是否需要认证 bool isNeedAuthentication = endpoint.Metadata.GetMetadata <IAllowAnonymous>() == null ? true : false; //Api不需要认证 if (isNeedAuthentication == false) { //如果是调用登录API、刷新token的Api,并且调用成功,需要保存accesstoken到cache if (controller == "account" && (action == "login" || action == "refreshaccesstoken")) { await SaveToken(context, _next); return; } //其他Api await _next(context); return; } //API需要认证 if (isNeedAuthentication == true) { //是修改密码,需要从cahce移除Token if (controller == "account" && action == "password") { await _next(context); if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { await RemoveToken(context); } return; } //是注销,需要判断是否主动注销 if (controller == "account" && action == "logout") { await _next(context); if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { //主动注销,从cahce移除token if (await CheckToken(context) == true) { await RemoveToken(context); } return; } } } //API需要认证,并且验证成功,需要检查accesstoken是否在缓存中。 if (StatusCodeChecker.Is2xx(context.Response.StatusCode)) { //需要先检查token是否是最新的,再走其它中间件 var result = await CheckToken(context); if (result) { await _next(context); return; } else { context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; var message = new ErrorModel(HttpStatusCode.Unauthorized, "账号已经在其他地方登录"); context.Response.ContentType = "application/json;charset=utf-8"; await context.Response.WriteAsync(message.ToString()); return; } } await _next(context); return; }