shrio教程初级(五)shiro基础(授权)

来源:互联网 发布:爱马仕雪白龙胆知乎 编辑:程序博客网 时间:2024/06/06 15:38

一、前言

回忆过去,shiro的认证忘不了:

0:通过securityFactory建立securityManager,加入securityUtil加入环境

1、subject(主体)请求认证,调用login(token)

2、securityManager开始认证

3、securityManager通过ModularRealmAuthenticator进行认证

4、ModularRealmAuthenticator将token传统给realm,realm根据token从数据源(库)查询用户信息的身份和凭证(用户名与密码)。

5、realm查询不到返回空(用户不存在异常),如果凭证错误,返回凭证错误。否则返回正确的AuthenticationInfo(认证信息)

二、shrio权限授权

权限授权验证,一样是四个步骤,写ini文件-----加载ini----认证用户----权限验证,请注意任何认证之后才验证权限,是一般的思路不要忘记了。

2.1 编写ini文件

shiro-permission.ini
#用户[users]#用户zhang的密码是123,此用户具有role1和role2两个角色ycy=111,role1,role2ycy2=111,role2#权限[roles]#角色role1对资源user拥有create、update权限role1=user:create,user:update#角色role2对资源user拥有create、delete权限role2=user:create,user:delete#角色role3对资源user拥有create权限role3=user:create

解读:user:create为我们的权限标示,表达:资源:操作:实例。因为我们这里默认是有实例。其实应该是:user:create:*  当然也可以真的某一个实例:user:create:01
    ycy=111,role1 逗号第一位为我们的凭证(密码),后面为角色。

2.2编写测试程序

编写权限认证不要忘记用户认证
程序里面只多了个permitted(权限)或者hasRole(角色),其他的与我们用户认证是一样的。

package com.ycy.test;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.config.IniSecurityManagerFactory;import org.apache.shiro.mgt.*;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.Factory;import org.junit.Test;import java.util.ArrayList;import java.util.Arrays;/** * Created by Administrator on 2015/10/16 0016. * 权限授权 */public class authorizationTest {    @Test    public void testAuthorization(){        //创建securityManager工厂        Factory<SecurityManager> securityManagerFactory=new IniSecurityManagerFactory("classpath:shiro-permission.ini");        //获取security        SecurityManager securityManager=securityManagerFactory.getInstance();        //蒋securityManager加入运行坏境        SecurityUtils.setSecurityManager(securityManager);        //建立subject        Subject subject=SecurityUtils.getSubject();        //创建用户令牌        UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("ycy","111");        //先认证        subject.login(usernamePasswordToken);        System.out.println("用户时候通过认证:" + subject.isAuthenticated());        //再权限授权验证(单个)         Boolean isPermittedOne=  subject.isPermitted("user:create");        System.out.println("单个权限认证:"+isPermittedOne);        //授权验证权限(多个)        Boolean isPermittedAll=subject.isPermittedAll("user:create", "user:update");        System.out.println("多个权限认证:" + isPermittedOne);        //另外也可以角色验证权限(不建议)        Boolean ishasRole=   subject.hasRole("role1");        Boolean ishasRoleAll=  subject.hasAllRoles(Arrays.asList("role1","role2"));        System.out.println("单个角色验证:"+ishasRole+"|多个角色验证"+ishasRoleAll);    }}


三、shrio权限授权(自定义realm)

1、自定义realm

package com.ycy.realm;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 java.util.ArrayList;import java.util.List;/** * Created by Administrator on 2015/10/15 0015. * 自定义数据源 */public class CustomRealm extends AuthorizingRealm{    //用户认证    @Override    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {       //authenticationToken为用户输入信息        String userCode=(String)authenticationToken.getPrincipal();        //模拟数据库操作查询用户        if(!userCode.equals("ycy")){            return null;        }        //查询密码为111        String password="111";        SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(userCode,password,"customRealm");        return info;    }    //用户授权    @Override    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {         //获取身份信息Principal        //这里的值跟我们用户认证的时候SimpleAuthenticationInfo一样        String usercode=(String)principalCollection.getPrimaryPrincipal();        //查询数据库。。。。        //模拟查询到数据        List<String> permission=new ArrayList<String>();        permission.add("user:create");        permission.add("items:add");        //..................        //查询全选数据,返回授权信息        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();        //增加权限信息        simpleAuthorizationInfo.addStringPermissions(permission);        return simpleAuthorizationInfo;    }}

2、编写ini程序

#用户信息配置[main]#自定义realmcutomRealm= com.ycy.realm.CustomRealm#自定义realm注入到securityManager中(标签语言)securityManager.realms=$cutomRealm


3、测试自定义授权

//自定义权限realm信息        //用户登录和退出(自定义realm)        @Test        public void testCustomRealm(){            //创建一个securityManager 通过ini文件创建            Factory<SecurityManager> securityManagerFactory=new IniSecurityManagerFactory("classpath:shrio-realm.ini");    //        XMLSecurityManager            //创建SecurityManager            SecurityManager securityManager=  securityManagerFactory.getInstance();            //将SecurityManager创建到生成环境中            SecurityUtils.setSecurityManager(securityManager);            //从SecurityUtils 构建一个subject            org.apache.shiro.subject.Subject subject=SecurityUtils.getSubject();            //认证提交认证token            UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken("ycy","111");            //执行认证提交认证            try {                subject.login(usernamePasswordToken);            }catch(AuthenticationException ex){                ex.printStackTrace();            }            System.out.println("是否通过认证:" + subject.isAuthenticated());            //授权。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。            //单个权限授权            boolean ispermitted=subject.isPermitted("user:create");            //多个权限授权            boolean ispermittedAll=subject.isPermittedAll("user:create","items:add");                System.out.println("单个授权:"+ispermitted+"|多个授权"+ispermittedAll);            //退出            subject.logout();        }

四、授权流程总结

1、对subject进行授权,调用的方法ispermitted("permission");括号里面为权限串:user:create
2、securityManager执行授权,通过ModularRealmAuthorize执行授权
3、ModularRealmAuthorizer执行realm从数据源查询数据 (调用doGetAuthorizationInfo)
4、ModularRealmAuthorizer(授权器)调用PermissionResolve(权限解析器)进行全新串对比
5、对比之后,ispermitted中的permission串与realm查询的串对比,无权限则抛出异常。有权限则通过授权。

注意:这个授权器modularRealmAuthorize跟我们的ModularRealmAuthenticator很像,做的事情也是从realm查询对比,但是功能不一样的:
ModularRealmAuthorizer 返回:SimpleAuthenticationInfo  认证信息
ModularRealmAuthenticator返回:simpleAuthorizationInfo权限信息


 

0 0
原创粉丝点击