diff --git a/application/src/main/java/run/halo/app/security/HaloServerRequestCache.java b/application/src/main/java/run/halo/app/security/HaloServerRequestCache.java index 0909d4020..02f146050 100644 --- a/application/src/main/java/run/halo/app/security/HaloServerRequestCache.java +++ b/application/src/main/java/run/halo/app/security/HaloServerRequestCache.java @@ -44,6 +44,7 @@ public class HaloServerRequestCache extends WebSessionServerRequestCache { public Mono saveRequest(ServerWebExchange exchange) { var redirectUriQuery = exchange.getRequest().getQueryParams().getFirst(REDIRECT_URI_QUERY); if (StringUtils.isNotBlank(redirectUriQuery)) { + // the query value is decoded, so we don't need to decode it again var redirectUri = URI.create(redirectUriQuery); return saveRedirectUri(exchange, redirectUri); } @@ -64,8 +65,11 @@ public class HaloServerRequestCache extends WebSessionServerRequestCache { var requestPath = exchange.getRequest().getPath(); var redirectPath = RequestPath.parse(redirectUri, requestPath.contextPath().value()); var query = redirectUri.getRawQuery(); - var finalRedirect = - redirectPath.pathWithinApplication() + (query == null ? "" : "?" + query); + var fragment = redirectUri.getRawFragment(); + var finalRedirect = redirectPath.pathWithinApplication() + + (query == null ? "" : "?" + query) + + (fragment == null ? "" : "#" + fragment); + return exchange.getSession() .map(WebSession::getAttributes) .doOnNext(attributes -> attributes.put(this.sessionAttrName, finalRedirect)) diff --git a/application/src/test/java/run/halo/app/security/HaloServerRequestCacheTest.java b/application/src/test/java/run/halo/app/security/HaloServerRequestCacheTest.java index 02e130c7e..aa5c09bf9 100644 --- a/application/src/test/java/run/halo/app/security/HaloServerRequestCacheTest.java +++ b/application/src/test/java/run/halo/app/security/HaloServerRequestCacheTest.java @@ -33,23 +33,28 @@ class HaloServerRequestCacheTest { @Test void shouldSaveIfPageCacheable() { var mockExchange = MockServerWebExchange.from( - MockServerHttpRequest.get("/archives").accept(MediaType.TEXT_HTML) + MockServerHttpRequest.get("/archives") + .queryParam("q", "v") + .accept(MediaType.TEXT_HTML) ); requestCache.saveRequest(mockExchange) .then(requestCache.getRedirectUri(mockExchange)) .as(StepVerifier::create) - .expectNext(URI.create("/archives")) + .expectNext(URI.create("/archives?q=v")) .verifyComplete(); } @Test - void shouldSaveIfQueryPresent() { - var mockExchange = - MockServerWebExchange.from(MockServerHttpRequest.get("/login?redirect_uri=/halo?q=v")); + void shouldSaveIfRedirectUriPresent() { + var mockExchange = MockServerWebExchange.from( + MockServerHttpRequest.get("/login") + .queryParam("redirect_uri", "/halo?q=v#fragment") + ); requestCache.saveRequest(mockExchange) .then(requestCache.getRedirectUri(mockExchange)) .as(StepVerifier::create) - .expectNext(URI.create("/halo?q=v")); + .expectNext(URI.create("/halo?q=v#fragment")) + .verifyComplete(); } @Test