143 lines
5.0 KiB
C#
143 lines
5.0 KiB
C#
using System.Text;
|
|
using Microsoft.Extensions.Options;
|
|
using Microsoft.Extensions.Primitives;
|
|
using Microsoft.Net.Http.Headers;
|
|
using StopShopping.Services.Extensions;
|
|
|
|
namespace StopShopping.Api.Middlewares;
|
|
|
|
public class DevelopmentCookieMiddleware
|
|
{
|
|
public DevelopmentCookieMiddleware(
|
|
RequestDelegate requestDelegate,
|
|
IOptions<AppOptions> options)
|
|
{
|
|
_next = requestDelegate;
|
|
_appOptions = options.Value;
|
|
}
|
|
|
|
private readonly RequestDelegate _next;
|
|
private readonly AppOptions _appOptions;
|
|
|
|
public async Task InvokeAsync(HttpContext httpContext)
|
|
{
|
|
int? port = null;
|
|
var origin = httpContext.Request.Headers[HeaderNames.Origin];
|
|
if (origin.Count > 0 && null != origin[0])
|
|
{
|
|
Uri uri = new(origin[0]!);
|
|
port = uri.Port;
|
|
}
|
|
else
|
|
{
|
|
var referer = httpContext.Request.Headers[HeaderNames.Referer];
|
|
if (referer.Count > 0 && null != referer[0])
|
|
{
|
|
Uri uri = new(referer[0]!);
|
|
port = uri.Port;
|
|
}
|
|
}
|
|
|
|
if (port.HasValue)
|
|
{
|
|
var modified = ModifyCookie(httpContext.Request.Headers[HeaderNames.Cookie], port.Value);
|
|
httpContext.Request.Headers[HeaderNames.Cookie] = modified;
|
|
}
|
|
|
|
httpContext.Response.OnStarting(() =>
|
|
{
|
|
if (port.HasValue)
|
|
{
|
|
var cookieHeader = httpContext.Response.Headers[HeaderNames.SetCookie];
|
|
ModifyResponseCookie(cookieHeader, httpContext, port.Value);
|
|
}
|
|
return Task.CompletedTask;
|
|
});
|
|
|
|
await _next(httpContext);
|
|
}
|
|
|
|
private void ModifyResponseCookie(StringValues cookieHeader, HttpContext httpContext, int port)
|
|
{
|
|
foreach (var cookieItem in cookieHeader)
|
|
{
|
|
if (cookieItem != null)
|
|
{
|
|
var cookies = cookieItem.Split(';');
|
|
foreach (var item in cookies)
|
|
{
|
|
if (null != item)
|
|
{
|
|
var pairs = item.Split('=');
|
|
if (2 == pairs.Length)
|
|
{
|
|
if (pairs[0].Trim() == _appOptions.CSRFCookieName)
|
|
{
|
|
var val = pairs[1];
|
|
httpContext.Response.Cookies.Delete(pairs[0]);
|
|
httpContext.Response.Cookies.Append($"{_appOptions.CSRFCookieName}_{port}", val);
|
|
}
|
|
else if (pairs[0].Trim() == HttpExtensions.REFRESH_TOKEN_COOKIE_KEY)
|
|
{
|
|
var val = pairs[1];
|
|
httpContext.Response.Cookies.Delete(pairs[0]);
|
|
httpContext.Response.Cookies.Append($"{HttpExtensions.REFRESH_TOKEN_COOKIE_KEY}_{port}", val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private StringValues ModifyCookie(StringValues cookie, int port)
|
|
{
|
|
List<string> result = [];
|
|
var csrfCookieName = $"{_appOptions.CSRFCookieName}_{port}";
|
|
var refreshTokenCookieName = $"{HttpExtensions.REFRESH_TOKEN_COOKIE_KEY}_{port}";
|
|
foreach (var cookieItem in cookie)
|
|
{
|
|
if (null != cookieItem)
|
|
{
|
|
StringBuilder itemBuilder = new();
|
|
var cookies = cookieItem.Split(';');
|
|
foreach (var item in cookies)
|
|
{
|
|
if (null != item)
|
|
{
|
|
var pairs = item.Split('=');
|
|
if (pairs.Length == 2)
|
|
{
|
|
if (0 != itemBuilder.Length)
|
|
itemBuilder.Append(';');
|
|
if (pairs[0].Trim() == csrfCookieName)
|
|
{
|
|
itemBuilder.Append(_appOptions.CSRFCookieName);
|
|
itemBuilder.Append('=');
|
|
itemBuilder.Append(pairs[1].Trim());
|
|
}
|
|
else if (pairs[0].Trim() == refreshTokenCookieName)
|
|
{
|
|
itemBuilder.Append(HttpExtensions.REFRESH_TOKEN_COOKIE_KEY);
|
|
itemBuilder.Append('=');
|
|
itemBuilder.Append(pairs[1].Trim());
|
|
}
|
|
else
|
|
{
|
|
itemBuilder.Append(item);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
itemBuilder.Append(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
result.Add(itemBuilder.ToString());
|
|
}
|
|
}
|
|
return new StringValues(result.ToArray());
|
|
}
|
|
}
|