Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security Authentication Provider exception handling

I have an authentication provider, that throwing my custom exception. This provider validating token on every request to controllers. Exceptions in controllers handling by controller advice, but provider works before controller, so controller advice cant handle exceptions that provider throws. How can i handle exception from provider?

Provider

@Component
@RequiredArgsConstructor
public class BearerTokenAuthenticationProvider implements AuthenticationProvider {

private final Wso2TokenVerificationClient client;

@Override
public Authentication authenticate( Authentication authentication ) {
    BearerTokenAuthenticationToken token = (BearerTokenAuthenticationToken) authentication;
    Map<String, String> requestBody = new HashMap<>();
    requestBody.put( "token", token.getToken() );
    Wso2TokenValidationResponse tokenValidationResponse = client.introspectToken( requestBody );
    if( !Boolean.parseBoolean( tokenValidationResponse.getActive() ) ) {
        throw new AuthenticationException(
            "Token not valid", HttpStatus.UNAUTHORIZED
        );
    }
    DecodedJWT jwt = JWT.decode(token.getToken());
    UserDetails details = new UserDetails();
    details.setId( Long.parseLong(jwt.getClaim( OidcUserClaims.USER_ID ).asString()) );
    details.setEmail( jwt.getClaim( OidcUserClaims.EMAIL ).asString() );
    token.setDetails( details );
    return token;
}

@Override
public boolean supports( Class<?> aClass ) {
    return BearerTokenAuthenticationToken.class.equals( aClass );
}

Security Config

@Configuration
@RequiredArgsConstructor
public class CommonWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

private final BearerTokenAuthenticationProvider bearerTokenProvider;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.headers().contentSecurityPolicy("script-src 'self'");
    http
            .csrf().disable()
            .authorizeRequests(auth -> auth
                    .antMatchers("/public/**").not().hasAuthority("ROLE_ANONYMOUS")
            )
        .and()
        .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
}

@Override
protected void configure( AuthenticationManagerBuilder auth ) throws Exception {
    auth.authenticationProvider( bearerTokenProvider );
}

}

like image 689
Montana Avatar asked Dec 14 '25 13:12

Montana


2 Answers

You can add an authenticationEntryPoint to handle custom exception.

@Configuration
@RequiredArgsConstructor
static class CommonWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {

    private final BearerTokenAuthenticationProvider bearerTokenProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .headers()
                .contentSecurityPolicy("script-src 'self'");
        http
            .csrf().disable()
            .authorizeRequests(auth -> auth
                 .antMatchers("/public/**").not().hasAuthority("ROLE_ANONYMOUS")
            )
            .oauth2ResourceServer(c -> c.jwt()
                .and()
                .authenticationEntryPoint((request, response, authException) -> {
                    //handle CustomAuthenticationException
                    
                    }
                )
            );
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(bearerTokenProvider);
    }
}

public class CustomAuthenticationException extends AuthenticationException {
    HttpStatus status;
    
    public CustomAuthenticationException(String message, HttpStatus status) {
        super(message);
        this.status = status;
    }
}
like image 114
DingHao Avatar answered Dec 16 '25 03:12

DingHao


I support the accepted answer here but want to highlight key tricky part of it:

I had same structure but instead of throwing my custom exception, I used AuthenticationServiceException and that was simply not working.

To be able to handle exception in your custom AuthenticationEntryPoint you MUST extend AuthenticationException with your own implementation as it is done in accepted answer.

like image 39
Michal Maťovčík Avatar answered Dec 16 '25 04:12

Michal Maťovčík



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!