I am using Spring Cloud Gateway (2023.0.0) and Spring Boot (3.2.3) with oauth2Login and formLogin.
Currently when the application is opened i am redirected to the login page. On the login page i can choose between the form or select the OAuth provider (as expected).
I want to skip the login page by default and directly redirect to the OAuth provider. Only when the user uses a defined url parameter (e.g. ?local=true) in the inital request i want to show the login page with the form.
@Bean
public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {
http
...
.oauth2Login(withDefaults())
.formLogin(withDefaults())
...;
return http.build();
}
@Bean
MapReactiveUserDetailsService userDetailsService() {
UserDetails userDetails = User
.withUsername("admin")
.password("{noop}admin")
.roles("admin")
.build();
return new MapReactiveUserDetailsService(List.of(userDetails));
}
I already tried to implement a custom ServerAuthenticationEntryPoint:
@Bean
public SecurityWebFilterChain springSecurityFilterChain(final ServerHttpSecurity http) {
http
...
.oauth2Login(withDefaults())
.formLogin(withDefaults())
.exceptionHandling(c -> c.authenticationEntryPoint(customAuthenticationEntryPoint()))
...;
return http.build();
}
public class ConditionalAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
private final RedirectServerAuthenticationEntryPoint oauth2EntryPoint;
private final RedirectServerAuthenticationEntryPoint loginFormEntryPoint;
public ConditionalAuthenticationEntryPoint() {
this.oauth2EntryPoint = new RedirectServerAuthenticationEntryPoint("/oauth2/authorization/oauth-client");
this.loginFormEntryPoint = new RedirectServerAuthenticationEntryPoint("/login");
}
@Override
public Mono<Void> commence(final ServerWebExchange exchange, final AuthenticationException ex) {
return exchange
.getSession()
.map(session -> {
if (session.getAttribute("local") != null) {
return true;
}
var local = exchange.getRequest().getQueryParams().containsKey("local");
if (local) {
session.getAttributes().putIfAbsent("local", true);
}
return local;
})
.flatMap(local -> {
if (local) {
return loginFormEntryPoint.commence(exchange, ex);
} else {
return oauth2EntryPoint.commence(exchange, ex);
}
});
}
}
But this leads to endless redirects. Is this the correct approach?