diff --git a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs index 528e11c85b..e9eff38ac4 100644 --- a/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNetCore.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -315,20 +315,23 @@ namespace Microsoft.AspNetCore.Authentication.Cookies if (shouldRedirectToReturnUrl && Response.StatusCode == 200) { CookieRedirectContext redirectContext = null; - - var query = Request.Query; - var redirectUri = query[Options.ReturnUrlParameter]; - if (!StringValues.IsNullOrEmpty(redirectUri) && IsHostRelative(redirectUri)) + + // set redirect uri in order: + // 1. properties.RedirectUri + // 2. query parameter ReturnUrlParameter + var redirectUri = properties.RedirectUri; + if (string.IsNullOrEmpty(redirectUri) || !IsHostRelative(redirectUri)) { - redirectContext = new CookieRedirectContext(Context, Options, redirectUri, properties); - } - else if (!string.IsNullOrEmpty(properties.RedirectUri) && IsHostRelative(properties.RedirectUri)) - { - redirectContext = new CookieRedirectContext(Context, Options, properties.RedirectUri, properties); + redirectUri = Request.Query[Options.ReturnUrlParameter]; + if (string.IsNullOrEmpty(redirectUri) || !IsHostRelative(redirectUri)) + { + redirectUri = null; + } } - if (redirectContext != null) + if (redirectUri != null) { + redirectContext = new CookieRedirectContext(Context, Options, redirectUri, properties); await Options.Events.RedirectToReturnUrl(redirectContext); } } diff --git a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs index a5283c80f1..9fc36e6d9c 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -1074,6 +1074,29 @@ namespace Microsoft.AspNetCore.Authentication.Cookies Assert.Equal("/redirect_test", transaction.Response.Headers.Location.ToString()); } + [Fact] + public async Task RedirectUriInQueryIsHoneredAfterSignin() + { + var options = new CookieAuthenticationOptions + { + LoginPath = "/testpath", + ReturnUrlParameter = "return", + CookieName = "TestCookie" + }; + + var server = CreateServer(options, async context => + { + await context.Authentication.SignInAsync( + CookieAuthenticationDefaults.AuthenticationScheme, + new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", CookieAuthenticationDefaults.AuthenticationScheme)))); + }); + var transaction = await SendAsync(server, "http://example.com/testpath?return=%2Fret_path_2"); + + Assert.NotEmpty(transaction.SetCookie); + Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); + Assert.Equal("/ret_path_2", transaction.Response.Headers.Location.ToString()); + } + [Fact] public async Task EnsurePrecedenceOfRedirectUriAfterSignin() { @@ -1095,7 +1118,7 @@ namespace Microsoft.AspNetCore.Authentication.Cookies Assert.NotEmpty(transaction.SetCookie); Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); - Assert.Equal("/ret_path_2", transaction.Response.Headers.Location.ToString()); + Assert.Equal("/redirect_test", transaction.Response.Headers.Location.ToString()); } [Fact]