【问题标题】:how to Handle Custom exception in spring boot rest filter methods?如何在 Spring Boot 休息过滤器方法中处理自定义异常?
【发布时间】:2020-08-28 09:21:12
【问题描述】:

我想在 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-boot authorization


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复。我做了但没有工作。我做了同样的事情,但没有调用这个特定的方法。我认为 ControllerAdvice 仅适用于休息控制器
    • 谁在捕捉 BadCredentialsException?如果您让它传播,它将最终出现在控制器建议中
    • 我的一个应用程序中有类似的情况。尝试创建一个自定义异常并抛出它。通过这种方式,您可以确定除了控制器建议之外没有其他任何东西可以捕捉到它。
    • 控制器建议缓存所有异常,它对于从控制器调用的异常(如约束违规)工作正常。但在尝试从过滤器身份验证方法中抛出时不起作用。
    • 我应该为 CentralExceptionHandler 类扩展 ResponseEntityExceptionHandler
    猜你喜欢
    • 2021-07-10
    • 2019-10-09
    • 2016-03-25
    • 2021-08-09
    • 2023-03-04
    • 1970-01-01
    • 2019-11-15
    • 2017-04-20
    • 2016-07-11
    相关资源
    最近更新 更多