Describe the bug This bug has been transferred from the Spring Cloud Gateway Forum. Please see the link to the bug here https://github.com/spring-cloud/spring-cloud-gateway/issues/2253.
Basically the WebSecurityConfig DefaultRedirectStrategy is always redirecting to the "/" and thus preventing our defined Spring Cloud Gatewatyrouting configuration from kicking in
I am attempting to utilize the Spring Cloud Gateway to redirect my custom login page to http://localhost:8080/
My application uses ThymeLeaf to render the login page. I have my WebFlux security set us as follows:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
AuthenticationWebFilter passThroughFilter = new AuthenticationWebFilter(passThrough());
return http
.addFilterAfter(passThroughFilter, SecurityWebFiltersOrder.REACTOR_CONTEXT)
.authorizeExchange(authorizeExchangeSpec ->
authorizeExchangeSpec.pathMatchers("/login", "/logout").permitAll()
.anyExchange().authenticated())
.httpBasic().disable()
.formLogin(formLogin -> formLogin.loginPage("/login")
.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/logout")))
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
}
Spring Cloud Routing is set up as follows
spring:
cloud:
gateway:
routes:
- id: authentication
uri: http://localhost:7000/
predicates:
- Path=/login,/logout
- id: proxy_route
uri: http://localhost:8080/
predicates:
- Path=/logout
- Method=POST
To Reproduce This can be replicated as follows:-
Define a WebSecurityConfig as follows:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.anyExchange().authenticated()
.and()
.formLogin()
.and()
.build();
}
This will create the default spring security login page. Once we enter the data in this form (a POST to /login) try to use Spring Cloud Gateway to route the POST action on the /login path. You will see that the logs indicate that the DefaultRedirectStrategy mechanism kicks in a redirects to the default path which is "/".
Even when we change the default redirect route path it still routes to "/". See logs below
2021-06-08 10:15:35.883 DEBUG 69022 --- [ctor-http-nio-4] athPatternParserServerWebExchangeMatcher : Checking match of request : '/login'; against '/login' 2021-06-08 10:15:35.883 DEBUG 69022 --- [ctor-http-nio-4] o.s.s.w.s.u.m.OrServerWebExchangeMatcher : matched 2021-06-08 10:15:35.890 DEBUG 69022 --- [oundedElastic-2] ebSessionServerSecurityContextRepository : Saved SecurityContext 'SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=qkdhajdhsajdas, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]]' in WebSession: 'org.springframework.web.server.session.InMemoryWebSessionStore$InMemoryWebSession@5879fab9' 2021-06-08 10:15:35.891 DEBUG 69022 --- [oundedElastic-2] o.s.s.w.s.DefaultServerRedirectStrategy : Redirecting to '/'
You can see from the logs that when we submit data in the form the POST to the /login page is matched by WebExchangeMatcher. Then the DefaultServerRedirectStrategy kicks in and redirects to the "/". This I believe is what prevents the Spring Cloud Gateway mechanism from kicking in. Even after overriding the default url for the form success it still redirects to "/" (see WebConfig snippet below that should set the url to /logout)
.formLogin(formLogin -> formLogin.loginPage("/login") .authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/logout")))
Expected behavior Once login from the page is successful we should be redirected to the logout page and then the Spring Cloud Gateway routing should kick in.
Sample
A link to a GitHub repository with a minimal, reproducible sample.
Reports that include a sample will take priority over reports that do not. At times, we may require a sample, so it is good to try and include a sample up front.
Comment From: marcusdacoregio
Thanks for the report @topdonn.
I tried to simulate the scenario in a sample but I couldn't. Can you provide a minimal, reproducible sample that simulates your scenario?
I'm not sure if I understand clearly, but upon successful login, you want to redirect the user to the /logout page?
Comment From: topdonn
Thanks for the report @topdonn.
I tried to simulate the scenario in a sample but I couldn't. Can you provide a minimal, reproducible sample that simulates your scenario?
I'm not sure if I understand clearly, but upon successful login, you want to redirect the user to the
/logoutpage?
Yes so upon a successful login the user should be redirected to the logout page. Once they are at the logout page the spring cloud gateway routing should kick in. As it is right now they are always redirected to "/" even when we explicity configure it to the redirect to the /logout page as shown below:
.formLogin(formLogin -> formLogin.loginPage("/login") .authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/logout")))
I will try and upload my sample on personal github and will update
Comment From: marcusdacoregio
Could you get your sample uploaded @topdonn?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.