I wanna authenticate users via Keycloak, but I need to add additional roles to Authentication object, that is using by Spring Security. Adding roles are saved in Postgres database.
I tried to override configureGlobal with custom AuthenticationProvider, but it didn't work.
@Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { ApplicationAuthenticationProvider provider = new ApplicationAuthenticationProvider(); provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper()); auth.authenticationProvider(provider); }@Component public class ApplicationAuthenticationProvider extends KeycloakAuthenticationProvider {
@Autowired private UserService userService; private GrantedAuthoritiesMapper grantedAuthoritiesMapper; public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) { this.grantedAuthoritiesMapper = grantedAuthoritiesMapper; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication; List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); String username = ((KeycloakAuthenticationToken) authentication) .getAccount().getKeycloakSecurityContext().getToken().getPreferredUsername(); List<Role> roles = userService.findRoles(username); for (Role role : roles) { grantedAuthorities.add(new KeycloakRole(role.toString())); } return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities)); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } private Collection<? extends GrantedAuthority> mapAuthorities( Collection<? extends GrantedAuthority> authorities) { return grantedAuthoritiesMapper != null ? grantedAuthoritiesMapper.mapAuthorities(authorities) : authorities; }}
Tried to add additional filter, but i'm not sure in correct configuration.
@Bean
@Override protected KeycloakAuthenticationProcessingFilter keycloakAuthenticationProcessingFilter() throws Exception { RequestMatcher requestMatcher = new OrRequestMatcher( new AntPathRequestMatcher("/api/login"), new QueryParamPresenceRequestMatcher(OAuth2Constants.ACCESS_TOKEN), // We're providing our own authorization header matcher new IgnoreKeycloakProcessingFilterRequestMatcher() ); return new KeycloakAuthenticationProcessingFilter(authenticationManagerBean(), requestMatcher); } // Matches request with Authorization header which value doesn't start with "Basic " prefix private class IgnoreKeycloakProcessingFilterRequestMatcher implements RequestMatcher { IgnoreKeycloakProcessingFilterRequestMatcher() { } public boolean matches(HttpServletRequest request) { String authorizationHeaderValue = request.getHeader("Authorization"); return authorizationHeaderValue != null && !authorizationHeaderValue.startsWith("Basic "); }}