shiro学习笔记:简单的入门,盐值加密

一些理论知识:

https://blog.csdn.net/zifengye520/article/details/121969099

一、基本使用

官网的入门案例,使用的是ini配置文件来模拟用户的信息,这里直接跳过这个步骤,直接使用自定义的Realm来模拟数据库获取用户信息

1、创建一个springboot项目

2、添加shiro依赖

<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-core</artifactId>
  <version>1.5.3</version>
</dependency>

3、自定义Realm,继承AuthorizingRealm,模拟从数据库卡获取用户信息

public class MyRealm extends AuthorizingRealm {
    @Override
    //实现授权
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    @Override
    //实现认证
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //如果输入的是test,表示这个用户存在
        if(principal.equals("test")){
            //返回一个假数据,模拟从数据库取出:test|123
            return new SimpleAuthenticationInfo("test","123",getName());
        }
        return null;
    }
}

4、创建测试类,执行main方法,模拟用户登录

public class MyReamTest {
    public static void main(String[] args) {
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        //设置realm为自定义的MyRealm
        securityManager.setRealm(new MyRealm());
        //给安全工具类,设置安全管理器
        SecurityUtils.setSecurityManager(securityManager);

        //从安全工具类中获取主体
        Subject subject = SecurityUtils.getSubject();
        //创建token
        UsernamePasswordToken token = new UsernamePasswordToken("test","123");

        try{
            //登录
            subject.login(token);
        }catch (UnknownAccountException e){
            System.out.println("登录账号不存在");
        }
        catch (IncorrectCredentialsException e){
            System.out.println("登录密码不正确");
        }
        //判断登录成功
        if(subject.isAuthenticated()){
            System.out.println("登录成功");
        }
    }
}

 5、通过修改代码中用户名test,或者密码123,可以看到后台打印出对应账号或密码错误的日志

二、基本流程

1、首先,自定义的Realm,继承了AuthorizingRealm 

2、在调用subject.login(token)的时候,通过断点调试,会一步一步执行到如下图中的方法

3、当info为null,就会调用自定义realm中的doGetAuthenticationInfo方法。 

三、密码加盐

1、同样自定义一个realm,并继承AuthorizingRealm

 在认证的方法doGetAuthenticationInfo中,返回SimpleAuthenticationInfo对象时,需要提供盐值

public class MySaltRealm extends AuthorizingRealm {
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String principal = (String) principalCollection.getPrimaryPrincipal();//主凭证,用来从数据库获取角色和权限等

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        info.addRoles(Arrays.asList("admin","user"));
        info.addStringPermissions(Arrays.asList("user:create"));

        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //test是模拟从数据库查出的账号,表示test账号存在数据库中
        if("test".equals(principal)){
            //894b3913a4a13b25dc6186d11835c209,是模拟从数据库查出的加密后的密码,该密码是经过MD5加密后的
            //加密方式:Md5Hash str = new Md5Hash("123","abc",1024);

            //参数:用户名、密码、盐值、realm名称
            //加上盐值的参数,shiro在验证密码的时候,会自动加上盐值
            return new SimpleAuthenticationInfo("test","894b3913a4a13b25dc6186d11835c209", ByteSource.Util.bytes("abc"),this.getName());
        }
        return null;
    }
}

2、写个测试类,模拟登录

要给realm设置一个凭证匹配器,并指定加密算法盐值散列次数

public class MySaltRealmTest {

    public static void main(String[] args) {
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();

        AuthorizingRealm myRealm = new MySaltRealm();
        //获取hash凭证匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //设置hash凭证匹配器使用的算法(MD5)
        credentialsMatcher.setHashAlgorithmName("md5");
        //如果使用散列(加密次数),则需要设置散列的次数:1024次
        credentialsMatcher.setHashIterations(1024);

        //给自定义的realm设置密码匹配器
        myRealm.setCredentialsMatcher(credentialsMatcher);

        //设置realm为自定义的realm
        defaultSecurityManager.setRealm(myRealm);

        SecurityUtils.setSecurityManager(defaultSecurityManager);

        UsernamePasswordToken token = new UsernamePasswordToken("test","123");

        Subject subject = SecurityUtils.getSubject();
        try{
            //认证
            subject.login(token);
        }catch (UnknownAccountException e){
            e.printStackTrace();
            System.out.println("账号出错");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码出错");
        }

        if(subject.isAuthenticated()){
            System.out.println("认证成功");
            //判断权限
            System.out.println("角色权限"+subject.hasRole("admin"));
            System.out.println("资源权限"+subject.isPermitted("user:*"));
        }
    }
}

3、通过修改登录方法中的账号和密码,看控制台打印出对应的信息

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值