项目结构如下:
Md5CustomerRealm.java
package com.xiangshuai.shiro.realmPasswordMatcher;
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.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
/**
* @author lqx ,密码用MD5 存在数据库--这里存在MAP中,并加盐
* @create 2019-03-06 22:47
*文件在
* E:\学习文档子目录压缩\框架\shiro\shiro安全框架入门\复习步骤6-获取权限数据CustomRealm提供subject桥梁 - 用集合用户权限角色等信息-shiro加密密码和盐存入数据库或map\shiro-test.rar
或 我的网盘/我的笔记/学习文档子目录压缩/框架/shiro/shiro安全框架入门/复习步骤6-获取权限数据CustomRealm提供subject桥梁 - 用集合用户权限角色等信息-shiro加密密码和盐存入数据库或map/shiro-test.rar
*/
public class Md5CustomerRealm extends AuthorizingRealm {
HashMap<String, String> upMap = new HashMap<>();
{
//构造代码块每次创建对象构造方法调用前都会被调用
//将"123456" MD5加密后放入Map中,本来应该将MD5密码放到数据库中的
Md5Hash md5password = new Md5Hash("123456","yan");//用密码 "123456"和盐 "yan" 计算出md5值存入数据库,这里存入map中
upMap.put("xiaomi",md5password.toString());
super.setName("customRealm");
}
//做权限用的 -- 将用户的权限验证对象返回
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获得用户名
String userName = (String) principalCollection.getPrimaryPrincipal();
//根据用户名获得 用户角色,用户权限,本来要从数据库中获取,这里测试直接从我们自己造的Set中获取
Set<String> permissions = getPermissionByUsername(userName);
Set<String> roles = getRolesByUsername(userName);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.setRoles(roles);
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;//将用户的权限验证对象返回
}
//做认证用的 -- 认证就是看用subject户名和密码在Realm是否存在 --将用户的认证对象AuthenticationInfo返回
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//从主体传过来的信息中获取用户名
String username= (String) authenticationToken.getPrincipal();
//根据用户名获得 密码,本来要从数据库中获取,这里测试直接从我们自己造的Map中获取
String password= getPasswordByUsername(username);
if(password==null){
return null;
}
//"customRealm" 是AuthorizingRealm中setName好的
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo("xiaomi", password, "customRealm");
//lqx --如果数据库中的 密码 存储有加盐操作,那么 authenticationInfo这个验证对象也要设置 盐
authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes("yan"));//这个 "yan"是和密码做为md5 做为盐的值
//lqx
return authenticationInfo;//将用户的认证对象AuthenticationInfo返回
}
public String getPasswordByUsername(String username){
String password = upMap.get(username);
return password;
}
public Set<String> getRolesByUsername(String username){
Set<String> roles = new HashSet<String>();
roles.add("admin");
roles.add("sjy");
return roles;
}
public Set<String> getPermissionByUsername(String username){
Set<String> permissions = new HashSet<String>();
permissions.add("user:select");
permissions.add("user:update");
return permissions;
}
}
Md5CustomRealmTest.java
package com.xiangshuai.shiro.realmPasswordMatcher; import org.apache.shiro.SecurityUtils; 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; import org.junit.Test; /** * <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>xiangshuai-shiro</artifactId> <groupId>com.xiangshuai</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>shiro-test</artifactId> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <!-- shiro核心包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <!--JdbcReals需从数据库获取数据 mysql连接驱动 --> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- JdbcReals需从数据库获取数据 数据库连接池 --> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> </dependencies> </project> * @author lqx * @create 2019-03-06 15:17 * 文件在 E:\学习文档子目录压缩\框架\shiro\shiro安全框架入门\复习步骤6-获取权限数据CustomRealm提供subject桥梁 - 用集合用户权限角色等信息-shiro加密密码和盐存入数据库或map\shiro-test.rar 或 我的网盘/我的笔记/学习文档子目录压缩/框架/shiro/shiro安全框架入门/复习步骤6-获取权限数据CustomRealm提供subject桥梁 - 用集合用户权限角色等信息-shiro加密密码和盐存入数据库或map/shiro-test.rar * */ public class Md5CustomRealmTest { @Test public void testCustomRealmTest(){ Md5CustomerRealm md5CustomerRealm = new Md5CustomerRealm(); //创建SecurityManger环境,添加自定义Reals到创建SecurityManger环境中 DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); //当数据库中的密码是加密数据时 --lqx //设置Realm密码 md5将密码从数据库或MAP中解密 HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();//加密匹配器 matcher.setHashAlgorithmName("md5");//加密算法名为md5 matcher.setHashIterations(1);//可选择多次--,这里设置加密次数为1--因为数据库存储的密码只被MD5加密一次 md5CustomerRealm.setCredentialsMatcher(matcher);//将加密对象设置进来 // 当数据库中的密码是加密数据时 --lqx defaultSecurityManager.setRealm(md5CustomerRealm); //主体Subject主动提交认证请求 SecurityUtils.setSecurityManager(defaultSecurityManager); Subject subject = SecurityUtils.getSubject(); // 给subject主体里面加 登录token UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("xiaomi","123456"); subject.login(usernamePasswordToken); //Reals 对subject和数据库(这里事模拟的)进行比对,看是否能通过验证 --true System.out.println("subject是否通过认证:"+subject.isAuthenticated()); System.out.println("subject是否通过认证:"+subject.hasRole("admin"));//subject是否有admin角色 subject.checkPermissions("user:select","user:update");//subject是否有"user:select","user:update"权限 } }