本次缓存使用ehcache
pom.xml
<shiro.version>1.3.2</shiro.version>
<!-- Shiro依赖包 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-all</artifactId>
<version>${shiro.version}</version>
</dependency>
web.xml
开头加入spring文件。 spring-model.xml包括spring-model-shiro.xml spring-model-ehcache.xml spring-model.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring-model*.xml</param-value>
</context-param>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring-model-shiro.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" xmlns:util="http://www.springframework.org/schema/util"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<description>Shiro配置信息</description>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean>
<!--自定义Realm -->
<bean id="customRealm" class="com.common.MyRealm">
<!--启用缓存,默认 false-->
<!--<property name="cachingEnabled" value="true"/>-->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property> <!-- 加密算法的名称 -->
<property name="hashIterations" value="1024"></property> <!-- 配置加密的次数 -->
</bean>
</property>
</bean>
<!-- shiro封装cacheManager -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManager" ref="cacheManagerFactory" />
</bean>
<!-- Shiro 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="customRealm"></property>
<property name="cacheManager" ref="shiroCacheManager"></property>
</bean>
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"></property>
<property name="loginUrl" value="/login"></property>
<property name="filterChainDefinitions">
<value>
/callMBG = anon
/test/** = anon
/static/** = anon<!--资源路径-->
/css/** = anon<!--资源路径-->
/js/** = anon<!--资源路径-->
/scripts/** = anon<!--资源路径-->
/images/** = anon<!--资源路径-->
/login/** = anon<!--登录相关,包含登录页、验证码、请求等-->
/error/** = anon<!--错误提示页面-->
/** = authc<!--其他所有请求都走认证和防止重复登录的过滤器-->
</value>
</property>
</bean>
<!-- 启用Shiro的注解 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor"/>
<!-- 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,
并在必要时进行安全逻辑验证 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
</beans>
最关键部分,"com.common.MyRealm"
MyRealm.java
package com.common;
import com.dataSource.DataSourceEnum;
import com.dataSource.DataSourceHolder;
import com.entity.TPriResource;
import com.entity.TPriRole;
import com.entity.TPriUser;
import com.entity.TPriUserRoleRel;
import com.service.TPriResourceService;
import com.service.TPriRoleService;
import com.service.TPriUserRoleRelService;
import com.service.TPriUserService;
import com.util.JsonUtil;
import com.util.SessionUtil;
import com.util.StringUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList;
import java.util.List;
/**
* @Title:
* @Description:
* @Author:ChenZey
* @Company:
* @Create:2019-08-27 16:54
* @Version:V1.0
**/
public class MyRealm extends AuthorizingRealm {
protected Logger logger = LoggerFactory.getLogger(MyRealm.class);
@Autowired
private TPriUserService userService;
@Autowired
private TPriRoleService roleService;
@Autowired
private TPriResourceService tPriResourceService;
@Autowired
private TPriUserRoleRelService tPriUserRoleRelService;
// @Autowired
// private ResourceService resourceService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(SessionUtil.getRoles());//添加角色
info.addStringPermissions(SessionUtil.getResources());//添加按钮资源
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
DataSourceHolder.setDataSources(DataSourceEnum.RASDATA.getKey());
String userName = (String) token.getPrincipal();
TPriUser user = userService.getByUserName(userName);
if (user == null) {
// 没找到帐号
throw new UnknownAccountException();
} else {
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), getName());
System.out.println(JsonUtil.toJson(user));
//session中保存用户信息
SessionUtil.setAttribute("user", user);
//保存机构信息
/* Org org = orgService.getById(user.getOrgId());
SessionUtil.setAttribute("org", org);*/
//保存角色信息
TPriUserRoleRel tPriUserRoleRel = tPriUserRoleRelService.userRole(user.getUserId());
TPriRole tPriRole = roleService.tPriRole(tPriUserRoleRel.getRoleId());
List<String> roleStrs = new ArrayList<>();
roleStrs.add(tPriRole.getRoleCode());
SessionUtil.setAttribute("roles",roleStrs );
//保存资源信息
List<TPriResource> resources = null;
if ("admin".equals(user.getStaffName())){
resources = tPriResourceService.getAll();
}else{
resources = tPriResourceService.getResourceListByUserId(user.getUserId());
}
List<String> resourceStrs = new ArrayList<>();
for (TPriResource resource : resources) {
//permission 页面使用name中值 与数据库中该按钮注册存储值需一致。用法:
// -----------------------------------------------
// <shiro:hasPermission name="ht-function-test">
// <div class="icon" id="delete" title="测试" onclick="deleteRole()">
// <a><img src="${contextPath}/static/images/delete.png"
//onmouseover="this.src='${contextPath}/static/images/delete_a.png'"
//onmouseout="this.src='${contextPath}/static/images/delete.png'" /><span>删除</span></a>
// </div>
// </shiro:hasPermission>
// -------------------------------------------------
String permission = resource.getPermission();
//3为资源表按钮类型资源 此处存储按钮权限,用来结合JSP使用标签来解决权限验证
if ("3".equals(resource.getResourceType()) && StringUtils.isNotEmpty(permission)) {
resourceStrs.add(permission);
}
}
SessionUtil.setAttribute("resources", resourceStrs);
return authenticationInfo;
}
}
}
SessionUtil.java
package com.util;
import com.entity.TPriUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import java.util.List;
public class SessionUtil {
/**
* 获取Shiro 的 Session
*
* @return
*/
public static Session getSession() {
return SecurityUtils.getSubject().getSession();
}
/**
* 获取Session中的属性
*
* @param attributeName
* @return
*/
public static Object getAttribute(String attributeName) {
return SecurityUtils.getSubject().getSession().getAttribute(attributeName);
}
/**
* 设置Session属性
*
* @param attributeName
* @param attribute
*/
public static void setAttribute(String attributeName, Object attribute) {
SecurityUtils.getSubject().getSession().setAttribute(attributeName, attribute);
}
/**
* 获取当前登录用户
* @return
*/
public static TPriUser getUser() {
return (TPriUser) getAttribute("user");
}
/**
* 获取当前登录用户ID
* @return
*/
public static String getUserId() {
//判断当前登录用户是否存在
TPriUser user = getUser();
if(user == null){
return null;
}
return getUser().getUserId();
}
/**
* 获取当前登录用户名
* @return
*/
public static String getUsername() {
//判断当前登录用户是否存在
TPriUser user = getUser();
if(user == null){
return null;
}
return getUser().getUserName();
}
/**
* 获取当前登录用户IP
* @return
*/
public static String getIp() {
return getSession().getHost();
}
/**
* 返回当前用户的角色列表
* @return
*/
public static List<String> getRoles() {
return (List<String>) getSession().getAttribute("roles");
}
/**
* 返回当前用户的资源列表
* @return
*/
public static List<String> getResources() {
return (List<String>) getSession().getAttribute("resources");
}
}
spring-model-ehcache.xml 其中引用ehcache.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"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd
">
<description>EhCache配置信息</description>
<!--<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
<property name="shared" value="true"/>
</bean>-->
<!-- 启用缓存注解功能-->
<cache:annotation-driven cache-manager="springCacheManager"/>
<!-- spring 封装ehcache缓存管理器-->
<bean id="springCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"/>
</bean>
<!--缓存配置-->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
<!--创建工具类ApplicationUtil,以便普通class根据bean id动态获取spring管理的bean-->
<bean id="springContextHolder" class="com.common.spring.SpringContextHolder" />
<bean id="applicationUtil" class="com.common.ehcache.EHCacheUtils"></bean>
</beans>
ehcache.xml
<?xml version="1.1" encoding="UTF-8"?>
<ehcache updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<!-- <cache name="diskCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache> -->
<cache name="passwordRetryCache"
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="0"
overflowToDisk="false"
>
</cache>
<cache name="authorizationCache"
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="0"
overflowToDisk="false"
>
</cache>
<cache name="authenticationCache"
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="0"
overflowToDisk="false"
>
</cache>
<cache name="shiro-activeSessionCache"
maxElementsInMemory="2000"
eternal="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="0"
overflowToDisk="false"
>
</cache>
</ehcache>