Nginx shiro redis 多tomcat共享session

pom.xml:

[html]  view plain  copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   <modelVersion>4.0.0</modelVersion>  
  4.   <groupId>com.sheng.webapp</groupId>  
  5.   <artifactId>redis_session</artifactId>  
  6.   <packaging>war</packaging>  
  7.   <version>1.0-SNAPSHOT</version>  
  8.   <name>redis_session Maven Webapp</name>  
  9.   <url>http://maven.apache.org</url>  
  10.   <properties>  
  11.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  12.     <spring.version>4.3.9.RELEASE</spring.version>  
  13.   </properties>  
  14.   <dependencies>  
  15.     <dependency>  
  16.       <groupId>junit</groupId>  
  17.       <artifactId>junit</artifactId>  
  18.       <version>4.12</version>  
  19.       <scope>test</scope>  
  20.     </dependency>  
  21.     <dependency>  
  22.       <groupId>org.springframework.session</groupId>  
  23.       <artifactId>spring-session-data-redis</artifactId>  
  24.       <version>1.1.1.RELEASE</version>  
  25.       <type>pom</type>  
  26.     </dependency>  
  27.     <!--Spring-->  
  28.     <dependency>  
  29.       <groupId>org.springframework</groupId>  
  30.       <artifactId>spring-context</artifactId>  
  31.       <version>${spring.version}</version>  
  32.     </dependency>  
  33.     <dependency>  
  34.       <groupId>org.springframework</groupId>  
  35.       <artifactId>spring-context-support</artifactId>  
  36.       <version>${spring.version}</version>  
  37.     </dependency>  
  38.     <dependency>  
  39.       <groupId>org.springframework</groupId>  
  40.       <artifactId>spring-tx</artifactId>  
  41.       <version>${spring.version}</version>  
  42.     </dependency>  
  43.     <dependency>  
  44.       <groupId>org.springframework</groupId>  
  45.       <artifactId>spring-web</artifactId>  
  46.       <version>${spring.version}</version>  
  47.     </dependency>  
  48.     <dependency>  
  49.       <groupId>org.springframework</groupId>  
  50.       <artifactId>spring-webmvc</artifactId>  
  51.       <version>${spring.version}</version>  
  52.     </dependency>  
  53.     <dependency>  
  54.       <groupId>org.springframework</groupId>  
  55.       <artifactId>spring-jdbc</artifactId>  
  56.       <version>${spring.version}</version>  
  57.     </dependency>  
  58.     <dependency>  
  59.       <groupId>org.springframework</groupId>  
  60.       <artifactId>spring-test</artifactId>  
  61.       <version>${spring.version}</version>  
  62.       <scope>test</scope>  
  63.     </dependency>  
  64.     <!---shiro相关-->  
  65.     <dependency>  
  66.       <groupId>org.apache.shiro</groupId>  
  67.       <artifactId>shiro-core</artifactId>  
  68.       <version>1.2.3</version>  
  69.     </dependency>  
  70.     <dependency>  
  71.       <groupId>org.apache.shiro</groupId>  
  72.       <artifactId>shiro-web</artifactId>  
  73.       <version>1.2.3</version>  
  74.     </dependency>  
  75.     <dependency>  
  76.       <groupId>org.apache.shiro</groupId>  
  77.       <artifactId>shiro-spring</artifactId>  
  78.       <version>1.2.3</version>  
  79.     </dependency>  
  80.     <dependency>  
  81.       <groupId>org.apache.shiro</groupId>  
  82.       <artifactId>shiro-ehcache</artifactId>  
  83.       <version>1.2.3</version>  
  84.     </dependency>  
  85.     <dependency>  
  86.       <groupId>javax.servlet</groupId>  
  87.       <artifactId>jstl</artifactId>  
  88.       <version>1.2</version>  
  89.       <type>jar</type>  
  90.       <scope>compile</scope>  
  91.     </dependency>  
  92.     <dependency>  
  93.       <groupId>log4j</groupId>  
  94.       <artifactId>log4j</artifactId>  
  95.       <version>1.2.17</version>  
  96.     </dependency>  
  97.     <dependency>  
  98.       <groupId>org.slf4j</groupId>  
  99.       <artifactId>slf4j-log4j12</artifactId>  
  100.       <version>1.7.25</version>  
  101.     </dependency>  
  102.   </dependencies>  
  103.   <build>  
  104.     <finalName>redis_session</finalName>  
  105.   </build>  
  106. </project>  
applicationContext.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  6.     <context:component-scan base-package="com.sheng.example">  
  7.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  8.         <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>  
  9.     </context:component-scan>  
  10. </beans>  
