tl;dr; How do I get Chrome to follow the 302 'Location' redirect to a different domain after an HTTP POST?
I'm using OpenID Connect, using an external provider to provide authentication services to my ASP.NET MVC (C#, .NET 6) application.
I have a controller action to close an account. In this instance,
[HttpPost("close-account")]
public async Task<IActionResult> CloseAccount()
{
// This does not work as expected in a POST and the browser does not redirect
var properties = new AuthenticationProperties { RedirectUri = "..." }
return SignOut(properties, "Cookies", "OpenIdConnect");
}
There is a standard html <form>
which is completing the post action to the controller via a <button>
. No Javascript involved.
Looking at the Chrome developer tools, the browser receives the 302 Found with the Location response header correctly set to the URL the browser needs to redirect to in order to complete the sign out with the OpenID Connect provider.
However, the browser does not follow the redirect. I am presuming because it is cross-origin, and starts with "https://oidc.myauthenticationprovider.com/logout?...." which is a different domain.
I have verified this - because if I change the redirect to be another URL in the same site, then the browser follows up with a GET
to the URL provided in the Location
header. It's just that if the origin is a different domain, it does nothing.
I only see this behaviour with POST. I have a similar GET endpoint to sign out users (without closing their account- just a regular sign-out) - which works perfectly.
[HttpGet("sign-out")]
public async Task<IActionResult> CloseAccount()
{
// This works as expected in a GET and the user is redirected.
var properties = new AuthenticationProperties { RedirectUri = "..." }
return SignOut(properties, "Cookies", "OpenIdConnect");
}
I'm not sure this is strictly a CORS issue because it is the response to an HTTP POST rather than an XHR request, however, I have tried the below in case it is related to CORS:
- I have tried the
services.AddCors
method in the application startup, adding the origin - I have tried manually adding the
Access-Control-Allow-Origin
header to both the original GET and also the POST response of the close account page
These do not make a difference.
To the user, the behaviour is as if the form has done nothing. They press the button, and it seems like nothing at all happens. The code within the controller executes (in my example, the account does get closed), but the redirection is then ignored.
CodePudding user response:
This was due to us setting the form-action: self
directive in CSP. As described on MDN Web Docs,
Warning: Whether
form-action
should block redirects after a form submission is debated and browser implementations of this aspect are inconsistent (e.g. Firefox 57 doesn't block the redirects whereas Chrome 63 does).
For us this was what was causing the blocked redirect to a different domain after form submission.