上篇博客讲到 集成Hibernate+Shiro+Ehcache 很是麻烦对吧。这里我要讲的是shiro的配置直接使用xml配置。
先来回顾一下spring-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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<!-- Realm 域 授权和认证的判断 -->
<bean id="systemUserRealm" class="com.dashuai.dadminboot.shiro.SystemUserRealm" />
<bean id="normalUserRealm" class="com.dashuai.dadminboot.shiro.NormalUserRealm" />
<!-- FormAuthenticationFilter -->
<bean id="systemAuthFilter" class="com.dashuai.dadminboot.shiro.SystemFormAuthFilter" >
<property name="loginUrl" value="/admin/login.html" />
<property name="successUrl" value="/admin/index.html" />
</bean>
<bean id="normalAuthFilter" class="com.dashuai.dadminboot.shiro.NormalFormAuthFilter" >
<property name="loginUrl" value="/login.html" />
<property name="successUrl" value="/index.html" />
</bean>
<bean id="defineModularRealmAuthenticator" class="com.dashuai.dadminboot.shiro.DefautModularRealm">
<property name="definedRealms">
<map>
<entry key="systemAuthorizingRealm" value-ref="systemUserRealm" />
<entry key="normalAuthorizingRealm" value-ref="normalUserRealm" />
</map>
</property>
<property name="authenticationStrategy">
<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
</property>
</bean>
<!-- 安全认证过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="filters">
<map>
<entry key="authsys" value-ref="systemAuthFilter"></entry>
<entry key="authnor" value-ref="normalAuthFilter"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/login.html=anon
/admin/login.*=anon
/admin/**.html=authsys
/user/**.html=authnor
/**=anon
</value>
</property>
</bean>
<!-- 定义Shiro安全管理配置 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="memoryConstrainedCacheManager" />
<property name="authenticator" ref="defineModularRealmAuthenticator" />
<!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->
<!-- <property name="realm" ref="loginRealm"/> -->
<property name="realms" >
<list>
<ref bean="systemUserRealm" />
<ref bean="normalUserRealm"/>
</list>
</property>
<property name="sessionManager" ref="sessionManager" />
<property name="rememberMeManager" ref="rememberMeManager"/>
</bean>
<!-- 定义授权缓存管理器 -->
<bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
</bean>
<bean id="memoryConstrainedCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
<!-- 自定义会话管理配置 -->
<!-- 指定本系统SESSIONID, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID,
当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="sessionDAO" ref="sessionDAO" />
<!-- 会话超时时间,单位:毫秒 -->
<property name="globalSessionTimeout" value="1800000" />
<!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 -->
<property name="sessionValidationInterval" value="1800000" />
<property name="sessionValidationSchedulerEnabled" value="true" />
<property name="sessionIdCookie" ref="simpleCookie" />
<property name="sessionIdCookieEnabled" value="true" />
</bean>
<!-- 会话Cookie模板 -->
<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg name="name" value="shiro.sesssion"/>
<property name="path" value="/"/>
</bean>
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe"/>
<property name="httpOnly" value="true"/>
<property name="maxAge" value="604800"/><!-- 7天 -->
</bean>
<!-- rememberMe管理器 -->
<bean id="rememberMeManager"
class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey"
value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/>
<property name="cookie" ref="rememberMeCookie"/>
</bean>
<bean id="sessionDAO"
class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<property name="cacheManager" ref="shiroCacheManager" />
</bean>
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>
这里面所有缺失的类,请参见http://blog.csdn.net/u011998835/article/details/78379905
如果是使用java类的方式。
package com.dashuai.dadminboot.config;
import com.dashuai.dadminboot.shiro.*;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.DelegatingFilterProxy;
import javax.servlet.Filter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
@Bean(name = "systemAuthFilter")
public SystemFormAuthFilter getSystemFormAuthFilter() {
SystemFormAuthFilter formAuthFilter = new SystemFormAuthFilter();
formAuthFilter.setSuccessUrl("/admin/index.html");
formAuthFilter.setLoginUrl("/admin/login.html");
return formAuthFilter;
}
@Bean(name = "normalAuthFilter")
public NormalFormAuthFilter getNormalFormAuthFilter() {
NormalFormAuthFilter formAuthFilter = new NormalFormAuthFilter();
formAuthFilter.setSuccessUrl("/index.html");
formAuthFilter.setLoginUrl("/login.html");
return formAuthFilter;
}
@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());
Map<String, Filter> filters = new LinkedHashMap<>();
filters.put("authsys", getSystemFormAuthFilter());
filters.put("authnor", getNormalFormAuthFilter());
shiroFilterFactoryBean.setFilters(filters);
LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
filterChainDefinitionMap.put("/login.html", "anon");
filterChainDefinitionMap.put("/admin/login.*", "anon");
filterChainDefinitionMap.put("/admin", "authsys");
filterChainDefinitionMap.put("/admin/", "authsys");
filterChainDefinitionMap.put("/admin/**.html", "authsys");// 也就是说 这个配置请细致配置
filterChainDefinitionMap.put("/admin//**", "authsys");// 也就是说 这个配置请细致配置
filterChainDefinitionMap.put("/user/**", "authnor");
filterChainDefinitionMap.put("/**", "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setCacheManager(getMemoryConstrainedCacheManager());
securityManager.setAuthenticator(getDefautModularRealm());
ArrayList<Realm> list = new ArrayList<>();
list.add(getSystemUserRealm());
list.add(getNormalUserRealm());
securityManager.setRealms(list);
securityManager.setSessionManager(getDefaultWebSessionManager());
securityManager.setRememberMeManager(getCookieRememberMeManager());
return securityManager;
}
@Bean(name = "memoryConstrainedCacheManager")
public MemoryConstrainedCacheManager getMemoryConstrainedCacheManager() {
MemoryConstrainedCacheManager manager = new MemoryConstrainedCacheManager();
return manager;
}
@Bean(name = "defineModularRealmAuthenticator")
public DefautModularRealm getDefautModularRealm() {
DefautModularRealm realm = new DefautModularRealm();
Map<String, Object> definedRealms = new HashMap<>();
definedRealms.put("systemAuthorizingRealm", getSystemUserRealm());
definedRealms.put("normalAuthorizingRealm", getNormalUserRealm());
realm.setDefinedRealms(definedRealms);
realm.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
return realm;
}
@Bean(name = "systemUserRealm")
public SystemUserRealm getSystemUserRealm() {
SystemUserRealm realm = new SystemUserRealm();
return realm;
}
@Bean(name = "normalUserRealm")
public NormalUserRealm getNormalUserRealm() {
NormalUserRealm realm = new NormalUserRealm();
return realm;
}
@Bean(name = "webSessionManager")
public DefaultWebSessionManager getDefaultWebSessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(getEnterpriseCacheSessionDAO());
sessionManager.setGlobalSessionTimeout(1800000);
sessionManager.setSessionValidationInterval(1800000);
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setSessionIdCookie(getSimpleCookie());
return sessionManager;
}
@Bean(name = "sessionDAO")
public EnterpriseCacheSessionDAO getEnterpriseCacheSessionDAO() {
EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
sessionDAO.setCacheManager(getEhCacheManager());
return sessionDAO;
}
@Bean(name = "shiroCacheManager")
public EhCacheManager getEhCacheManager() {
EhCacheManager em = new EhCacheManager();
em.setCacheManagerConfigFile("classpath:ehcache.xml");
return em;
}
@Bean(name = "simpleCookie")
public SimpleCookie getSimpleCookie() {
SimpleCookie simpleCookie = new SimpleCookie("shiro.sesssion");
simpleCookie.setPath("/");
return simpleCookie;
}
@Bean(name = "rememberMeManager")
public CookieRememberMeManager getCookieRememberMeManager() {
CookieRememberMeManager meManager = new CookieRememberMeManager();
meManager.setCipherKey(org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
meManager.setCookie(getRememberMeCookie());
return meManager;
}
@Bean(name = "rememberMeCookie")
public SimpleCookie getRememberMeCookie() {
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
simpleCookie.setMaxAge(604800); // 7天
return simpleCookie;
}
// 加上会导致 Could not obtain transaction-synchronized Session for current thread异常
// @Bean(name = "lifecycleBeanPostProcessor")
// public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
// return new LifecycleBeanPostProcessor();
// }
@Bean
public FilterRegistrationBean shiroFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean(new DelegatingFilterProxy());
registration.setAsyncSupported(true);
registration.addInitParameter("targetFilterLifecycle","true");
registration.addUrlPatterns("/*");
registration.setOrder(20);
return registration;
}
}
如果是xml的方式是这样的。
package com.dashuai.dadminboot.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.filter.DelegatingFilterProxy;
@Configuration
@ImportResource("classpath:spring-shiro.xml")
public class ShiroConfigFromXML {
@Bean
public FilterRegistrationBean shiroFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean(new DelegatingFilterProxy());
registration.setAsyncSupported(true);
registration.addInitParameter("targetFilterLifecycle","true");
registration.addUrlPatterns("/*");
registration.setOrder(2);
return registration;
}
}
显然 如果 你以前有xml的配置,你肯定懒得写java的配置了。所以 可以考虑导入xml的配置。而且,java的配置,不要@Bean LifecycleBeanPostProcessor,否则一定异常Could not obtain transaction-synchronized Session for current thread。虽然我是不懂原因啦。xml的配置,好像你加上 LifecycleBeanPostProcessor也没有问题,不知道为什么。但xml配置,我一开始尝试为什么觉得不行呢,还是url拦截的问题,不要拦截的那么满,就是/**之类的,请细致的配置。