如何将基于Shiro的加盐自定义Realm登录认证改写为长尾关键词?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1255个文字,预计阅读时间需要6分钟。
1. 代码:javaConfig + Shiro环境 + public class ConfigShiro { public void simpleDbConfig() { DefaultSecurityManager securityManager=new DefaultSecurityManager(); Realm realm=new MyRealm(); securityManager.setRealm(realm); SecurityUtils.setSe
public class ConfigShiro { public void simpleDbCOnfig(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); Realm realm = new MyRealm(); securityManager.setRealm(realm); SecurityUtils.setSecurityManager(securityManager); } } 2、代码:生成盐,存到数据库中,salt我们也存到数据库中,解密时会取出
public void saltTest(){ //所需加密的参数 即 密码 String pwd = "123"; //[盐] 一般为用户名 或 随机数 String salt = "shiro"; //加密次数 int hashIterations = 1; /*调用org.apache.shiro.crypto.hash.SimpleHash.SimpleHash(String algorithmName, Object source, Object salt, int hashIterations) * 构造方法实现盐值加密 String algorithmName 为加密算法 支持md5 base64 等*/ SimpleHash sh = new SimpleHash("md5", pwd, salt, hashIterations); //打印最终结果,或将其存入数据库 System.out.println(sh.toHex()); } 3、代码:MyRealm(加盐)
package com.amiu.shiro.chapter5;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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 com.amiu.mybatisTest.autoMybatis.SqlSessionHelper;
import com.amiu.shiro.db.User;
import com.amiu.shiro.db.UsersDao;
public class MyRealm extends AuthorizingRealm {
//操作数据库的类
@Autowired
RoleService roleService;
@Autowired
PermissionService permissionService;
@Autowired
UserDao userDao;
//设置盐解析,这里要和生成盐的设置相同,使用MD5,解密次数1次
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
//HashedCredentialsMatcher是shiro提供的解析盐的实现类
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(1);
super.setCredentialsMatcher(matcher);
}
//处理权限的,将角色Role和权限Permission存入shiro中
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// 获取当前登录对象
User user = (User) principals.getPrimaryPrincipal();
//查询拥有角色
Map
@Test public void saltLogin(){ new ConfigShiro().simpleDbCOnfig(); Subject subject = SecurityUtils.getSubject(); //页面用户“li”输入的密码是明文“123” UsernamePasswordToken token = new UsernamePasswordToken("li","123"); try { subject.login(token); } catch (UnknownAccountException unknownAccountEx) { //处理无此用户 }catch(IncorrectCredentialsException wrongPasswordEx){ //处理用户名或密码不正确 }catch(LockedAccountException lockedAccountEx){ //账户被锁定 } catch ( AuthenticationException ae ) { //不期望出现的错误 error? } Assert.assertTrue(subject.isAuthenticated()); } 5、解析:MyRealm
1、登陆测试中的: UsernamePasswordToken token = new UsernamePasswordToken("li","123"); 执行subject.login(token)后,这个token传到了MyRealm中的方法: //处理身份验证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 这里的参数(AuthenticationToken token)即是我们的登陆用户“li”的token 2、我们自定义的Realm,我们一般选择继承shiro的AuthorizingRealm。 3、MyRealm中的返回值: SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password.toCharArray(), byteSalt, getName()); SimpleAuthenticationInfo的第一个参数我么可以放入我们想要放入才参数,如这里的对象User,我们还能存入id 或Username等等,这个参数体现在本类处理权限的方法中: //处理权限 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) 这里的参数(PrincipalCollection principals)就是我们传入的对象User,我们可以这么使用它: User User = (User) principals.getPrimaryPrincipal(); 获取User对象后我们可以去数据库中查询权限信息,并加载到shiro中 6、解析:MyRealm中的重写方法setCredentialsMatcher()
@Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { super.setCredentialsMatcher(credentialsMatcher); } 1、CredentialsMatcher字面意思简单理解就是[用户匹配器],作用就是匹配密码,检查 [登录密码]是否等于[数据库中查询的密码] 2、CredentialsMatcher的默认实现是SimpleCredentialsMatcher,作用是简单匹配密码, 当匹配[登录密码:123],[数据库中查询的密码:123]时,才会成功。 当匹配[登录密码:123],[数据库中加密的密码:1f45e9afefc5e28edbcbdfae08a1f7a6]时, 是不会成功的;SimpleCredentialsMatcher作用其实也就是简单判等。 上面的setCredentialsMatcher()等同于: @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { SimpleCredentialsMatcher matcher = new SimpleCredentialsMatcher(); super.setCredentialsMatcher(matcher); } 3、当我们需要匹配加盐的密码时,就不能使用SimpleCredentialsMatcher了,我们一般使用 HashedCredentialsMatcher,HashedCredentialsMatcher可以匹配[登录明文密码]与[数据库加密密码] 但是我们必须为其指定匹配规则,也就是密码加密时的加密规则,HashedCredentialsMatcher将按照 此规则解密[数据库加密密码],然后再匹配[登录明文密码],如: @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("md5");//设置解密算法为:md5 matcher.setHashIterations(1);//设置解密次数为1次 super.setCredentialsMatcher(matcher); }
本文共计1255个文字,预计阅读时间需要6分钟。
1. 代码:javaConfig + Shiro环境 + public class ConfigShiro { public void simpleDbConfig() { DefaultSecurityManager securityManager=new DefaultSecurityManager(); Realm realm=new MyRealm(); securityManager.setRealm(realm); SecurityUtils.setSe
public class ConfigShiro { public void simpleDbCOnfig(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); Realm realm = new MyRealm(); securityManager.setRealm(realm); SecurityUtils.setSecurityManager(securityManager); } } 2、代码:生成盐,存到数据库中,salt我们也存到数据库中,解密时会取出
public void saltTest(){ //所需加密的参数 即 密码 String pwd = "123"; //[盐] 一般为用户名 或 随机数 String salt = "shiro"; //加密次数 int hashIterations = 1; /*调用org.apache.shiro.crypto.hash.SimpleHash.SimpleHash(String algorithmName, Object source, Object salt, int hashIterations) * 构造方法实现盐值加密 String algorithmName 为加密算法 支持md5 base64 等*/ SimpleHash sh = new SimpleHash("md5", pwd, salt, hashIterations); //打印最终结果,或将其存入数据库 System.out.println(sh.toHex()); } 3、代码:MyRealm(加盐)
package com.amiu.shiro.chapter5;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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 com.amiu.mybatisTest.autoMybatis.SqlSessionHelper;
import com.amiu.shiro.db.User;
import com.amiu.shiro.db.UsersDao;
public class MyRealm extends AuthorizingRealm {
//操作数据库的类
@Autowired
RoleService roleService;
@Autowired
PermissionService permissionService;
@Autowired
UserDao userDao;
//设置盐解析,这里要和生成盐的设置相同,使用MD5,解密次数1次
@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
//HashedCredentialsMatcher是shiro提供的解析盐的实现类
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
matcher.setHashIterations(1);
super.setCredentialsMatcher(matcher);
}
//处理权限的,将角色Role和权限Permission存入shiro中
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// 获取当前登录对象
User user = (User) principals.getPrimaryPrincipal();
//查询拥有角色
Map
@Test public void saltLogin(){ new ConfigShiro().simpleDbCOnfig(); Subject subject = SecurityUtils.getSubject(); //页面用户“li”输入的密码是明文“123” UsernamePasswordToken token = new UsernamePasswordToken("li","123"); try { subject.login(token); } catch (UnknownAccountException unknownAccountEx) { //处理无此用户 }catch(IncorrectCredentialsException wrongPasswordEx){ //处理用户名或密码不正确 }catch(LockedAccountException lockedAccountEx){ //账户被锁定 } catch ( AuthenticationException ae ) { //不期望出现的错误 error? } Assert.assertTrue(subject.isAuthenticated()); } 5、解析:MyRealm
1、登陆测试中的: UsernamePasswordToken token = new UsernamePasswordToken("li","123"); 执行subject.login(token)后,这个token传到了MyRealm中的方法: //处理身份验证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 这里的参数(AuthenticationToken token)即是我们的登陆用户“li”的token 2、我们自定义的Realm,我们一般选择继承shiro的AuthorizingRealm。 3、MyRealm中的返回值: SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password.toCharArray(), byteSalt, getName()); SimpleAuthenticationInfo的第一个参数我么可以放入我们想要放入才参数,如这里的对象User,我们还能存入id 或Username等等,这个参数体现在本类处理权限的方法中: //处理权限 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) 这里的参数(PrincipalCollection principals)就是我们传入的对象User,我们可以这么使用它: User User = (User) principals.getPrimaryPrincipal(); 获取User对象后我们可以去数据库中查询权限信息,并加载到shiro中 6、解析:MyRealm中的重写方法setCredentialsMatcher()
@Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { super.setCredentialsMatcher(credentialsMatcher); } 1、CredentialsMatcher字面意思简单理解就是[用户匹配器],作用就是匹配密码,检查 [登录密码]是否等于[数据库中查询的密码] 2、CredentialsMatcher的默认实现是SimpleCredentialsMatcher,作用是简单匹配密码, 当匹配[登录密码:123],[数据库中查询的密码:123]时,才会成功。 当匹配[登录密码:123],[数据库中加密的密码:1f45e9afefc5e28edbcbdfae08a1f7a6]时, 是不会成功的;SimpleCredentialsMatcher作用其实也就是简单判等。 上面的setCredentialsMatcher()等同于: @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { SimpleCredentialsMatcher matcher = new SimpleCredentialsMatcher(); super.setCredentialsMatcher(matcher); } 3、当我们需要匹配加盐的密码时,就不能使用SimpleCredentialsMatcher了,我们一般使用 HashedCredentialsMatcher,HashedCredentialsMatcher可以匹配[登录明文密码]与[数据库加密密码] 但是我们必须为其指定匹配规则,也就是密码加密时的加密规则,HashedCredentialsMatcher将按照 此规则解密[数据库加密密码],然后再匹配[登录明文密码],如: @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(); matcher.setHashAlgorithmName("md5");//设置解密算法为:md5 matcher.setHashIterations(1);//设置解密次数为1次 super.setCredentialsMatcher(matcher); }

