返回

化解 Java SpringBoot 项目中 org.apache.shiro.authz.UnauthorizedException: Subject does not have permission 异常的正确姿势

后端

解决 SpringBoot 项目中 Shiro 框架的 UnauthorizedException 异常

在 Java SpringBoot 项目中,Shiro 框架是实现身份验证和授权的常用工具。然而,当用户尝试访问受保护资源时,如果他们没有必要的权限,Shiro 可能会抛出 org.apache.shiro.authz.UnauthorizedException: Subject does not have permission 异常。

异常的根源

1. 未登录或会话过期:
如果用户尚未登录或其会话已过期,Shiro 无法识别他们的身份和角色,从而无法授予访问受保护资源的权限。

2. 权限不足:
即使用户已登录,但他们拥有的权限不足以访问受保护资源,也会引发此异常。

3. 资源权限配置错误:
如果受保护资源的权限配置不当,则即使用户具有必要的权限,也可能无法访问该资源,从而引发异常。

4. Shiro 框架配置错误:
Shiro 框架的配置不当也可能导致此异常的发生。

解决策略

1. 确保用户已登录并会话有效:
* 使用 SecurityUtils.getSubject().isAuthenticated() 方法检查用户是否已登录。

2. 检查用户权限:
* 使用 SecurityUtils.getSubject().isPermitted() 方法检查用户是否拥有访问该资源的权限。

3. 检查资源权限配置:
* 检查 Shiro 的 SecurityManagergetAuthorizationInfo() 方法来查看资源的权限配置。

4. 检查 Shiro 框架配置:
* 检查 Shiro 的 SecurityManagergetConfiguration() 方法来查看 Shiro 框架的配置。

5. 代码示例:

@RequestMapping("/protected-resource")
public String protectedResource() {
    // 检查用户是否已登录
    if (!SecurityUtils.getSubject().isAuthenticated()) {
        return "redirect:/login";
    }

    // 检查用户是否拥有访问该资源的权限
    if (!SecurityUtils.getSubject().isPermitted("/protected-resource")) {
        throw new UnauthorizedException("您没有访问该资源的权限!");
    }

    // 显示受保护的资源
    return "protected-resource";
}

常见问题解答

1. 如何防止该异常发生?
确保用户已登录、拥有必要的权限,并正确配置资源权限和 Shiro 框架。

2. 该异常是临时的吗?
这取决于异常的原因。如果它是由于用户未登录或会话过期造成的,则它是临时的。但如果是由于权限不足或配置错误造成的,则需要解决根本问题。

3. 如何调试此异常?
使用日志记录和调试工具,例如断点,来确定异常发生的确切原因。

4. 该异常与 AccessDeniedException 有何不同?
AccessDeniedException 指示用户没有访问受保护资源的权限,而 UnauthorizedException 指示用户甚至没有被授权尝试访问该资源。

5. 如何在不抛出异常的情况下处理该异常?
您可以使用异常处理机制,例如 @ControllerAdvice 注解,在不抛出异常的情况下对该异常进行处理。