applicationContext-shiro.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  
  5.   
  6.     <!-- 配置緩存管理器 -->  
  7.     <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
  8.         <!-- 指定 ehcache 的配置文件 -->  
  9.         <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />  
  10.     </bean>  
  11.   
  12.     <!-- 配置进行授权和认证的 Realm -->  
  13.     <bean id="myRealm" class="com.sheng.example.MyRealm" init-method="setCredentialMatcher"></bean>  
  14.     <!-- 配置 Shiro 的 SecurityManager Bean. -->  
  15.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  16.         <property name="sessionManager" ref="sessionManager" />  
  17.         <property name="cacheManager" ref="cacheManager" />  
  18.         <property name="realm" ref="myRealm" />  
  19.     </bean>  
  20.   
  21.     <!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->  
  22.     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />  
  23.   
  24.     <!-- 配置 ShiroFilter bean: 该 bean 的 id 必须和 web.xml 文件中配置的 shiro filter 的   
  25.         name 一致 -->  
  26.     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
  27.         <!-- 装配 securityManager -->  
  28.         <property name="securityManager" ref="securityManager" />  
  29.         <!-- 配置登陆页面 -->  
  30.         <property name="loginUrl" value="/login.jsp" />  
  31.         <!-- 登陆成功后的一面 -->  
  32.         <property name="successUrl" value="/shiro-success.jsp" />  
  33.         <property name="unauthorizedUrl" value="/shiro-unauthorized.jsp" />  
  34.         <!-- 具体配置需要拦截哪些 URL, 以及访问对应的 URL 时使用 Shiro 的什么 Filter 进行拦截. -->  
  35.         <property name="filterChainDefinitions">  
  36.             <value>  
  37.                 <!--静态资源-->  
  38.                 /css/**  = anon  
  39.                 /images/**  = anon  
  40.                 /assets/**=anon  
  41.                 /js/**=anon  
  42.                 <!-- 配置登出: 使用 logout 过滤器 -->  
  43.                 /=anon  
  44.                 /index.jsp=anon  
  45.                 /login=anon  
  46.                 /user.jsp = roles[user]  
  47.                 /admin.jsp = roles[admin]  
  48.                 /** = authc  
  49.             </value>  
  50.         </property>  
  51.   
  52.         <property name="filters">  
  53.             <map>  
  54.                 <entry key="authc">  
  55.                     <bean class="com.sheng.example.AuthcLevelFilter"></bean>  
  56.                 </entry>  
  57.                 <!-- <entry key="roles"> <bean class="com.atguigu.shiro.realm.RolesAnyAuthorizationFilter"></bean>   
  58.                     </entry> -->  
  59.             </map>  
  60.         </property>  
  61.   
  62.     </bean>  
  63.     <!-- 会话管理器 -->  
  64.     <bean id="sessionManager"  
  65.         class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  66.         <property name="globalSessionTimeout" value="60000" />  
  67.         <property name="deleteInvalidSessions" value="true" />  
  68.         <property name="sessionValidationSchedulerEnabled" value="true" /><!-- 定时检查失效的session -->  
  69.         <!-- <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/> -->  
  70.         <property name="sessionDAO" ref="sessionDAO" />  
  71.         <!--<property name="sessionIdCookie.name" value="jsid"/>  -->  
  72.         <!--<property name="sessionIdCookieEnabled" value="true" />-->  
  73.         <!--<property name="sessionIdCookie" ref="sessionIdCookie" />-->  
  74.     </bean>  
  75.     <!-- 会话验证调度器 -->  
  76.     <!--<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">   
  77.         <property name="sessionValidationInterval" value="1800000"/> <property name="sessionManager"   
  78.         ref="sessionManager"/> </bean> -->  
  79.     <!-- 会话DAO -->  
  80.     <bean id="sessionDAO" class="com.sheng.example.RedisSessionDao"></bean>  
  81.     <!--<bean id="sessionDAO"-->  
  82.         <!--class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">-->  
  83.         <!--<property name="activeSessionsCacheName" value="shiro-activeSessionCache" />-->  
  84.         <!--<property name="sessionIdGenerator" ref="sessionIdGenerator" />-->  
  85.     <!--</bean>-->  
  86.     <!-- 会话ID生成器 -->  
  87.     <bean id="sessionIdGenerator"  
  88.         class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />  
  89.     <!-- 会话Cookie模板 -->  
  90.     <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
  91.         <constructor-arg value="sid" />  
  92.         <property name="httpOnly" value="true" />  
  93.         <property name="maxAge" value="86400" />  
  94.         <property name="name" value="daskldj"></property>  
  95.         <property name="domain" value="sadf"></property>  
  96.     </bean>  
  97.   
  98. </beans>  

ehcache-shiro.xml

[html]  view plain  copy
  1. <!--  
  2.   ~ Licensed to the Apache Software Foundation (ASF) under one  
  3.   ~ or more contributor license agreements.  See the NOTICE file  
  4.   ~ distributed with this work for additional information  
  5.   ~ regarding copyright ownership.  The ASF licenses this file  
  6.   ~ to you under the Apache License, Version 2.0 (the  
  7.   ~ "License"); you may not use this file except in compliance  
  8.   ~ with the License.  You may obtain a copy of the License at  
  9.   ~  
  10.   ~     http://www.apache.org/licenses/LICENSE-2.0  
  11.   ~  
  12.   ~ Unless required by applicable law or agreed to in writing,  
  13.   ~ software distributed under the License is distributed on an  
  14.   ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY  
  15.   ~ KIND, either express or implied.  See the License for the  
  16.   ~ specific language governing permissions and limitations  
  17.   ~ under the License.  
  18.   -->  
  19.   
  20. <!-- EhCache XML configuration file used for Shiro spring sample application -->  
  21. <ehcache>  
  22.   
  23.     <!-- Sets the path to the directory where cache .data files are created.  
  24.   
  25. If the path is a Java System Property it is replaced by  
  26. its value in the running VM.  
  27.   
  28. The following properties are translated:  
  29. user.home - User's home directory  
  30. user.dir - User's current working directory  
  31. java.io.tmpdir - Default temp file path -->  
  32.     <diskStore path="java.io.tmpdir/shiro-spring-sample"/>  
  33.   
  34.   
  35.     <!--Default Cache configuration. These will applied to caches programmatically created through  
  36.     the CacheManager.  
  37.   
  38.     The following attributes are required:  
  39.   
  40.     maxElementsInMemory            - Sets the maximum number of objects that will be created in memory  
  41.     eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the  
  42.                                      element is never expired.  
  43.     overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache  
  44.                                      has reached the maxInMemory limit.  
  45.   
  46.     The following attributes are optional:  
  47.     timeToIdleSeconds              - Sets the time to idle for an element before it expires.  
  48.                                      i.e. The maximum amount of time between accesses before an element expires  
  49.                                      Is only used if the element is not eternal.  
  50.                                      Optional attribute. A value of 0 means that an Element can idle for infinity.  
  51.                                      The default value is 0.  
  52.     timeToLiveSeconds              - Sets the time to live for an element before it expires.  
  53.                                      i.e. The maximum time between creation time and when an element expires.  
  54.                                      Is only used if the element is not eternal.  
  55.                                      Optional attribute. A value of 0 means that and Element can live for infinity.  
  56.                                      The default value is 0.  
  57.     diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.  
  58.                                      The default value is false.  
  59.     diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value  
  60.                                      is 120 seconds.  
  61.     memoryStoreEvictionPolicy      - Policy would be enforced upon reaching the maxElementsInMemory limit. Default  
  62.                                      policy is Least Recently Used (specified as LRU). Other policies available -  
  63.                                      First In First Out (specified as FIFO) and Less Frequently Used  
  64.                                      (specified as LFU)  
  65.     -->  
  66.   
  67.     <defaultCache  
  68.             maxElementsInMemory="10000"  
  69.             eternal="false"  
  70.             timeToIdleSeconds="120"  
  71.             timeToLiveSeconds="120"  
  72.             overflowToDisk="false"  
  73.             diskPersistent="false"  
  74.             diskExpiryThreadIntervalSeconds="120"  
  75.             />  
  76.   
  77.     <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session  
  78. expirations explicitly.  If we set it to false and then set corresponding timeToIdle and timeToLive properties,  
  79. ehcache would evict sessions without Shiro's knowledge, which would cause many problems  
  80. (e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"  
  81. Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)  
  82.   
  83. diskPersistent=true since we want an enterprise session management feature - ability to use sessions after  
  84. even after a JVM restart.  -->  
  85.     <cache name="shiro-activeSessionCache"  
  86.            maxElementsInMemory="10000"  
  87.            eternal="true"  
  88.            overflowToDisk="true"  
  89.            diskPersistent="true"  
  90.            diskExpiryThreadIntervalSeconds="600"/>  
  91.   
  92.     <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"  
  93.            maxElementsInMemory="100"  
  94.            eternal="false"  
  95.            timeToLiveSeconds="600"  
  96.            overflowToDisk="false"/>  
  97.   
  98. </ehcache>  


springmvc.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
  6.     <!-- 配置自动扫描的包 -->  
  7.     <context:component-scan base-package="com.sheng.example" use-default-filters="false">  
  8.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
  9.         <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>  
  10.     </context:component-scan>  
  11.     <!--一下内容只能放在springmvc.xml中  不可放在ApplicationContext.xml或ApplicationContext-shiro.xml中-->  
  12.     <!--<bean id="exceptionHandler" class="com.sheng.atx.parking.handlers.MyExceptionHandler"/>-->  
  13.     <!-- 使 Shiro 的注解起作用, Shiro 的注解标示在方法上. 例如 @RequiresRoles、@RequiresPermissions -->  
  14.     <!-- 因为目前是在 Handler 的方法上添加注解, 所以以下的配置需要作用在 SpringMVC 的 IOC 容器中. 而不是其父容器中.  -->  
  15.     <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
  16.           depends-on="lifecycleBeanPostProcessor"/>  
  17.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
  18.         <property name="securityManager" ref="securityManager"/>  
  19.     </bean>  
  20. </beans>  
web.xml

[html]  view plain  copy
  1. <!DOCTYPE web-app PUBLIC  
  2.  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  3.  "http://java.sun.com/dtd/web-app_2_3.dtd" >  
  4.   
  5. <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"  
  6.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  7.          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">  
  8.   <!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->  
  9.   <context-param>  
  10.     <param-name>contextConfigLocation</param-name>  
  11.     <param-value>classpath:applicationContext*.xml</param-value>  
  12.   </context-param>  
  13.   <listener>  
  14.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  15.   </listener>  
  16.   <servlet>  
  17.     <servlet-name>dispatcherServlet</servlet-name>  
  18.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  19.     <init-param>  
  20.       <param-name>contextConfigLocation</param-name>  
  21.       <param-value>classpath:springmvc.xml</param-value>  
  22.     </init-param>  
  23.     <load-on-startup>1</load-on-startup>  
  24.     <async-supported>true</async-supported>  
  25.   </servlet>  
  26.   
  27.   <servlet-mapping>  
  28.     <servlet-name>dispatcherServlet</servlet-name>  
  29.     <url-pattern>/</url-pattern>  
  30.   </servlet-mapping>  
  31.   <welcome-file-list>  
  32.     <welcome-file>index.jsp</welcome-file>  
  33.   </welcome-file-list>  
  34.   <!-- 配置  Shiro 的 Filter -->  
  35.   <filter>  
  36.     <filter-name>shiroFilter</filter-name>  
  37.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  38.     <async-supported>true</async-supported>  
  39.     <init-param>  
  40.       <param-name>targetFilterLifecycle</param-name>  
  41.       <param-value>true</param-value>  
  42.     </init-param>  
  43.   </filter>  
  44.   <filter-mapping>  
  45.     <filter-name>shiroFilter</filter-name>  
  46.     <url-pattern>/*</url-pattern>  
  47.   </filter-mapping>  
  48. </web-app>  

AuthcLevelFilter.java

[java]  view plain  copy
  1. package com.sheng.example;  
  2. import org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter;  
  3. import org.apache.shiro.web.util.WebUtils;  
  4.   
  5. import javax.servlet.ServletRequest;  
  6. import javax.servlet.ServletResponse;  
  7. import javax.servlet.http.HttpServletRequest;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. import java.io.IOException;  
  10. import java.io.PrintWriter;  
  11. import java.net.URLEncoder;  
  12. import java.util.ArrayList;  
  13. import java.util.HashMap;  
  14. import java.util.Map;  
  15.   
  16. public class AuthcLevelFilter extends PassThruAuthenticationFilter {  
  17.     @SuppressWarnings("deprecation")  
  18.     @Override  
  19.         protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {  
  20.         HttpServletResponse httpResponse ;  
  21.         HttpServletRequest httpRequest;  
  22.         Map<String, Object> map = new HashMap<String, Object>();  
  23.         httpResponse = WebUtils.toHttp(response);   
  24.         httpRequest = WebUtils.toHttp(request);  
  25.   
  26.         if(isLoginRequest(httpRequest, httpResponse)){  
  27.         return true;  
  28.         }else {  
  29.   
  30.             WebUtils.saveRequest(request);  
  31.             String url = httpRequest.getRequestURI();  
  32.             map.put("requestUri", url);  
  33.             PrintWriter out=null;  
  34.             try {  
  35.                 httpResponse.setContentType("text/html; charset=utf-8");  
  36.                 out =  httpResponse.getWriter();  
  37. //              if (url.equals("/logList.jsp")||url.equals("/parkManager.jsp")) {  
  38. //                  httpResponse.setContentType("text/html;charset=utf-8");  
  39. //                  out.append("<script language='javascript'>parent.location='../index.jsp';</script>");  
  40. //              }else if(url.equals("/getParkList")||url.equals("/getLogList_admin")||url.equals("/getLogList_park")){  
  41. //                  PageData pageData=new PageData();  
  42. //                  pageData.setData(new ArrayList<>());  
  43. //                  ReturnData ret = new ReturnData();  
  44. //                  ret.setMessage(URLEncoder.encode("用户未登录,试图访问!","utf-8"));  
  45. //                  pageData.setOtherData(ret);  
  46. //                  httpResponse.setCharacterEncoding("UTF-8");  
  47. //                  httpResponse.setContentType("application/json; charset=utf-8");  
  48. //                  out.append(JSONObject.toJSONString(pageData));  
  49. //              } else if(url.equals("/park/query_coast")) {  
  50. //                  ReturnData ret = new ReturnData();  
  51. //                  ret.setStatus(false);  
  52. //                  ret.setMessage(URLEncoder.encode("用户未登录,试图访问!","utf-8"));  
  53. //                  out.append(JSONObject.toJSONString(ret));  
  54. //              }else{  
  55. //                  System.out.println("requestUri:" + httpRequest.getRequestURI());  
  56. //                  httpResponse.setStatus(200, "redirect");  
  57. //                  httpResponse.setCharacterEncoding("UTF-8");  
  58. //                  httpResponse.setContentType("application/json; charset=utf-8");  
  59. //  
  60. //                      ReturnData ret = new ReturnData();  
  61. //                      ret.setMessage("用户未登录,试图访问!");  
  62. //                      ret.setData(httpResponse.toString());  
  63.                         out.append("用户未登录,试图访问!");  
  64. //  
  65. //  
  66. //              }  
  67.             } catch (IOException e) {  
  68.                 e.printStackTrace();  
  69.             } finally {  
  70.                 if (out != null) {  
  71.                     out.close();  
  72.                 }  
  73.             }  
  74.                 return false;  
  75.   
  76.             }  
  77.         }  
  78.       
  79. }  
MyController.java

[java]  view plain  copy
  1. package com.sheng.example;  
  2.   
  3. import org.apache.shiro.SecurityUtils;  
  4. import org.apache.shiro.authc.AuthenticationException;  
  5. import org.apache.shiro.authc.UsernamePasswordToken;  
  6. import org.apache.shiro.subject.Subject;  
  7. import org.springframework.stereotype.Controller;  
  8. import org.springframework.web.bind.annotation.RequestMapping;  
  9. import org.springframework.web.bind.annotation.ResponseBody;  
  10. import org.springframework.web.servlet.ModelAndView;  
  11.   
  12. /** 
  13.  * Created by Administrator on 2017/6/30 0030. 
  14.  */  
  15. @Controller  
  16. public class MyController {  
  17.   
  18.     @RequestMapping("test")  
  19.     @ResponseBody  
  20.     public String index(){  
  21.         Subject currentUser = SecurityUtils.getSubject();  
  22.         return "Hello:"+currentUser.getPrincipal().toString()+",我是tomcat2";  
  23.     }  
  24.     @RequestMapping("login")  
  25.     public ModelAndView login(String username,String password){  
  26.         ModelAndView modelAndView=null;  
  27.         Subject subject = SecurityUtils.getSubject();  
  28.         UsernamePasswordToken token = new UsernamePasswordToken(username, password);  
  29.         try {  
  30.             subject.login(token);  
  31.             modelAndView=new ModelAndView("test");  
  32.             modelAndView.addObject("username",username);  
  33.         }catch (AuthenticationException ae){  
  34.             modelAndView=new ModelAndView("/");  
  35.             modelAndView.addObject("message","用户名或密码错误");  
  36.         }  
  37.   
  38.         return modelAndView;  
  39.     }  
  40. }  
