三、Shiro授权开发

Shiro 支持三种方式的授权:

I、 编程式:通过写if/else 授权代码块完成:

Subject subject =SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有权限

} else {

//无权限

}

II、 注解式:通过在执行的Java方法上放置相应的注解完成:

@RequiresRoles("admin")

public void hello() {

//有权限

}

III、 JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:

<shiro:hasRolename="admin">

<!— 有权限—>

</shiro:hasRole>

此教程序授权测试使用第一种编程方式,实际与web系统集成使用后两种方式。

权限标识符

权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。

例子:

用户创建权限:user:create,或user:create:*
用户修改实[例]()001的权限:user:update:001
用户实例001的所有权限:user:*:001

I、根据配置文件认证

[users]
zhang3=123123,normal
li4=123456,super

[roles]
# normal 具有用户的所有权限

normal=user:*
super=product:*,user:*
package com.baizhi.Authorrizer;/**
 * @Author:luoht
 * @Description:
 * @Date:Create in 20:50 2018/12/30
 */

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

import java.util.Arrays;
import java.util.List;

/**
 * @program: DJ
 * @description:
 * @author: luoht
 * @create: 2018-12-30 20:50
 **/

public class TestAuthorize {
    public static void main(String[] args) {
        //如果授权,就先认证
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro3.ini");
        SecurityManager instance = iniSecurityManagerFactory.getInstance();
        SecurityUtils.setSecurityManager(instance);
        Subject subject =   SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken("zhang3", "123123");
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            System.out.println(("用户名错误"));
        } catch (IncorrectCredentialsException e){
            System.out.println("密码错误");
        }

        boolean authenticated = subject.isAuthenticated();

        if (authenticated){
            /**
             * 认证成功之后
             * 编程式授权
             * 1. 基于角色
             * 2. 基于资源
             *
             */

            /* 1.1 判断当前主体是否含有某种角色*/
            boolean hasRole = subject.hasRole("normal");
            System.out.println(hasRole);
            /* 1.2 判断当前主体是否具有某些角色*/
            List<String> strings = Arrays.asList("normal", "super");
            boolean[] booleans = subject.hasRoles(strings);
            for (boolean aBoolean : booleans) {
                System.out.println(aBoolean);
            }

            /* 1.3 判断当前主主体是否同时具有某些角色*/
            boolean hasAllRoles = subject.hasAllRoles(strings);
            System.out.println(hasAllRoles);

            /* 2.1 判断当前主体是否具有某个权限*/
            boolean subjectPermitted = subject.isPermitted("user:create");
            System.out.println(subjectPermitted);
            /* 2.2 判断当前用户书否具有某些权限*/

            List<String> stringList = Arrays.asList("user:create", "product:delete");
            String[] strings1={"user:create", "product:delete"};
            boolean[] permitted = subject.isPermitted(strings1);
            for (boolean b : permitted) {
                System.out.println(b);
            }
            boolean permittedAll = subject.isPermittedAll(strings1);
            System.out.println(permittedAll);


        }

    }
}
  

II、数据库认证

自定义Realm:

package com.baizhi.Authorrizer;/**
 * @Author:luoht
 * @Description:
 * @Date:Create in 22:30 2018/12/30
 */

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * @program: DJ
 * @description:
 * @author: luoht
 * @create: 2018-12-30 22:30
 **/

public class MyRealm3 extends AuthorizingRealm {
     /* 授权 | Actually, I don't know what that fucking means*/
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        /*通过用户查询角色*/
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRole("normal");

        /*通过角色查询权限*/
        return simpleAuthorizationInfo;
    }

    /* 认证*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        if (principal.equals("zhang3")){
            return new SimpleAuthenticationInfo("zhang3","b8cc2120cdf1554cf35603e08f7f5524", ByteSource.Util.bytes("1345"),this.getName());
        }
        return null;
    }
}
 
[main]
# 声明凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
# 声明realm
realm2= com.baizhi.Authorrizer.MyRealm3
securityManager.realms=$realm2
# 告知realm使用HashedCredentialsMatcher 为凭证匹配器
realm2.credentialsMatcher=$credentialsMatcher
# 告知安全管理器使用自定义
securityManager.realms=$realm2

# 告知Shiro算法的名称
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=1024 

III、授权执行流程

  1. 执行subject.isPermitted("user:create")
  2. securityManager通过ModularRealmAuthorizer进行授权
  3. ModularRealmAuthorizer调用realm获取权限信息

ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

猜你喜欢

转载自www.cnblogs.com/adrien/p/10227146.html