pom.xml
引入shiro和spring-shiro依赖:
<!--用于slf4j与log4j2保持桥接 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
工具类MD5Util
public class MD5Util {
// 散列次数
private static int hashIterations = 3;
// 内置salt
private static String public_salt = "958AEF84DB49419689159022A74D547E";
/**
* md5加密工具类
* @param source 要用共盐加密的字符串
* @return
*/
private static String md5_public_salt(String source) {
return new Md5Hash(source, public_salt, hashIterations).toString();
}
/**
*
* @param source 原始密码
* @param salt 私盐
* @return
*/
public static String md5_private_salt(String source,String salt) {
//1.先用共盐对原始密码加密
//md5_public_salt(source);
//2.再对加密的后密文用私盐加密一次
return new Md5Hash(md5_public_salt(source), salt, hashIterations).toString();
}
}
ShiroRealm
public class ShiroRealm extends AuthorizingRealm {
/**
* 登录认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 1.获取用户输入的用户名
String username = token.getUsername();
// 2.获取用户输入的密码
String password = new String(token.getPassword());
// 3.根据用户名去DB查询对应的用户信息
User user = new User("admin", "6f89a35fca3ed82005e9ec4ddabc8226", 0,"98C69A2446384F22B5EFC7874095AC69");
password = MD5Util.md5_private_salt(password,user.getSalt());
if (!user.getUsername().equals(username)) {
throw new UnknownAccountException("用户名不存在");
}
if (!user.getPassword().equals(password)) {
throw new CredentialsException("密码错误");
}
if (user.getStatus() == 1) {
throw new DisabledAccountException("账号被禁用");
}
if (user.getStatus() == 2) {
throw new LockedAccountException("账号被锁定");
}
System.out.println("认证成功...");
// 创建简单认证信息对象
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName());
return info;
}
/**
* 授权
* 将认证通过的用户的角色和权限信息设置到对应用户主体上
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = principals.getPrimaryPrincipal().toString();
//模拟从数据库获取当前用户的角色 通过用户名查询该用户拥有的角色名称
Set<String> roleNameSet = new HashSet<>();
roleNameSet.add("系统管理员");
//roleNameSet.add("系统运维");
//模拟从数据库获取当前用户的权限 通过用户名查询该用户拥有的权限名称
Set<String> permissionNameSet = new HashSet<>();
permissionNameSet.add("sys:user:list"); // 查看列表
permissionNameSet.add("sys:user:info"); // 查看用户详情
permissionNameSet.add("sys:user:create");// 创建用户
permissionNameSet.add("sys:user:update");// 修改用户
permissionNameSet.add("sys:user:delete");// 删除用户
// 简单授权信息对象,对象中包含用户的角色和权限信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roleNameSet);
info.addStringPermissions(permissionNameSet);
System.out.println("授权完成....");
return info;
}
}
shiro-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--自定义的relam-->
<bean name="shiroRelam" class="com.imcode.common.shiro.ShiroRealm"/>
<!--缓存管理器-->
<bean name="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"/>
<!--安全管理器-->
<bean name="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
<!--注入自定义relam-->
<property name="realm" ref="shiroRelam"/>
<!--注入缓存管理器-->
<property name="cacheManager" ref="cacheManager"/>
</bean>
<!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/>
<property name="arguments" ref="securityManager"/>
</bean>
<!-- Shiro生命周期处理器-->
<bean name="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>
spring-config.xml
在spring-config.xml
中引入shiro-config.xml
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
此处省略了spring mybaits 事务 配置
<!--导入shiro配置-->
<import resource="classpath:shiro-config.xml"/>
</beans>
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config.xml")
public class ShiroTest {
@Autowired
private SecurityManager securityManager;
@Test
public void test(){
String username = "admin";
//对密码进行加密
String password = MD5Util.md5("123456","ak47");
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
SecurityUtils.getSubject().login(token);
Subject subject = SecurityUtils.getSubject();
System.out.println(subject.hasRole("admin"));
System.out.println(subject.isPermitted("user:create222"));
// 退出登录
subject.logout();
}
}