MyRealm.java

[java]  view plain  copy
  1. package com.sheng.example;  
  2.   
  3. import org.apache.shiro.authc.AuthenticationException;  
  4. import org.apache.shiro.authc.AuthenticationInfo;  
  5. import org.apache.shiro.authc.AuthenticationToken;  
  6. import org.apache.shiro.authc.SimpleAuthenticationInfo;  
  7. import org.apache.shiro.authc.credential.HashedCredentialsMatcher;  
  8. import org.apache.shiro.authz.AuthorizationInfo;  
  9. import org.apache.shiro.authz.SimpleAuthorizationInfo;  
  10. import org.apache.shiro.crypto.hash.Md5Hash;  
  11. import org.apache.shiro.crypto.hash.SimpleHash;  
  12. import org.apache.shiro.realm.AuthorizingRealm;  
  13. import org.apache.shiro.subject.PrincipalCollection;  
  14. import org.apache.shiro.util.ByteSource;  
  15.   
  16. /** 
  17.  * Created by Administrator on 2017/6/30 0030. 
  18.  */  
  19. public class MyRealm extends AuthorizingRealm {  
  20.     /** 
  21.      * 授权方法: 
  22.      * 1. 实际返回的是 SimpleAuthorizationInfo 类的实例 
  23.      * 2. 可以调用 SimpleAuthorizationInfo 的 addRole 来添加当前登录 user 的权限信息. 
  24.      * 3. 可以调用 PrincipalCollection 参数的 getPrimaryPrincipal() 方法来获取用户信息 
  25.      */  
  26.     @Override  
  27.     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {  
  28.         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
  29.   
  30.         Object principal = principalCollection.getPrimaryPrincipal();  
  31. //        User user = userService.getAdmin(principal.toString());  
  32. //      if("admin".equals(principal)){  
  33. //        info.addRole(user.getRole().getName());  
  34. //          System.out.println("用户角色admin");  
  35. //          info.addRole("list");  
  36. //      }  
  37. //      if("user".equals(principal)){  
  38. //          info.addRole("list");  
  39. //      }  
  40.   
  41. //      info.addRole("user");  
  42.   
  43.         return info;  
  44.     }  
  45.   
  46.     /** 
  47.      * 认证方法 
  48.      * 1. 编写表单: 表单的 action、和 username、password 的参数都是什么 ? 
  49.      * 回答: 提交到你想提交的地方, username 和 password 也参数名称都任意. 
  50.      * 2. 例如, 提交到了一个 SpringMVC 的 handler: 
  51.      * 1). 获取用户名、密码 
  52.      * 2). 
  53.      * Subject currentUser = SecurityUtils.getSubject(); 
  54.      * UsernamePasswordToken token = new UsernamePasswordToken(username, password); 
  55.      * currentUser.login(token); 
  56.      * 3. 当 Subject 调用 login 方法时, 即会触发当前的 doGetAuthenticationInfo 方法. 且把 
  57.      * UsernamePasswordToken 对象传入, 然后再该方法中执行真正的认证: 访问数据库进行比对. 
  58.      * 1). 获取用户名和密码 
  59.      * 2). 
  60.      */  
  61.     @Override  
  62.     protected AuthenticationInfo doGetAuthenticationInfo(  
  63.             AuthenticationToken token) throws AuthenticationException {  
  64.         System.out.println("doGetAuthenticationInfo------->"+token.getPrincipal());  
  65.         System.out.println("doGetAuthenticationInfo------->"+token.getCredentials());  
  66.   
  67.         //1. 从 token 中获取登录的 username! 注意不需要获取 password.  
  68.   
  69.         //2. 利用 username 查询数据库得到用户的信息.  
  70.   
  71.         //3. 创建 SimpleAuthenticationInfo 对象并返回. 注意该对象的凭证式从数据库中查询得到的.  
  72.         //而不是页面输入的. 实际的密码校验可以交由 Shiro 来完成  
  73.   
  74.         //4. 关于密码加密的事: shiro 的密码加密可以非常非常的复杂, 但实现起来却可以非常简单.  
  75.         //1). 可以选择加密方式: 在当前的 realm 中编写一个 public 类型的不带参数的方法, 使用 @PostConstruct  
  76.         //注解进行修饰, 在其中来设置密码的匹配方式.  
  77.         //2). 设置盐值: 盐值一般是从数据库中查询得到的.  
  78.         //3). 调用 new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName)  
  79.         //构造器返回 SimpleAuthenticationInfo 对象:  credentialsSalt 为  
  80.         //ByteSource credentialsSalt = new Md5Hash(source);  
  81.   
  82.         //登陆的主要信息: 可以是一个实体类的对象, 但该实体类的对象一定是根据 token 的 username 查询得到的.  
  83.         Object principal = token.getPrincipal();//获取登录名  
  84.         //认证信息: 从数据库中查询出来的信息. 密码的比对交给 shiro 去进行比较  
  85.         String credentials = "789ecdde95405b37ffafd9c4e460b4a9";  
  86.         //设置盐值:  
  87.         String source = "abcdefg";  
  88.         ByteSource credentialsSalt = new Md5Hash(source);  
  89. //      System.out.println(credentialsSalt);  
  90. //        User atx_admin=null;  
  91. //        try {  
  92. //            atx_admin = userService.getAdmin(token.getPrincipal().toString());  
  93. //            if(atx_admin.getRole().getName().equals("park_station")){//数据库不加密前台人员密码  
  94. //                atx_admin.setPassword(strToMD5(atx_admin.getPassword()));  
  95. //            }  
  96. ////            System.out.println("数据库密码:" + atx_admin.getPassword());  
  97. //        }catch (Exception e){  
  98. //            e.printStackTrace();  
  99. //        }  
  100. //        if(atx_admin==null)  
  101. //            throw new AuthenticationException("用户名不存在");  
  102.         //当前 Realm 的 name  
  103.         String realmName = getName();  
  104. //      System.out.println("realmName:"+realmName);  
  105.         SimpleAuthenticationInfo info =  
  106.                 new SimpleAuthenticationInfo(principal, credentials,  
  107.                         credentialsSalt, realmName);  
  108.   
  109.         return info;  
  110.     }  
  111.   
  112.     //@PostConstruct: 相当于 bean 节点的 init-method 配置.  
  113.     public void setCredentialMatcher(){  
  114.         HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();  
  115.   
  116.         credentialsMatcher.setHashAlgorithmName("MD5");  
  117.         credentialsMatcher.setHashIterations(1024);  
  118.   
  119.         setCredentialsMatcher(credentialsMatcher);  
  120.     }  
  121.     public static String strToMD5(String str){  
  122.         String saltSource = "abcdefg";  
  123.   
  124.         String hashAlgorithmName = "MD5";//加密方式  
  125.         Object salt = new Md5Hash(saltSource);//盐值  
  126.         int hashIterations = 1024;//加密次数  
  127.   
  128.         //加密后的密码  
  129.         Object result = new SimpleHash(hashAlgorithmName, str, salt, hashIterations);  
  130.         return result.toString();  
  131.     }  
  132.     public static void main(String[] args) {  
  133.         String saltSource = "abcdefg";  
  134.   
  135.         String hashAlgorithmName = "MD5";//加密方式  
  136.         String credentials = "123";//密码  
  137.         Object salt = new Md5Hash(saltSource);//盐值  
  138.         int hashIterations = 1024;//加密次数  
  139.   
  140.         //加密后的密码  
  141.         Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);  
  142.         System.out.println(result);  
  143.         System.out.println("68f3139a38b232392cc9d3b6ddd762f7".equals(result.toString()));  
  144.     }  
  145. }  
