spring security抛出自定义异常

首先抛出自定义异常这个思路是没啥问题的,至少比抛出UsernameNotFoundException来的自由些,因为在hideUserNotFoundExceptions属性默认为true的情况下,UsernameNotFoundException会被转换成BadCredentialsException,同时连异常信息都会被写成固定的Bad credentials了,部分源码参考如下:
在这里插入图片描述

  1. 首先我们要先定义一个自定义异常类,参考如下:
/**
 1. @Author:jiejie
 2. @Desc: 自定义业务异常
 3. @Date: 2021/3/16 11:35
 4. @Version 1.0
 */
public class BusinessException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    protected final String message;

    public BusinessException(String message) {
        this.message = message;
    }

    public BusinessException(String message, Throwable e) {
        super(message, e);
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}
  1. 此时碰到什么手机号已注册等等的业务异常,都使用该异常来处理,但是会发现,还是没法抛出我们想要的code和message。
  2. 自定义异常了,那我们此时就应该自定义一个全局异常处理器类,让它捕获到BusinessException,然后再封装信息做具体的返回,参考如下:
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Author: jiejie
 * @Date: 2021/4/13 下午2:11
 * @Desc: 全局处理抛出的异常
 * @Version 1.0
 */
@ControllerAdvice
public class Oauth2ExceptionHandler {
    /**
     * 业务异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public R handlerBusinessException(BusinessException e) {
        return R.failed(BizCodeEnume.BUSSINESS_EXCEPTION, e.getMessage());
    }


    @ResponseBody
    @ExceptionHandler(value = OAuth2Exception.class)
    public R handleOauth2(OAuth2Exception e) {
        return R.failed(e.getMessage());
    }
}

  1. 继续验证,发现即使抛出的是BusinessException异常,但是全局异常处理器竟然还是没捕获到,导致返回的结果还是不符合要求,此时猜想spring security捕获UsernameNotFoundException异常再转化成BadCredentialsException异常的操作,猜测异常可能是被转化了,此时只能去跟踪源码,慢慢找,最终发现,有个大的处理逻辑,就是如果匹配不到具体的异常,就会把此时的Exception转化成InternalAuthenticationServiceException异常再抛出,具体源码如下:
    在这里插入图片描述
  2. 此时的处理思路就很清晰了,在全局异常处理器中马上再加上几个要捕获处理的异常即可,修改后整体如下:
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Author: jiejie
 * @Date: 2021/4/13 下午2:11
 * @Desc: 全局处理抛出的异常
 * @Version 1.0
 */
@ControllerAdvice
public class Oauth2ExceptionHandler {
    /**
     * 业务异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public R handlerBusinessException(BusinessException e) {
        return R.failed(BizCodeEnume.BUSSINESS_EXCEPTION, e.getMessage());
    }

    /**
     * 用户名和密码错误
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(InvalidGrantException.class)
    public R handleInvalidGrantException(InvalidGrantException e) {
        return R.failed(BizCodeEnume.BUSSINESS_EXCEPTION, e.getMessage());
    }

    /**
     * 账户异常(禁用、锁定、过期)
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler({InternalAuthenticationServiceException.class})
    public R handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e) {
        return R.failed(BizCodeEnume.BUSSINESS_EXCEPTION, e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = OAuth2Exception.class)
    public R handleOauth2(OAuth2Exception e) {
        return R.failed(e.getMessage());
    }
}

再次测试,发现返回结果符合需求了,如下:
在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Spring Security中,可以通过自定义异常来处理登录过程中的异常情况。以下是实现自定义异常的步骤: 1. 创建一个自定义的异常类,继承自`AuthenticationException`或其子类。例如,可以创建一个名为`CustomAuthenticationException`的异常类。 ```java public class CustomAuthenticationException extends AuthenticationException { public CustomAuthenticationException(String msg) { super(msg); } } ``` 2. 创建一个自定义的认证提供者(AuthenticationProvider)或认证过滤器(AuthenticationFilter)。 - 如果你选择创建认证提供者,需要实现`AuthenticationProvider`接口,并在`authenticate()`方法中抛出自定义异常。 ```java public class CustomAuthenticationProvider implements AuthenticationProvider { @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 自定义认证逻辑 if (认证失败) { throw new CustomAuthenticationException("自定义异常信息"); } // 认证成功则返回一个认证对象 return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), authentication.getAuthorities()); } @Override public boolean supports(Class<?> authentication) { return authentication.equals(UsernamePasswordAuthenticationToken.class); } } ``` - 如果你选择创建认证过滤器,需要继承`AbstractAuthenticationProcessingFilter`类,并在`attemptAuthentication()`方法中抛出自定义异常。 ```java public class CustomAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public CustomAuthenticationFilter() { super(new AntPathRequestMatcher("/login", "POST")); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { // 自定义认证逻辑 if (认证失败) { throw new CustomAuthenticationException("自定义异常信息"); } // 认证成功则返回一个认证对象 return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username, password)); } } ``` 3. 在Spring Security配置类中,将自定义的认证提供者或认证过滤器添加到认证流程中。 ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomAuthenticationProvider customAuthenticationProvider; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(customAuthenticationProvider); } } ``` 这样,当登录过程中发生自定义异常时,Spring Security会捕获并处理该异常,你可以在登录失败的处理逻辑中进行相应的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值