I have a middleware class that reads the user's cookies and validates them, then redirects to a login URL if they are invalid or missing. The URL that the user is redirected to contains a 'back' parameter. This middleware works perfectly fine on a static-file SPA and when the application is not a nested application within IIS.
My Question, this does not work when using MVC controllers and Views, before the user is redirected to the login page somehow the path (which points to the nested IIS site) is stripped and the back URL does not contain the URL path. Any ideas?
What happens
Go to -> http://test.com/mysite
Redirects to -> http://login.com?back=http://test.com
What should happen
Go to -> http://test.com/mysite
Redirects to -> http://login.com?back=http://test.com/mysite
public class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private readonly IOptions<MyMiddlewareOptions> _options;
public MyMiddleware(RequestDelegate next, IOptions<MyMiddlewareOptions> options, ILoggerFactory logger)
{
_next = next;
_options = options;
_logger = logger.CreateLogger("My Middleware");
}
public async Task Invoke(HttpContext context)
{
var middlewareCookieValidator = context.RequestServices.GetService<IMiddlewareCookieValidator>();
await new CookieRequestCultureProvider().DetermineProviderCultureResult(context);
if (!_options.Value.Bypass && !Path.HasExtension(context.Request.Path.Value))
{
try
{
if (wslCookieValidator.HasCreatedCookies(context) || await middlewareCookieValidator.ValidateCookiesAsync())
{
context.Response.OnStarting(async () => await middlewareCookieValidator.GenerateAndApplyCookiesToResponse(context));
await _next(context);
}
else
{
var location = new Uri($"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}");
context.Response.Redirect($"{_options.Value.Url}?back={location}");
}
}
catch (Exception exception)
{
throw new Exception($"RequestDelegate '_next' = {_next}. {exception.Message}");
}
}
else
{
await _next(context);
}
}
}
}
@Lex Li
Thank you for your answer, turns out due to IIS running with sub-applications.
I needed the following for it to work.
var location = new Uri($"{context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}");