182 lines
5.1 KiB
C#
182 lines
5.1 KiB
C#
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<XIdentityTokenRefresherMiddleware> ();
|
|
}
|
|
#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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Provide all DI Requirements for XIdentityTokenRefresher Middleware
|
|
/// </summary>
|
|
public static class XIdentityTokenRefresherDIHelper {
|
|
/// <summary>
|
|
/// Use XTokenValidator Middleware
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXIdentityTokenRefresher (this IApplicationBuilder app) {
|
|
app.UseMiddleware<XIdentityTokenRefresherMiddleware> ();
|
|
}
|
|
}
|
|
} |