首页 > 解决方案 > 如何在 Spring Boot 休息过滤器方法中处理自定义异常?

问题描述

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

我正在使用自定义过滤器从当前请求中获取授权 API 密钥。然后将此 API 密钥与存储的 apikey 匹配,如果 API 密钥不匹配想要显示自定义异常说“无效的 API 密钥”或者如果未提供 API 密钥则“在授权标头中找不到 API 密钥”。

当 API 密钥不匹配时,如何将自定义通知作为 BadCredentialsException 抛出。

我的 SpringSecurityConfig 类

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);
         */

    }

}

标签: spring-bootauthorization

解决方案


使用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需要是运行时异常,并且可以从代码中的任何位置抛出。


推荐阅读