RedisClient.java

[java]  view plain  copy
  1. package com.sheng.example;  
  2.   
  3. import org.apache.shiro.codec.Base64;  
  4. import org.apache.shiro.session.Session;  
  5. import redis.clients.jedis.Jedis;  
  6. import redis.clients.jedis.JedisPool;  
  7. import redis.clients.jedis.JedisPoolConfig;  
  8.   
  9. import java.io.*;  
  10.   
  11. /** 
  12.  * Created by Administrator on 2017/6/30 0030. 
  13.  */  
  14. public class RedisClient {  
  15.     private static JedisPool pool;  
  16.     private static String redisServerIp="192.168.31.7";  
  17.   
  18.     /** 
  19.      * 建立连接池 真实环境,一般把配置参数缺抽取出来。 
  20.      * 
  21.      */  
  22.     private static void createJedisPool() {  
  23.   
  24.         // 建立连接池配置参数  
  25.         JedisPoolConfig config = new JedisPoolConfig();  
  26.         config.setMaxWaitMillis(1000);  
  27.         // 设置最大连接数  
  28. //        config.setMaxActive(1000);  
  29.   
  30.         // 设置最大阻塞时间,记住是毫秒数milliseconds  
  31. //        config.setMaxWait(1000);  
  32.         // 设置空间连接  
  33.         config.setMaxIdle(10);  
  34.         config.setMaxTotal(100);  
  35.         config.setMinIdle(2);  
  36.         // 创建连接池  
  37.         pool = new JedisPool(config, redisServerIp, 6379);  
  38.   
  39.     }  
  40.   
  41.     /** 
  42.      * 在多线程环境同步初始化 
  43.      */  
  44.     private static synchronized void poolInit() {  
  45.         if (pool == null)  
  46.             createJedisPool();  
  47.     }  
  48.   
  49.     /** 
  50.      * 获取一个jedis 对象 
  51.      * 
  52.      * @return 
  53.      */  
  54.     private static Jedis getJedis() {  
  55.   
  56.         if (pool == null)  
  57.             poolInit();  
  58.         return pool.getResource();  
  59.     }  
  60.   
  61.     /** 
  62.      * 归还一个连接 
  63.      * 
  64.      * @param jedis 
  65.      */  
  66.     private static void returnRes(Jedis jedis) {  
  67.         pool.returnResource(jedis);  
  68.     }  
  69.   
  70.     void set(String sessionId, Session session) {  
  71.         jedis = getJedis();  
  72.         jedis.append(sessionId, serialize(session));  
  73.         returnRes(jedis);  
  74.     }  
  75.   
  76.     void replace(String sessionId, Session session) {  
  77.         set(sessionId, session);  
  78.   
  79.     }  
  80.   
  81.     Jedis jedis = null;  
  82.   
  83.     void delete(String sessionId) {  
  84.         jedis = getJedis();  
  85.         jedis.del(sessionId);  
  86.         returnRes(jedis);  
  87.     }  
  88.   
  89.     Object get(String sessionId) {  
  90.         jedis = getJedis();  
  91.         Object obj = deserialize(jedis.get(sessionId));  
  92.         returnRes(jedis);  
  93.         return obj;  
  94.     }  
  95.   
  96.     private static Object deserialize(String str) {  
  97.         ByteArrayInputStream bis = null;  
  98.         ObjectInputStream ois = null;  
  99.         try {  
  100.             bis = new ByteArrayInputStream(Base64.decode(str));  
  101.             ois = new ObjectInputStream(bis);  
  102.             return ois.readObject();  
  103.         } catch (Exception e) {  
  104.             throw new RuntimeException("deserialize session error", e);  
  105.         } finally {  
  106.             try {  
  107.                 ois.close();  
  108.                 bis.close();  
  109.             } catch (IOException e) {  
  110.                 e.printStackTrace();  
  111.             }  
  112.   
  113.         }  
  114.     }  
  115.   
  116.     private static String serialize(Object obj) {  
  117.         ByteArrayOutputStream bos = null;  
  118.         ObjectOutputStream oos = null;  
  119.         try {  
  120.             bos = new ByteArrayOutputStream();  
  121.             oos = new ObjectOutputStream(bos);  
  122.             oos.writeObject(obj);  
  123.             return Base64.encodeToString(bos.toByteArray());  
  124.         } catch (Exception e) {  
  125.             throw new RuntimeException("serialize session error", e);  
  126.         } finally {  
  127.             try {  
  128.                 oos.close();  
  129.                 bos.close();  
  130.             } catch (IOException e) {  
  131.                 e.printStackTrace();  
  132.             }  
  133.   
  134.         }  
  135.     }  
  136.     public static void main(String[] args){  
  137.         Jedis jedisCli = new Jedis("192.168.31.7"6379); //新建Jedis对象  
  138.         jedisCli.select(2); //切换Redis数据库  
  139.         jedisCli.set("firstJedis""hello,Jedis"); //与Redis命令行操作基本一致  
  140.     }  
  141. }  

