Shrio基本原理及工作流程

185 阅读2分钟

Apache Shiro 是一个强大且易用的 Java 安全框架,其核心设计围绕三大组件(Subject、SecurityManager、Realm)和分层工作流程实现身份认证、授权、会话管理等安全功能。以下是其基本原理及工作流程的详细解析:


一、核心组件

  1. Subject(主体)​

    • 代表当前与应用程序交互的实体(如用户、第三方服务等),是开发者直接交互的对象。
    • 提供登录、注销、权限检查等操作接口,所有操作最终委托给 SecurityManager执行。
    • 示例:Subject currentUser = SecurityUtils.getSubject();获取当前用户实例。
  2. SecurityManager(安全管理器)​

    • Shiro 的核心,协调所有安全操作(认证、授权、会话管理等),类似 Spring MVC 中的 DispatcherServlet
    • 管理所有 Subject实例,并通过 Realm获取安全数据(用户、角色、权限)。
  3. Realm(安全数据源)​

    • 充当 Shiro 与应用程序安全数据(如数据库、LDAP)之间的桥梁,负责认证和授权的具体逻辑实现。
    • 开发者需自定义 Realm,重写 doGetAuthenticationInfo(认证)和 doGetAuthorizationInfo(授权)方法。

二、工作流程

1. 身份认证(Authentication)​

  • 步骤​:

    1. 用户提交凭证(如用户名/密码),封装为 AuthenticationToken(如 UsernamePasswordToken)。
    2. Subject.login(token)调用 SecurityManager,后者委托 Realm验证凭证。
    3. Realm查询用户数据并比对凭证,成功则返回 AuthenticationInfo,失败抛出异常(如 UnknownAccountException)。
  • 关键代码​:

    UsernamePasswordToken token = new UsernamePasswordToken(username, password);  
    Subject subject = SecurityUtils.getSubject();  
    subject.login(token); // 触发认证流程
    

2. 授权(Authorization)​

  • 步骤​:

    1. 认证通过后,SecurityManager通过 Realm获取用户的角色和权限。
    2. 调用 subject.hasRole("admin")subject.isPermitted("user:create")进行权限校验。
    3. 若权限不足,抛出 UnauthorizedException
  • 权限模型​:

    • RBAC(基于角色)​​:如 admin=*表示管理员拥有所有权限。
    • 细粒度控制​:支持资源级(如 user:delete)或实例级(如 user:delete:123)权限。

3. 会话管理(Session Management)​

  • Shiro 提供统一的会话 API,支持 Web 和非 Web 环境。会话数据可存储在内存、数据库或缓存中。

  • 关键操作:

    Session session = subject.getSession(); // 获取或创建会话  
    session.setAttribute("key", value);  
    session.setTimeout(1800000); // 设置超时
    

4. 过滤器链(Web 集成)​

  • 在 Web 应用中,Shiro 通过过滤器链(如 anonauthcperms)拦截请求,按 URL 规则执行认证或授权检查。

  • 示例配置​(shiro.ini):

    [urls]
    /login = anon          # 匿名访问
    /admin/** = authc, roles[admin] # 需认证且角色为admin
    

三、扩展功能

  • 加密(Cryptography)​​:提供 Md5HashSha512Hash等工具类,简化密码加密与校验。
  • 缓存​:通过 CacheManager(如 EhCache)缓存用户权限,提升性能。
  • Remember Me​:基于 Cookie 实现持久化登录状态。

总结

Shiro 通过分层设计(Subject→SecurityManager→Realm)实现灵活的安全控制,其工作流程清晰且易于扩展,适用于从命令行到企业级 Web 应用的各种场景。开发者只需关注 Realm的自定义和权限规则配置,即可快速集成安全功能。