说真的用spring boot 集成集成Hibernate+Shiro+Ehcache。费了我老大的功夫啊。
但这一切都是值得。
1. 首先第一点,以前用xml配置shiro的,将失效。错误的说法,可以使用xml。
2. 以前xml中配置的bean,请在加@Configuration注解的类中定义方法并加上注解
@Bean,最好写上name属性,不然以方法名命名bean的名字
下面开始配置吧。
第一: 集成hibernate。这一步骤,http://blog.csdn.net/u011998835/article/details/78369721已经介绍了。但是我稍微做一下修改。
@EnableTransactionManagement @EnableCaching @SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
这里不再定义SessionFactory的注入了。改成下面的方式
package com.dashuai.springboot.config; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManagerFactory; @Configuration public class SessionFactoryConfig { @Autowired private EntityManagerFactory entityManagerFactory; @Bean(name="SessionFactory") public SessionFactory getSessionFactory() { if (entityManagerFactory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } return entityManagerFactory.unwrap(SessionFactory.class); } }
还有就是我一直忽略的问题,这里补充一下,就是Druid数据源监控页面并没有配置。
这里新增一下。
package com.dashuai.springboot.config; import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class DruidConfig { @Bean public ServletRegistrationBean druidStatView() { ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet()); registration.addUrlMappings("/druid/*"); return registration; } @Bean public FilterRegistrationBean druidWebStatFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(new WebStatFilter()); registration.addInitParameter("exclusions","/css/*,/style/*,/js/*,*.js,*.css,/druid*,/attached/*,*.jsp"); registration.addInitParameter("principalSessionName","sessionUser"); registration.addInitParameter("profileEnable","true"); registration.addUrlPatterns("/*"); registration.setOrder(1); return registration; } }这里@Bean我没有给name属性赋值,那么它的值就是 方法名字
其实上述代码就是以前web.xml中配置的如下代码的转换
<!-- //阿里巴巴数据连接池 Druid的监控/// -->
<filter>
<filter-name>druidWebStatFilter</filter-name>
<filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>
/css/*,/style/*,/js/*,*.js,*.css,/druid*,/attached/*,*.jsp
</param-value>
</init-param>
<init-param>
<param-name>principalSessionName</param-name>
<param-value>sessionUser</param-value>
</init-param>
<init-param>
<param-name>profileEnable</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>druidWebStatFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- //druid监控页面,使用${pageContext.request.contextPath}/druid/index.html访问/ -->
<servlet>
<servlet-name>druidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>druidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
上面的集成完毕之后,解析来集成shiro。
以前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.shiro.SystemUserRealm" />
<bean id="normalUserRealm" class="com.dashuai.shiro.NormalUserRealm" />
<!-- FormAuthenticationFilter -->
<bean id="systemAuthFilter" class="com.dashuai.shiro.SystemFormAuthFilter" >
<property name="loginUrl" value="/admin/login.html" />
<property name="successUrl" value="/admin/index.html" />
</bean>
<bean id="normalAuthFilter" class="com.dashuai.shiro.NormalFormAuthFilter" >
<property name="loginUrl" value="/login.html" />
<property name="successUrl" value="/index.html" />
</bean>
<bean id="defineModularRealmAuthenticator" class="com.dashuai.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>
/res_admin/**=anon
/res_front/**=anon
/plugins/**=anon
/login.html=anon
/admin/login.*=anon
/admin/**=authsys
/user/**=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>
但是用springboot 就不能这样写了。应慢慢修改成对应下面的java代码,我也是很辛苦的一一对应的写上的。
package com.dashuai.springboot.config; import com.dashuai.springboot.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");// 不可以加这个,否则/admin/login.*失效 filterChainDefinitionMap.put("/user/**", "authnor"); filterChainDefinitionMap.put("/**"