@ControllerAdvice nie łapie wyjatku, Spring Boot 1.5.3

0

Cześć, mam rest api postawione na spring boocie 1.5.3 z security, logowanie i autentykacja requestów po tokenie. Dodałem nowy exception i exception handler żeby łapał mi mój wyjątek i zwracał 401 przy braku tokena w nagłowkach, ale Spring zawsze zwraca status code 500, poniżej mój kod.

StatelessAuthenticationFilter

public class StatelessAuthenticationFilter extends GenericFilterBean {

    private final TokenAuthenticationService tokenAuthenticationService;

    public StatelessAuthenticationFilter(TokenAuthenticationService taService) {
        this.tokenAuthenticationService = taService;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        SecurityContextHolder.getContext().setAuthentication(tokenAuthenticationService.getAuthentication((HttpServletRequest) req));
        chain.doFilter(req, res);
    }
}

StatelessLoginFilter

public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter {

    private final TokenAuthenticationService tokenAuthenticationService;
    private final UserServiceImpl userService;

    public StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService,
                                   UserServiceImpl userDetailsService, AuthenticationManager authManager) {
        super(new AntPathRequestMatcher(urlMapping));
        this.userService = userDetailsService;
        this.tokenAuthenticationService = tokenAuthenticationService;
        setAuthenticationManager(authManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {

        String headerCredentials = request.getHeader("BasicAuth");

        if (headerCredentials == null) {
            throw new BadCredentialsException("No header in request");
        }

        String credentials = new String(Base64.decodeBase64(headerCredentials), "UTF-8");
        if (!credentials.contains((":"))) {
            throw new BadCredentialsException("Wrong header");
        }
        String [] credentialsArray = credentials.split(":");

        String login = credentialsArray[0];
        String password = credentialsArray[1];

        final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken(login, password);
        return getAuthenticationManager().authenticate(loginToken);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain chain, Authentication authentication) throws IOException, ServletException {

        // Lookup the complete User2 object from the database and create an Authentication for it
        final User authenticatedUser = userService.loadUserByUsername(authentication.getName());
        final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser);

        // Add the custom token as HTTP header to the response
        tokenAuthenticationService.addAuthentication(response, userAuthentication);

        // Add the authentication to the Security context
        SecurityContextHolder.getContext().setAuthentication(userAuthentication);
    }
}

MyOwnException

public class MyOwnException extends RuntimeException {

    public MyOwnException(String message) {
        super(message);

    }
}

RestResponseEntityExceptionHandler


@ControllerAdvice
public class RestResponseEntityExceptionHandler  extends DefaultHandlerExceptionResolver {

    @ExceptionHandler(MyOwnException.class)
    void handleMyOwnException(HttpServletResponse response) throws IOException {
        response.sendError(HttpStatus.UNAUTHORIZED.value());
    }
}

StatelessAuthenticationSecurityConfig

@EnableWebSecurity
@Configuration
@Order(1)
public class StatelessAuthenticationSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private TokenAuthenticationService tokenAuthenticationService;

    public StatelessAuthenticationSecurityConfig() {
        super(true);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/login").permitAll()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().hasRole("USER")
                .anyRequest().hasRole("ADMIN").and()

                // custom JSON based authentication by POST of {"username":"<name>","password":"<password>"} which sets the token header upon authentication
                .addFilterBefore(new StatelessLoginFilter("/login", tokenAuthenticationService, userService, authenticationManager()), UsernamePasswordAuthenticationFilter.class)

                // custom Token based authentication based on the header previously given to the client
                .addFilterBefore(new StatelessAuthenticationFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("*");
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "DELETE", "OPTIONS"));
        configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
        configuration.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Override
    protected UserServiceImpl userDetailsService() {
        return userService;
    }
}

VoteApp

@SpringBootApplication
public class VoteApp {
    public static void main(String[] args) {
        SpringApplication.run(VoteApp.class, args);
    }

    @Bean
    public Filter characterEncodingFilter() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return characterEncodingFilter;
    }
}
0

No tak. Piątek i magia nie działa...
Zobacz na debugu czy wchodzi do tego handle. A może spring i tak wysyła własny kod błędu - nieważne co ty ustawiasz. Może coś w stylu @ResponseStatus musisz dodać ?

0
@ExceptionHandler(MyOwnException.class)

Łapiesz ten wyjątek ale nigdzie go nie rzucasz

1 użytkowników online, w tym zalogowanych: 0, gości: 1