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); } }