RedisSessionDao.java

[java]  view plain  copy
  1. package com.sheng.example;  
  2.   
  3. import org.apache.shiro.session.Session;  
  4. import org.apache.shiro.session.UnknownSessionException;  
  5. import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;  
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8.   
  9. import java.io.Serializable;  
  10. import java.util.Collection;  
  11. import java.util.Collections;  
  12.   
  13. /** 
  14.  * Created by Administrator on 2017/6/30 0030. 
  15.  */  
  16. public class RedisSessionDao extends AbstractSessionDAO {  
  17.     private RedisClient sessionCacheClient=new RedisClient();  
  18.   
  19.     Logger log= LoggerFactory.getLogger(getClass());  
  20.   
  21.     public void update(Session session) throws UnknownSessionException {  
  22.         log.info("更新seesion,id=[{}]",session.getId().toString());  
  23.         try {  
  24.             sessionCacheClient.replace(session.getId().toString(), session);  
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.         }  
  28.     }  
  29.   
  30.     public void delete(Session session) {  
  31.         log.info("删除seesion,id=[{}]",session.getId().toString());  
  32.         try {  
  33.             sessionCacheClient.delete(session.getId().toString());  
  34.         } catch (Exception e) {  
  35.             e.printStackTrace();  
  36.         }  
  37.   
  38.     }  
  39.   
  40.     public Collection<Session> getActiveSessions() {  
  41.         System.out.println("getActiveSessions");  
  42.         log.info("获取存活的session");  
  43.         return Collections.emptySet();  
  44.     }  
  45.   
  46.     @Override  
  47.     protected Serializable doCreate(Session session) {  
  48.         Serializable sessionId = generateSessionId(session);  
  49.         assignSessionId(session, sessionId);  
  50.         log.info("创建seesion,id=[{}]",session.getId().toString());  
  51.         try {  
  52.             sessionCacheClient.set(sessionId.toString(),  session);  
  53.         } catch (Exception e) {  
  54.             log.error(e.getMessage());  
  55.         }  
  56.         return sessionId;  
  57.     }  
  58.   
  59.     @Override  
  60.     protected Session doReadSession(Serializable sessionId) {  
  61.         log.info("获取seesion,id=[{}]",sessionId.toString());  
  62.         Session session = null;  
  63.         try {  
  64.             session = (Session) sessionCacheClient.get(sessionId.toString());  
  65.         } catch (Exception e) {  
  66.             log.error(e.getMessage());  
  67.         }  
  68.         return session;  
  69.     }  
  70. }  

index.jsp

[html]  view plain  copy
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>  
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
  3. <!DOCTYPE html>  
  4. <html>  
  5. <body>  
  6. <h2>Hello World!</h2>  
  7. <form action="login">  
  8.     <input type="text" name="username">  
  9.     <input type="password" name="password">  
  10.     <input type="submit" value="提交">  
  11. </form>  
  12. <%=session.getId()%>  
  13. <script>  
  14.     <c:if test="${not empty message}">  
  15.         alert("${message}");  
  16.     </c:if>  
  17. </script>  
  18. </body>  
  19. </html>  


打包后放在不同tomcat下 即可实现session共享
相关文章

相关标签/搜索