shiro加密加盐

1、配置shiro.ini文件

#自定义配置
[main]
#配置凭证器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName=MD5
credentialsMatcher.hashIterations=3

#配置自定义ream,类似springioc
myReam=com.xiangwen.myream.MyReam
#设置自己的凭证器
myReam.credentialsMatcher=$credentialsMatcher


#将ream配置给安全管理器,类似spring di注入
securityManager.realm= $myReam

 2、增加Account类

package com.xiangwen.myream;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account {
    private String userName;
    private String password;
    private String salt;
}

  

3、自定MyReam

package com.xiangwen.myream;

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;
import java.util.ArrayList;
import java.util.List;

public class MyReam extends AuthorizingRealm {
    //认证
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        return null;
    }
    //授权
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //模拟数据库
        List<Account> dbAccount=new ArrayList<Account>();
        dbAccount.add(new Account("tom","869ea400ff7d9b10b69ff3758f18c183","aaa"));
        dbAccount.add(new Account("jack","869ea400ff7d9b10b69ff3758f18c183","aaa"));
        //获取登录的token账户信息
        Object logonAccount=token.getPrincipal();
        Account tmp=null;
        //如果数据库中没有这个账号,则返回null,抛出UnknownAccountException(msg)
        boolean flg=false;
        for( Account account:dbAccount){
            if(logonAccount.equals(account.getUserName())){
                tmp= (Account) account;
                flg=true;
            }
        }
        if(!flg){
            return null;
        }
        //获取盐,包装程bytesouce
        String salt=tmp.getSalt();
        ByteSource source=ByteSource.Util.bytes(salt);
        //如果有账号,shiro则会去匹配密码,如果密码不正确抛出IncorrectCredentialsException(msg)
        SimpleAuthenticationInfo simpinfo=new SimpleAuthenticationInfo(tmp,tmp.getPassword(),source,this.getName());
        return simpinfo;
    }
}

 4、测试

package com.xiangwen.test;

import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
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 org.apache.shiro.util.Factory;


public class ShiroTest {
    public static void main(String[] args) {
        //1、读取配置文件,创建安全管理器:SecurityManager
        IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager=factory.createInstance();
        //2、将工厂对象和当前线程绑定
        SecurityUtils.setSecurityManager(securityManager);
        //3、从当前线程获取主体对象
        Subject subject=SecurityUtils.getSubject();

        //5、判断是否认证
        boolean authentic=subject.isAuthenticated();
        System.out.println("认证前:"+authentic);
        //6、开始认证
        if(!authentic){
            //4、创建token令牌:封装身份(账号)和凭证(密码)
            AuthenticationToken token=new UsernamePasswordToken("tom","1234");

            try {
                subject.login(token);
                authentic=subject.isAuthenticated();
            }catch (UnknownAccountException e){
                System.out.println("无效账号");
            }catch (IncorrectCredentialsException e){
                System.out.println("无效密码");
            }
            System.out.println("认证后:"+authentic);

        }
        //7、获取认证信息
        Object person=subject.getPrincipal();
        System.out.println("person:"+person);
        //8、退出登录
        subject.logout();
        authentic=subject.isAuthenticated();
        System.out.println("退出认证后:"+authentic);
    }
}

  

posted @ 2021-06-28 21:07  傲云萧雨  阅读(119)  评论(0编辑  收藏  举报