We have React frontend app that calls SpringBoot app ( using Auth0 API) with the access token ( audience is backend API registered in the dashboard as API). We have a custom Action to add user.email to the access token instead of fetching this information from user_info on the backend. I’m using this “enhanced” access token to know which user is called the backend.
The action looks like this ( Auth0 dashboard)
exports.onExecutePostLogin = async (event, api) => {
// This rule adds the authenticated user's email address to the access token.
if (event.authorization) {
const namespace = 'https://mynamespace.com';
api.accessToken.setCustomClaim(`${namespace}/email`, event.user.email);
api.accessToken.setCustomClaim(`${namespace}/email_verified`, event.user.email_verified);
}
};
On the backend side, I’m using this security configuration
@Override
public void configure(HttpSecurity http) throws Exception {
/*
This is where we configure the security required for our endpoints and setup our app to serve as
an OAuth2 Resource Server, using JWT validation.
*/
http.authorizeRequests()
.mvcMatchers("/api/public").permitAll()
.mvcMatchers("/api/private").authenticated()
.mvcMatchers("/api/private-scoped").hasAuthority("SCOPE_read:messages")
.and().cors()
.and().oauth2ResourceServer().jwt();
}
Is there some example of how to write an Integration test for controllers for this? When using standard MocMvc
@Test
@DisplayName("Should be able to access private endpoint with auth")
@WithMockUser(username = "test@something.com")
void shouldBeAbleToAccessPrivateEndpointWithAuth() throws Exception {
MockHttpServletResponse response = mockMvc.perform(
*get* ("/api/private"))
.andExpect( *status* ().isOk())
.andReturn().getResponse();
*assertThat* (response.getContentAsString()).isNotEmpty();
}
}
The only thing I found that works are to test which instance is Principal that I’m fetching from SecurityContextHolder. getContext(). Jwt (Access token) or User ( for Mock tests)
In my controller I’m using something like this:
var principal = SecurityContextHolder. getContext ().getAuthentication().getPrincipal();
var principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
var userEmail = "";
if(principal instanceof User){
userEmail = ((User)principal).getUsername(); // This is for tests where userName = email;
} else if(principal instanceof Jwt){
Jwt jwtPrincipal = (Jwt) principal;
var emailFromClaim = jwtPrincipal.getClaims().get("https://mydomain/email");
}
How can I create this access token with custom claims to test my backend API, and is there some example of creating an access token with these custom claims and user called endpoint (controller testing) in SpringBoot?