using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using xCommons.Constants; using xCommons.Extensions; using xIdentityModels.Extensions; using xIdentityService.Interfaces; namespace xIdentityService.Middlewares { public partial class XIdentityTokenRefresherMiddleware { // #region Properties ... private readonly ILogger logger; private readonly RequestDelegate next; private readonly IXTokenProvider tokenProvider; private readonly IXIdentityProvider identityProvider; #endregion // #region Constructor ... public XIdentityTokenRefresherMiddleware ( RequestDelegate next, ILoggerFactory loggerFactory, IXTokenProvider tokenProvider, IXIdentityProvider identityProvider ) { // this.next = next; this.tokenProvider = tokenProvider; this.identityProvider = identityProvider; this.logger = loggerFactory .CreateLogger (); } #endregion // #region Actions ... public async Task Invoke (HttpContext context) { // // Handle Request ... await HandleRequest (context); // // Do Main Task ... try { await next.Invoke (context); } catch (Exception ex) { logger.LogError ($"Error: {ex.Message}"); } // // Handle Response ... await HandleResponse (context); } #endregion // #region Private ... private async Task HandleRequest (HttpContext context) { // // Log ... logger.LogInformation ($"Start Process Request ..."); // // Check Access Token ... var hasAccessToken = HasAccessToken (context); if (!hasAccessToken) { return; } // // Check Access Token ... var accessToken = GetAccessToken (context); var isExists = await tokenProvider .IsTokenExists (accessToken); if (!isExists) { return; } // // Try Check is Refreshable ... var tokens = await tokenProvider .RetrieveToken (accessToken); if (tokens.IsNull ()) { return; } // // Check is Expired or Refreshable ... var isRefreshable = tokens.IsRefreshable (); if (!isRefreshable) { return; } // // Refresh Token ... var refreshedTokens = await identityProvider .RefreshTokens (tokens); if (refreshedTokens.IsNull ()) { return; } // // Set Refreshed AccessToken to Request ... context .Request .Headers[XAuthorization.Header] = $"{XAuthorization.TokenIdentifier}{refreshedTokens.AccessToken}"; } private async Task HandleResponse (HttpContext context) { // // Log ... logger.LogInformation ($"Start Process Response ..."); // await Task.Run (() => { }); } private bool HasAccessToken (HttpContext context) { // // Check Headers ... if (context.IsNull () || context.Request.IsNull () || context.Request.Headers.IsNull ()) { return false; } // var result = context .Request .Headers .ContainsKey ( XAuthorization.Header ); // return result; } private string GetAccessToken (HttpContext context) { // var hasAccessToken = HasAccessToken (context); if (!hasAccessToken) { return string.Empty; } // // Get Result ... var result = context .Request .Headers[ XAuthorization.Header ]; result = result .ToString () .Replace ( XAuthorization.TokenIdentifier, "" ); // return result; } #endregion } /// /// Provide all DI Requirements for XIdentityTokenRefresher Middleware /// public static class XIdentityTokenRefresherDIHelper { /// /// Use XTokenValidator Middleware /// /// public static void UseXIdentityTokenRefresher (this IApplicationBuilder app) { app.UseMiddleware (); } } }