如何处理 spring 引导其余过滤器方法中的自定义异常?

how to Handle Custom exception in spring boot rest filter methods?

我想在 WebSecurityConfigurerAdapter 过滤器方法中添加自定义异常处理程序。

我正在使用自定义过滤器从当前请求中获取授权 API 密钥。然后将此 API 键与存储的 apikey 匹配,如果 API 键不匹配想要显示自定义异常说 "invalid API key" 或者如果 API 键未提供则 "API key not found in authorization header" .

如何在 API 键不匹配时将自定义通知作为 BadCredentialsException 抛出。

我的 SpringSecurityConfig class

package com.nil.springjpa.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.access.ExceptionTranslationFilter;

import com.nil.springjpa.exceptions.BadCredentialsException;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPoint authEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("1st");

        /*
         * http.csrf().disable().authorizeRequests() .anyRequest().authenticated()
         * .and().httpBasic() .authenticationEntryPoint(authEntryPoint);
         */

        PreAuthTokenHeaderFilter filter = new PreAuthTokenHeaderFilter("Authorization");

        filter.setAuthenticationManager(new AuthenticationManager() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {

                String principal = (String) authentication.getPrincipal();
                String authHeaderValue = "123xyz";
                System.out.println("5th" + principal);
                if (!authHeaderValue.equals(principal)) {
                    System.out.println("5th" + principal);
                    throw new BadCredentialsException("API Key not matched");
                }
                authentication.setAuthenticated(true);
                return authentication;
            }
        });

        http.csrf().disable().addFilter(filter)
                .addFilterBefore(new ExceptionTranslationFilter(authEntryPoint), filter.getClass()).authorizeRequests()
                .anyRequest().authenticated();

        /*
         * http.csrf().disable().authorizeRequests() .anyRequest().authenticated()
         * .and().httpBasic() .authenticationEntryPoint(authEntryPoint);
         */

    }

}

使用ControllerAdvice.

@ControllerAdvice
@RequestMapping(produces = "application/json")
public class CentralExceptionHandler {

  @ExceptionHandler(CustomException.class)
  @ResponseBody
  protected void handleAccessDeniedException(CustomException ex, HttpServletResponse response) {

    response.setHeader("Content-Type", "application/json");
    response.setStatus(status);
    response.getOutputStream().write("Something went wrong".getBytes());
  }    

}

CustomException 需要是运行时异常,并且可以从代码中的任何位置抛出。