Hello everyone!
I am working on a dummy project with a Typescript frontend and a Spring Boot backend to try out Auth0 for the first time. My frontend is quite straightforward—it essentially contains a button that, when clicked, sends a request to my server to initiate the OAuth2 login flow. My backend has a Spring Security configuration and a single controller to handle this.
Upon clicking the button, the backend successfully redirects me to the Auth0 login page. However, after logging in, instead of being redirected to my specified defaultSuccessURL (/secured), I am being redirected to /login?error. I have checked the Spring Security logs and it seems like I’m hitting the /login/oauth2/code/auth0 endpoint with a valid authorization code, but something goes amiss right after that, leading to the /login?error redirect which contains the error page with the light red box with the text “Invalid Request” and a link, upon clicking the link again i get directed to the proper page which is at http://localhost:8080/secured.
I have also verified that my Auth0 application settings are correct and the specified redirect URIs match.
Thank in advance for anyone who can provide the slightest of help.
below is some relevant code from my server-side and logs.
application.yml
spring:
security:
oauth2:
client:
registration:
auth0:
client-id: ***
client-secret: ***
scope:
- openid
- profile
- email
redirect-uri: http://localhost:8080/login/oauth2/code/auth0
provider:
auth0:
issuer-uri: https://***.auth0.com/
authorization-uri: https://***.auth0.com/authorize
spring security config class:
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
@Slf4j
public class SecurityConfig
{
private final CorsConfigurationSource corsConfigurationSource;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws
Exception {
http.csrf(AbstractHttpConfigurer::disable)
.cors(customizer -> customizer.configurationSource(corsConfigurationSource))
.authorizeHttpRequests(authorizer -> authorizer.requestMatchers("/secured")
.authenticated()
.requestMatchers("/oauth2/authorize-client", "/error/**")
.permitAll()
.anyRequest()
.authenticated())
.oauth2Login(oauth2Login -> oauth2Login.authorizationEndpoint(authorizationEndpoint -> authorizationEndpoint.baseUri(
"/oauth2/authorize-client"))
.tokenEndpoint(tokenEndpoint -> tokenEndpoint.accessTokenResponseClient(
accessTokenResponseClient()))
.defaultSuccessUrl("/secured", true)
.failureUrl("/login?error"));
return http.build();
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() {
return new DefaultAuthorizationCodeTokenResponseClient();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplateBuilder().build();
}
}
and my only controller :
@RestController
@RequiredArgsConstructor
public class HomeController
{
@Value("${spring.security.oauth2.client.registration.auth0.client-id}")
private String clientId;
@Value("${spring.security.oauth2.client.registration.auth0.redirect-uri}")
private String redirectUri;
@Value("${spring.security.oauth2.client.provider.auth0.authorization-uri}")
private String authorizationUri;
@GetMapping("/oauth2/authorize-client")
public ResponseEntity<Map<String, String>> login() {
String url = UriComponentsBuilder.fromUriString(authorizationUri)
.queryParam("response_type", "code")
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri)
.queryParam("scope", "openid profile email")
.build()
.toUriString();
Map<String, String> response = Collections.singletonMap("redirectUrl", url);
return ResponseEntity.ok(response);
}
@GetMapping("/secured")
public Map<String, Object> getSecuredData(@AuthenticationPrincipal OidcUser principal) {
Map<String, Object> securedData = new HashMap<>();
if (principal != null) {
securedData.put("user", principal.getName());
securedData.put("claims", principal.getClaims());
} else {
securedData.put("error", "User not authenticated");
}
return securedData;
}
}
server-side logs that occur when i hit the login button
-Securing GET /oauth2/authorize-client
-Mapped to com.projectpulse.projectpulsebe.features.user.controllers.HomeController#login()
-Secured GET /oauth2/authorize-client
-GET "/oauth2/authorize-client", parameters={}
-Mapped to com.projectpulse.projectpulsebe.features.user.controllers.HomeController#login()
-Writing [{redirectUrl=https://***.auth0.com/authorize?response_type=code&client_id=...]
-Completed 200 OK
-Set SecurityContextHolder to anonymous SecurityContext
-Securing GET /login/oauth2/code/auth0?code=***
-Redirecting to /login?error
Application Details in auth0 website:
- Allowed Callback URLs:
http://localhost:8080/login/oauth2/code/auth0
- Allowed Logout URLs:
http://localhost:8080/logout
,http://localhost:3000
- Allowed Web Origins:
http://localhost:3000
- Allowed Origins (CORS):
http://localhost:3000