美文网首页Java web
shiro初体验,蹒跚学步

shiro初体验,蹒跚学步

作者: Ktry | 来源:发表于2020-02-29 21:27 被阅读0次

    1-登录登出

    • shiro.ini
    [users]
    zhangsan=666
    lisi=456
    
    • ShiroTest
    @Test
    public void testLogin() throws Exception{
        //创建工厂对象,加载配置文件
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro.ini");
        //通过工厂对象创建securityManager对象
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
        //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前登录的主体(此时主体未认证)
        Subject subject = SecurityUtils.getSubject();
        //收集主体登录的数据(账号密码)
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
        //登录操作
        try {
            subject.login(token);
        }catch (Exception e){
            //登录失败
            e.printStackTrace();
        }
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
        //登出操作
        subject.logout();
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
    }
    
    
    • 异常解析
    UnknownAccountException====>账号有误
    IncorrectCredentialsException====> 密码有误
    

    2-自定义realm

    • 继承AuthorizingRealm,重写三个方法
    public class MyRealm extends AuthorizingRealm {
        @Override
        public String getName() {
            return "MyRealm";
        }
        //授权操作
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            return null;
        }
        //认证操作
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //token表示登录时封装的UsernamePasswordToken
            String usernam = (String) token.getPrincipal();
            //假设数据库找不到这个用户名
            if(!usernam.equals("zhangsan")){
                return null;
            }
            String password = "666";
            //simpleAuthenticationInfo表示realm登录比对信息,
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, getName());
            return simpleAuthenticationInfo;
        }
    }
    
    • 配置ini文件,指定使用自定义realm
    myRealm= com.wu.realm.MyRealm
    securityManager.realms=$myRealm
    
    • 加载配置文件,执行登录操作
    @Test
    public void testLoginByRealm() throws Exception{
        //创建工厂对象,加载配置文件
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
        //通过工厂对象创建securityManager对象
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
        //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前登录的主体(此时主体未认证)
        Subject subject = SecurityUtils.getSubject();
        //收集主体登录的数据(账号密码)
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
        //登录操作
        try {
            subject.login(token);
        }catch (Exception e){
            e.printStackTrace();
            //登录失败
        }
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
        //登出操作
        subject.logout();
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
    }
    

    3-加密realm

    • 使用MD5散列
    @Test
    public void testMD5(){
        //模拟未加密的密码
        String password = "666";
        //使用MD5散列后的结果
        Md5Hash md5Hash = new Md5Hash(password);
        //使用MD5加盐散列后的结果
        md5Hash = new Md5Hash(password,"zhangsan");
        //使用MD5加盐散列3次后的结果
        md5Hash = new Md5Hash(password,"zhangsan",3);
        //输出结果  cd757bae8bd31da92c6b14c235668091
        System.out.println(md5Hash);
    }
    
    • 新建realm,继承AuthorizingRealm,重写三个方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
       //token表示登录时封装的UsernamePasswordToken
       String usernam = (String) token.getPrincipal();
    
       //假设数据库找不到这个用户名
       if(!usernam.equals("zhangsan")){
           return null;
       }
       //模拟数据库中加密之后的密码
       String password = "cd757bae8bd31da92c6b14c235668091";
       //simpleAuthenticationInfo表示realm登录比对信息  ----------加上盐值
       SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
       return simpleAuthenticationInfo;
    }
    
    • 配置ini文件,指定使用自定义realm
    [main]
    #定义密码凭证器
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    #设置散列算法
    credentialsMatcher.hashAlgorithmName=md5
    #设置散列次数
    credentialsMatcher.hashIterations=3
    #将凭证匹配器设置到realm
    myRealm= com.wu.realm.PasswordRealm
    myRealm.credentialsMatcher=$credentialsMatcher
    securityManager.realms=$myRealm
    
    • 加载配置文件,执行登录操作
    @Test
    public void testLoginByPasswordRealm() throws Exception{
        //创建工厂对象,加载配置文件
        IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography.ini");
        //通过工厂对象创建securityManager对象
        SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
        //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
        SecurityUtils.setSecurityManager(securityManager);
        //创建当前登录的主体(此时主体未认证)
        Subject subject = SecurityUtils.getSubject();
        //收集主体登录的数据(账号密码)
        UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
        //登录操作
        try {
            subject.login(token);
        }catch (Exception e){
            e.printStackTrace();
            //登录失败
        }
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
        //登出操作
        subject.logout();
        //判断是否登录成功
        System.out.println(subject.isAuthenticated());
    }
    

    4-权限

    • 继承AuthorizingRealm,重写三个方法
    @Override
    public String getName() {
        return "SuRealm";
    }
    
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //获取前端传来的用户名
        String userName = (String) principals.getPrimaryPrincipal();
        //通过用户名去数据库查询其权限(省略------ 。。。。模拟数据)
        Set<String> perms = new HashSet<String>();
        perms.add("user:add");
        perms.add("user:modify");
        perms.add("user:delete");
        //通过用户名去数据库查询其角色(省略------ 。。。。模拟数据)
        Set<String> roles = new HashSet<String>();
        roles.add("administrator");
        roles.add("seller");
        roles.add("buyer");
    
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(roles);
        simpleAuthorizationInfo.setStringPermissions(perms);
        return simpleAuthorizationInfo;
    }
    
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //token表示登录时封装的UsernamePasswordToken
        String usernam = (String) token.getPrincipal();
    
        //假设数据库找不到这个用户名
        if(!usernam.equals("zhangsan")){
            return null;
        }
        //模拟数据库中加密之后的密码
        String password = "cd757bae8bd31da92c6b14c235668091";
        //simpleAuthenticationInfo表示realm登录比对信息,
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usernam, password, ByteSource.Util.bytes("zhangsan"), getName());
        return simpleAuthenticationInfo;
    }
    
    • 配置ini文件,指定使用自定义realm
    [main]
    #定义密码凭证器
    credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
    #设置散列算法
    credentialsMatcher.hashAlgorithmName=md5
    #设置散列次数
    credentialsMatcher.hashIterations=3
    #将凭证匹配器设置到realm
    myRealm= com.wu.realm.SuRealm
    myRealm.credentialsMatcher=$credentialsMatcher
    securityManager.realms=$myRealm
    
    • 执行登录操作,测试权限

      1,代码实现

      @Test
      public void testLoginByPasswordRealm() throws Exception{
          //创建工厂对象,加载配置文件
          IniSecurityManagerFactory iniSecurityManagerFactory = new IniSecurityManagerFactory("classpath:shiro-cryptography-su.ini");
          //通过工厂对象创建securityManager对象
          SecurityManager securityManager = iniSecurityManagerFactory.getInstance();
          //将securityManager绑定到当前运行环境中,让系统随时随地都可以访问securityManager对象
          SecurityUtils.setSecurityManager(securityManager);
          //创建当前登录的主体(此时主体未认证)
          Subject subject = SecurityUtils.getSubject();
          //收集主体登录的数据(账号密码)
          UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","666");
          //登录操作
          try {
              subject.login(token);
          }catch (Exception e){
              e.printStackTrace();
              //登录失败
          }
          //判断是否登录成功
          System.out.println(subject.isAuthenticated());
      
          //测试权限      需求:输出"hello",需要"user:add"权限
          if(subject.isPermitted("user:add")){
              System.out.println("hello");
          }else {System.out.println("没有权限");}
          //表示一个个判断,返回bool数组
          boolean[] booleans = subject.isPermitted("","","");
          subject.isPermitted(new ArrayList<Permission>());
      
          //测试角色      判断是否具有某个角色
          subject.hasRole("");
          //一个一个判断,是否具有某个角色
          subject.hasRoles(new ArrayList<String>());
          //判断是否具有所有角色
          subject.hasAllRoles(new ArrayList<String>());
      
          //登出操作
          subject.logout();
          //判断是否登录成功
          System.out.println(subject.isAuthenticated());
      }
      

    ​ 2,注解实现

    @RequiresRoles("")
    public void test1(){}
    

    待续。。。

    相关文章

      网友评论

        本文标题:shiro初体验,蹒跚学步

        本文链接:https://www.haomeiwen.com/subject/nmamhhtx.html