0%

Shiro简介

Shiro简介

Shiro是一个开源的安全框架,可以进行身份认证、访问控制授权、会话管理以及加密等

  • Authentication 身份验证
  • Authorization 授权
  • Session Management 用户session管理器
  • Crytography 加密
架构

核心对象

Subject

Subject是与程序进行交互的对象,可以理解为用户,即当前操作用户,所有Subject实例必须绑定到一个SecurityManager上,与Subject进行交互,shiro会自动转换到与SecurityManager交互的特定Subject的交互

SecurityManager

SecurityManager是Shiro的核心,初始化时协调各个模块运行,管理内部组件实例,提供安全管理的各种服务,管理所有的Bubkect、且负责进行认证和授权以及会话、缓存

Realms

Realms在Shiro中作为应用程序和安全数据之间的桥梁,可以认为是安全实体数据源,用于获取安全实体的

shiro提供了几个实现类

  • IniRealm [users]部分指定用户名、密码及其角色;[roles]部分指定角色及权限信息

  • PropertiesRealm user.username=password,role1,role2 role.role1=permission1,permission2

  • JdbcRealm 通过sql查询对应的信息,有默认的几条获取的sql

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
    * The default query used to retrieve account data for the user.
    */
    protected static final String DEFAULT_AUTHENTICATION_QUERY = "select password from users where username = ?";

    /**
    * The default query used to retrieve account data for the user when {@link #saltStyle} is COLUMN.
    */
    protected static final String DEFAULT_SALTED_AUTHENTICATION_QUERY = "select password, password_salt from users where username = ?";

    /**
    * The default query used to retrieve the roles that apply to a user.
    */
    protected static final String DEFAULT_USER_ROLES_QUERY = "select role_name from user_roles where username = ?";

    /**
    * The default query used to retrieve permissions that apply to a particular role.
    */
    protected static final String DEFAULT_PERMISSIONS_QUERY = "select permission from roles_permissions where role_name = ?";

Authenticator

认证器,负责主体认证,可以进行自定义扩展,在shiro中提供的ModularRealmAuthenticator实现是委托给多个Realm来进行验证,验证规则通过AuthenticationStrategy来进行判断,默认提供了三种规则

  • AllSuccessfulStrategy 所有Realm都验证成功才算成功
  • AtLeastOneSuccessfulStrategy 只要有一个Realm验证成功就算成功 默认使用该策略
  • FirstSuccessfulStrategy 只要有一个验证成功就算成功,但是只返回第一个Realm身份验证成功的认证信息,其他的忽略

Authrizer

授权器,用来决定主体是否有权限进行相应的操作,即控制用户能否访问应用中的某个功能

SessionManager

Session管理

SessionDAO

数据访问对象,用于会话的CRUD,如果需要把session保存到数据库中,可以实现自己的SessionDAO,通过JDBC写入到数据库

CacheManger

缓存控制器,来管理用户、角色、权限等的缓存

Cryptography

密码模块,可用于加密和解密

认证过程

1
2
3
4
5
6
7
8
9
10
11
// 环境准备
BasicIniEnvironment environment = new BasicIniEnvironment("classpath:shiro.ini");
// 全局配置,绑定SecurityManager
SecurityUtils.setSecurityManager(environment.getSecurityManager());
// 通过SecurityUtils获取subject,会自动绑定到当前线程
Subject subject = SecurityUtils.getSubject();
// 用户名密码验证token
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");

// 登录
subject.login(token);
  • 应用程序构建了一个终端用户认证信息的AuthenticationToken实例后,调用Subject.login方法
  • Subject的实例通常是DelegatingSubject类或其子类,在认证开始时,会委托应用程序设置的securityManager实例调用securityManager.login(token)方法
  • securityManager接收到token后会委托内置的Authenticator实例(一般为ModularRealmAuthenticator实例)调用authenticator.authenticate(token)
  • 如果在应用程序中配置了多个Realm,ModularReamAuthenticator会根据配置的AuthenticationStrategy认证策略来进行多Realm的认证过程,在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果作出响应
  • 判断每一个Realm是否支持提交的token,如果支持,Realm将会调用getAuthenticationInfo(token)进行实际认证处理,可以重写doGetAuthenticationInfo方法来编写自定义的认证处理

授权过程

  • 在应用程序中调用授权验证方法(Subject的isPermitted或者hasRole等)
  • Subject的实例通常是DelegatingSubject类或其子类,会委托应用程序设置的securityManager实例调用相应的isPermitted或者hasRole
  • securityManager会委托内置的Authorizer调用相应的授权方法
  • 每一个Realm将检查是否实现了相同的Authorizer接口,调用Realm相应的授权验证方法