I have implemented Auditing with Spring Data JPA, following exactly this documentation. Everything works fine when I run the app, but when I deploy the WAR to Tomcat and try to create an entity, I get an error in the getCurrentAuditor
method.
I have secured my app with keycloak, so in AuditorAwareConfig
i am trying to get the keycloak username, and after debugging i found out that request.getUserPrincipal()
is null :
java.lang.NullPointerException: null
at com.cevital.cirta.util.AuditorAwareConfig.getCurrentAuditor(AuditorAwareConfig.java:20) ~[classes/:0.0.1-SNAPSHOT
AuditorAwareConfig :
public class AuditorAwareConfig implements AuditorAware<String> {
@Autowired
private HttpServletRequest request;
@Override
public Optional<String> getCurrentAuditor() {
KeycloakPrincipal<KeycloakSecurityContext> kp = (KeycloakPrincipal<KeycloakSecurityContext>) request.getUserPrincipal();
String userName = kp.getKeycloakSecurityContext().getToken().getPreferredUsername();
return Optional.ofNullable(userName);
}
}
I recently did the same thing in my applications but I didn't use the Keycloak adapter, Spring Security 5 provides all we need to secure our applications with Keycloak or with any Oauth2 provider. Another difference, I use Hibernate Envers, which allow me to also audit delete operations.
To get the authenticated user, this is how I proceed.
public static String extractUsernameFromAuthentication() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String username;
if ( isNull( authentication ) ) {
return null;
}
if ( authentication instanceof JwtAuthenticationToken ) {
JwtAuthenticationToken token = (JwtAuthenticationToken) authentication;
username = (String) ( token ).getTokenAttributes().get( "preferred_username" );
} else {
username = authentication.getName();
}
return username;
}
Remember, I do not use the Keycloak Adapter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With