I am implementing Auth0 with my spring boot application. I want Auth0 to handle the authorization part and also the authentication with OAuth2.0.
I integrated Auth0 in my application with basic configuration and it was working just fine.
However i wanted to integrate custom use case to my application. Therefore i added a CustomOAuthAuthenticationSuccessHandler to get roles from Auth0 Api management and adding them as authorities (roles) to my application using the SecurityContextHolder.
However i get an invalid_request from Auth0 without any log or clue about the error and i am not able to log in successfully.
I have resolved the issue. I changed my CustomOAuthAuthenticationSuccessHandler implementation. Instead of creating a UserPasswordToken (done previously) i am now creating an OAuth2AuthenticationToken.
After successful attribution of authorities i finally redirect to root page (“/”)
Here is my Handler implementation in case it may be helpful:
package com.interco.reconciliation.handler;
import com.interco.reconciliation.service.Auth0ApiManagementService;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.exceptions.UnirestException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
@Component
public class CustomOAuthAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger logger = Logger.getLogger(CustomOAuthAuthenticationSuccessHandler.class.getName());
@Autowired
private Auth0ApiManagementService auth0ApiManagementService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
logger.info("Authentication successful. Retrieving roles.");
// Get the initial list of authorities for authenticated user
List<GrantedAuthority> authorities = new ArrayList<>(authentication.getAuthorities());
// Get userId
OAuth2User principal = (OAuth2User) authentication.getPrincipal();
OAuth2AuthenticationToken oauthToken = (OAuth2AuthenticationToken) authentication;
String userId = principal.getAttribute("sub");
try {
HttpResponse<JsonNode> roles = this.auth0ApiManagementService.getUserRoles(userId);
JsonNode rolesBody = roles.getBody();
for(int i = 0; i < rolesBody.getArray().length(); i++) {
JSONObject role = rolesBody.getArray().getJSONObject(i);
String roleName = role.getString("name");
authorities.add(new SimpleGrantedAuthority("ROLE_" + roleName));
}
} catch(UnirestException | UnsupportedEncodingException e) {
logger.severe("Error fetching roles from Auth0: " + e.getMessage());
throw new RuntimeException(e);
}
logger.info("Roles retrieved and added to authorities: " + authorities.toString());
OAuth2AuthenticationToken newAuth = new OAuth2AuthenticationToken(principal, authorities, oauthToken.getAuthorizedClientRegistrationId());
newAuth.setDetails(new WebAuthenticationDetails(request));
SecurityContextHolder.getContext().setAuthentication(newAuth);
response.sendRedirect("/");
}
}
And in my Web Security Configuration file this is how i implemented it: