Shiro自定义异常无法被捕获总是抛出AuthenticationException解决方案

问题描述

  • 配置Realm之后,发现在Realm中抛出的异常被无法捕获,最后抛出AuthenticationException异常

解决办法

  • 针对上面问题
  • 直接在全局异常中捕获AuthenticationException异常,简单粗暴
/**
     * 拦截认证失败异常
     *
     * @author dduan
     * @date 2021/12/1 10:00
     */
    @ExceptionHandler(AuthenticationException.class)
    @ResponseBody
    public ErrorResponseData shiroAuthFail(AuthException e
### Shiro框架中doGetAuthenticationInfo方法抛出异常无法捕获解决方案Shiro框架中,`doGetAuthenticationInfo` 方法中的异常通常会被包装为 `AuthenticationException` 或其子类,导致自定义异常无法直接被捕获。以下是解决此问题的具体方法: #### 1. **全局异常处理器捕获 AuthenticationException** 在 Spring Boot 中,可以使用 `@RestControllerAdvice` 和 `@ExceptionHandler` 来捕获 `AuthenticationException` 及其子类,并通过日志记录或返回友好的错误信息[^3]。 ```java @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(AuthenticationException.class) @ResponseBody public ResponseEntity<ErrorResponseData> handleAuthenticationException(AuthenticationException e) { log.error("认证异常:{}", e.getMessage()); ErrorResponseData errorResponse = new ErrorResponseData(); errorResponse.setCode(401); errorResponse.setMessage("认证失败:" + e.getMessage()); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse); } } ``` #### 2. **自定义异常包装** 如果需要捕获特定的自定义异常(如 `BusinessException` 或 `TokenException`),可以在 `Realm` 中将这些异常包装为 `AuthenticationException` 的子类,并在全局异常处理器中进行区分处理[^4]。 ```java @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String credentials = (String) token.getCredentials(); try { JwtUtil.getInstance().verifyToken(credentials); } catch (TokenExpiredException e) { log.error("Token 已过期", e); throw new ExpiredCredentialsException("Token 已过期"); } catch (SignatureVerificationException e) { log.error("Token 签名无效", e); throw new IncorrectCredentialsException("Token 签名无效"); } catch (JWTVerificationException e) { log.error("Token 无效", e); throw new AuthenticationException("Token 无效"); } // 返回认证信息 return new SimpleAuthenticationInfo(credentials, credentials, getName()); } ``` #### 3. **确保异常传递到全局处理器** Shiro 的过滤器链会拦截异常并将其重新抛出为 `AuthenticationException`,因此需要确保全局异常处理器能够正确捕获这些异常。如果自定义异常未被正确捕获,可能是由于过滤器链配置不当或异常未被正确传递[^1]。 #### 4. **检查 Shiro 过滤器链配置** 确保 Shiro 的过滤器链配置正确,所有需要认证的接口都被拦截,并且异常能够被传递到全局异常处理器[^4]。 ```java @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); // 登录接口无需认证 filterChainDefinitionMap.put("/**", "authc"); // 其他接口需认证 factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return factoryBean; } ``` #### 5. **调试与验证** - 验证 `Realm` 中抛出异常是否能被 `AuthenticationException` 捕获。 - 测试各种异常场景(如 Token 过期、签名无效等),确保全局异常处理器能够返回正确的错误信息。 --- ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dadeity

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值