带你揭秘Shiro(二)

授权流程

 

1、对subject进行授权,调用方法isPermitted("permission串")

2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

3、ModularRealmAuthorizer执行realm(自定义的Realm)从数据库查询权限数据,调用realm的doGetAuthorizationInfo授权方法

4、realm从数据库查询权限数据,返回ModularRealmAuthorizer

5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

修改之前realmDemo.java中的doGetAuthorizationInfo方法
// 用于授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
        PrincipalCollection principals) {

    // 从 principals获取主身份信息
    // 将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
    String userName = (String) principals.getPrimaryPrincipal();

    // 根据身份信息获取权限信息
    // 连接数据库...
    // 模拟从数据库获取到数据
    List<String> permissions = new ArrayList<String>();
    permissions.add("user:create");// 用户的创建
    permissions.add("user:update");// 用户的修改
    // ....

    // 查到权限数据,返回授权信息(要包括 上边的permissions)
    SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    // 将上边查询到授权信息填充到simpleAuthorizationInfo对象中
    simpleAuthorizationInfo.addStringPermissions(permissions);

    return simpleAuthorizationInfo;
}


3.创建shiro-realm.ini文件,配置自定义的realm,将realm设置到securityManager中,因为之前已经配置过,该步骤可以省略


4.在AuthorizationDemo中添加方法进行测试



//
自定义realm进行资源授权测试 @Test public void testRealmDemo() { // 创建SecurityManager工厂 Factory<SecurityManager> factory = new IniSecurityManagerFactory( "classpath:shiro-realm.ini"); // 创建SecurityManager SecurityManager securityManager = factory.getInstance(); // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理 SecurityUtils.setSecurityManager(securityManager); // 创建subject Subject subject = SecurityUtils.getSubject(); // 创建token令牌 UsernamePasswordToken token = new UsernamePasswordToken("jack", "123"); // 执行认证 try { subject.login(token); } catch (AuthenticationException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("认证状态:" + subject.isAuthenticated()); // 认证通过后执行授权 // 基于资源的授权,调用isPermitted方法会调用realmDemo从数据库查询正确权限数据 // isPermitted传入权限标识符,判断user:create:1是否在realmDemo查询到权限数据之内 boolean isPermitted = subject.isPermitted("user:create:1"); System.out.println("单个权限判断" + isPermitted); boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:update"); System.out.println("多个权限判断" + isPermittedAll); // 使用check方法进行授权,如果授权不通过会抛出异常 // subject.checkPermission("user:delete"); }

 

posted @ 2019-12-05 20:47  魏小哥  阅读(220)  评论(0编辑  收藏  举报