zoukankan      html  css  js  c++  java
  • shiro认证管理

    1、认证

      身份认证就是判断一个用户是否为合法用户的处理过程。通过核对用户输入的用户名和口令,判断身份是否正确。

    2、shiro中认证关键对象

      subject:主体

    访问系统的用户,主体可以是用户、程序等,进行认证都称为主体。

      Principal:身份信息

    例如:是主体(subject)进行身份认证的标识,标识必须具有唯一性。一个主体可以有多个身份,例如可以用手机号、账号、邮箱进行账号密码登陆。

      Credential:凭证信息

    口令,只有主体自己知道的安全信息,例如,密码,证书等。

    3、认证流程

      登陆用户,携带身份和口令(凭证),将两种信息打包成一个令牌shirofilter进行拦截,将令牌拿到安全管理器中,调用认证器,认证器调用reaml获取数据库中数据,如果身份信息与口令与原始数据中的存留信息一致,就属于认证成功,放行进入系统,否则失败。

    4、认证开发

    4.1 引入依赖

    <!--编码处理  -->
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        </properties>
    <!--JDk版本的引入  -->
        <profiles>
          <profile>
            <id>development</id>
            <activation>
              <jdk>1.8</jdk>
              <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
              <maven.compiler.source>1.8</maven.compiler.source>
              <maven.compiler.target>1.8</maven.compiler.target>
              <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
            </properties>
          </profile>
        </profiles>
    <!--shiro包引入  -->
        <dependencies>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.5.3</version>
            </dependency>
        </dependencies>

    4.2 shiro.ini配置文件

      在resource目录下,该配置存放的本次认证的账号和密码。

    [users]
    zhangsan=123
    lisi=456
    wangwu=789

    4.3 认证代码

    package com.demo;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.mgt.DefaultSecurityManager;
    import org.apache.shiro.realm.text.IniRealm;
    import org.apache.shiro.subject.Subject;
    
    public class ShiroDemo {
        public static void main(String[] args) {
            //创建安全管理器
            DefaultSecurityManager defaultSecurityManager=new DefaultSecurityManager();
            //创建realm  读取配置文件中的用户名 密码
            defaultSecurityManager.setRealm(new IniRealm("classpath:shiro.ini"));
            //使用工具,将安装工具类中设置默认安全管理器
            SecurityUtils.setSecurityManager(defaultSecurityManager);
            //实用工具类获取登录主体
            Subject subject = SecurityUtils.getSubject();
            //创建令牌  用户名+密码  
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            try {
                System.out.println("认证状态:"+subject.isAuthenticated());
                subject.login(token);//用户登录   这里加入了用户登陆信息
                System.out.println("认证状态:"+subject.isAuthenticated());  //验证登陆信息
                System.out.println("登录成功!!");
            } catch (UnknownAccountException e) {   
                e.printStackTrace();
                System.out.println("用户名错误!!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("密码错误!!!");
            }   
        }   
    }

    其他认证异常

      DisabledAccountException(账号被禁用)

      LockedAccountException(账号被锁定)

      ExcessiveAttemptsException(登录失败次数过多)

      ExpiredCredentialsException(凭证过期)

    5、加盐认证

    md5工具,加入不同字符串数字后密码的强度

    package com.demo.md5;
    
    import org.apache.shiro.crypto.hash.Md5Hash;
    
    /**
     * 三种组合的md5加密
     * @author Administrator
     *
     */
    public class ShiroMD5 {
        public static void main(String[] args) {
            Md5Hash md5Hash=new Md5Hash("123");  //这个容易被反编译  安全性不高
            System.out.println(md5Hash.toHex());
            //md5+salt  md5加密+自定义字符串
            Md5Hash md5Hash2=new Md5Hash("123","x0*&p");
            System.out.println(md5Hash2.toHex());
            //md5+salt+hash散列
            Md5Hash md5Hash3=new Md5Hash("123","x0*&p",1024);
            System.out.println(md5Hash3.toHex());
        }
    }

    效果:

    202cb962ac59075b964b07152d234b70
    0ea1434575ac41da89b2335d8dde11e1
    efe2cdcad63be25838e3847becd43df4   

      自定义CustomerRealm类中,需要继承AuthorizingRealm类,进行登陆账号、密码、盐salt的定义,当然真实情况,账号密码应该从数据库中获取。salt应该作为随机字符串变量存在。

    package com.demo.md5;
    
    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.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.apache.shiro.util.ByteSource;
    
    /**
     * 自定义md5+salt realm
     */
    public class CustomerRealm extends AuthorizingRealm {
        //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            return null;
        }
        //认证方法
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            //获取身份信息
            String principal = (String) token.getPrincipal();
            //这里的zhangsan就是数据查出来的,模拟   这里的账号、密码按道理是在数据库的变量
            if("zhangsan".equals(principal)){
                String password = "efe2cdcad63be25838e3847becd43df4";
                String salt = "x0*&p";    //自定义加盐
                //数据库的用户名
                //数据库md5+salt之后的密码
                //注册时的随机盐
                //realm的名字
                return new SimpleAuthenticationInfo(principal,password, 
                                                    ByteSource.Util.bytes(salt),this.getName());
            }
            return null;
        }
    }

    测试类

    package com.demo.md5;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.mgt.DefaultSecurityManager;
    import org.apache.shiro.subject.Subject;
    
    public class TestAuthenticatorCusttomerRealm {
        public static void main(String[] args) {
            //创建securityManager
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            //IniRealm realm = new IniRealm("classpath:shiro.ini");
            //设置为自定义realm获取认证数据
            CustomerRealm customerRealm = new CustomerRealm();
            //设置md5加密
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");  //添加加密字符串
            credentialsMatcher.setHashIterations(1024);//设置散列次数   打乱顺序
            customerRealm.setCredentialsMatcher(credentialsMatcher); //在customerRealm设置加密后的密码验证器//设置自定义realm
            defaultSecurityManager.setRealm(customerRealm);  //将自定义的realm设置到安全管理中
            //将安装工具类中设置默认安全管理器
            SecurityUtils.setSecurityManager(defaultSecurityManager);  //将安全管理设置到安全工具中
            //获取主体对象   
            Subject subject = SecurityUtils.getSubject();  
            //创建token令牌
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            try {
                //subject对象 中方法  +加盐 +验证+权限操作
                subject.login(token);//用户登录,shiro会自动将token中的password在自定义realm中加上盐去处理
                System.out.println("登录成功~~");
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("用户名错误!!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("密码错误!!!");
            }
        }
    }

    6、授权认证

      CustomerRealm类中添加可放通的角色role,添加可访问资源"user:*:01"。

    package com.demo.grant;
    
    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;
    //授权领域
    public class CustomerRealm extends AuthorizingRealm {
        //授权方法
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //获取主要身份
            String primaryPrincipal = (String) principals.getPrimaryPrincipal();
            System.out.println("primaryPrincipal = " + primaryPrincipal);
            //根据身份信息  用户名   获取当前用户的角色信息,以及权限信息   xiaochen admin  user
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            //将模拟数据库中查询角色信息赋值给权限对象
            simpleAuthorizationInfo.addRole("admin");
            simpleAuthorizationInfo.addRole("user");
            //将数据库中查询权限信息赋值给权限对象
            //对用户下01实例具有所有权限   这是资源路径实例
            simpleAuthorizationInfo.addStringPermission("user:*:01");
            //对product下一切资源实例具有创建权限,*可以省略
            simpleAuthorizationInfo.addStringPermission("product:create");
    
            return simpleAuthorizationInfo;
        }
    
        //认证方法
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            String principal = (String) token.getPrincipal();
            if("zhangsan".equals(principal)){
            //模拟数据库中已经md5加盐处理过的密码 String password
    = "efe2cdcad63be25838e3847becd43df4"; String salt = "x0*&p"; //需要这个解开密码 return new SimpleAuthenticationInfo(principal,password, ByteSource.Util.bytes(salt),this.getName()); } return null; } }

    测试类

    package com.demo.md5;
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.IncorrectCredentialsException;
    import org.apache.shiro.authc.UnknownAccountException;
    import org.apache.shiro.authc.UsernamePasswordToken;
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
    import org.apache.shiro.mgt.DefaultSecurityManager;
    import org.apache.shiro.subject.Subject;
    
    public class TestAuthenticatorCusttomerRealm {
        public static void main(String[] args) {
            //创建securityManager
            DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
            //IniRealm realm = new IniRealm("classpath:shiro.ini");
            //设置为自定义realm获取认证数据
            CustomerRealm customerRealm = new CustomerRealm();
            //设置md5加密
            HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
            credentialsMatcher.setHashAlgorithmName("MD5");  //添加加密字符串
            credentialsMatcher.setHashIterations(1024);//设置散列次数   打乱顺序
            customerRealm.setCredentialsMatcher(credentialsMatcher); //MD5加密器//设置自定义realm
            defaultSecurityManager.setRealm(customerRealm);  //将自定义的realm设置到安全管理中
            //将安装工具类中设置默认安全管理器
            SecurityUtils.setSecurityManager(defaultSecurityManager);  //将安全管理设置到安全工具中
            //获取主体对象   
            Subject subject = SecurityUtils.getSubject();  
            //创建token令牌
            UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
            try {
                //subject对象 中方法  +加盐 +验证+权限操作 主体对象调用login方法
                subject.login(token);//用户登录,shiro会自动将token中的password在自定义realm中加上盐去处理
                System.out.println("登录成功~~");
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                System.out.println("用户名错误!!");
            }catch (IncorrectCredentialsException e){
                e.printStackTrace();
                System.out.println("密码错误!!!");
            }
    
        }
    }

      

  • 相关阅读:
    矩阵树定理 / 生成树计数
    NC20811 蓝魔法师 (树形DP/树上01背包)
    Xor-MST学习/ 2020牛客暑假多校(五)B.Graph
    HDU-6820 Tree (2020杭电多校(五) 1007)
    Flipping Coins (概率DP)
    宝石装箱 容斥+dp
    Rabbit的工作(1) (dP)
    Codeforces-1350 E.Orac and Game of Life
    HDU-6563 Strength (贪心)
    HDU-6558 The Moon (期望DP)
  • 原文地址:https://www.cnblogs.com/HelloM/p/14154258.html
Copyright © 2011-2022 走看看