Shiro权限校验失败需抛出UnauthorizedException才能触发统一处理机制;手动抛异常时必须使用Shiro原生UnauthorizedException,自定义Realm中可主动抛出,注解校验失败由Shiro自动抛出,且需避免catch中掩盖该异常。

Shiro 权限校验失败时默认会抛出 UnauthorizedException(继承自 AuthorizationException),但如果你在业务逻辑中手动用 throw 抛出的是其他异常(比如 RuntimeException 或自定义异常),Shiro 不会自动识别为权限拒绝,也就无法触发 setUnauthorizedUrl 或统一异常处理机制。要让 Shiro 正确捕获并按权限异常流程处理,关键在于:**抛出的必须是 Shiro 原生的 UnauthorizedException 或其子类**。
确保抛出的是真正的 UnauthorizedException
不要自己 new 一个普通异常,而应直接 throw Shiro 提供的标准异常:
-
正确写法:
throw new UnauthorizedException("缺少操作权限:/order/delete"); -
错误写法:
throw new RuntimeException("无权删除订单");—— Shiro 完全不感知,不会走权限拦截逻辑
在自定义 Realm 中主动抛出
当重写 doGetAuthorizationInfo() 后,若发现用户未分配对应权限,可在业务判断中主动 throw:
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 例如检查数据库返回的权限列表为空,或不包含当前请求所需权限字符串
- 此时直接
throw new UnauthorizedException("角色 " + principal + " 未授权访问资源 " + resource); - 注意:这不是替代 Shiro 的权限检查,而是补充校验逻辑(如动态权限、租户隔离等场景)
配合注解使用时,异常由 Shiro 自动抛出
只要使用了 Shiro 的标准权限注解,失败时 Shiro 会自动抛 UnauthorizedException,无需手动 throw:
立即学习“Java免费学习笔记(深入)”;
@RequiresPermissions("order:delete")@RequiresRoles("admin")- Shiro AOP 拦截器会在方法执行前校验,不通过就直接 throw
UnauthorizedException - 前提是注解已生效(配置了
DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor)
避免被其他异常掩盖
如果代码中已有 try-catch,需确保没把 UnauthorizedException 吞掉或转成其他异常:
- 错误示例:
catch (Exception e) { throw new RuntimeException(e); }→ 原始UnauthorizedException被包装丢失 - 正确做法:显式捕获并重新 throw,或至少保留原始异常类型:
catch (UnauthorizedException e) { throw e; }

















