pom.xml:
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.sheng.webapp</groupId>
- <artifactId>redis_session</artifactId>
- <packaging>war</packaging>
- <version>1.0-SNAPSHOT</version>
- <name>redis_session Maven Webapp</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>4.3.9.RELEASE</spring.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.session</groupId>
- <artifactId>spring-session-data-redis</artifactId>
- <version>1.1.1.RELEASE</version>
- <type>pom</type>
- </dependency>
- <!--Spring-->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <version>${spring.version}</version>
- <scope>test</scope>
- </dependency>
- <!---shiro相关-->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-ehcache</artifactId>
- <version>1.2.3</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.7.25</version>
- </dependency>
- </dependencies>
- <build>
- <finalName>redis_session</finalName>
- </build>
- </project>
- <?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:context="http://www.springframework.org/schema/context"
- 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">
- <context:component-scan base-package="com.sheng.example">
- <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
- </context:component-scan>
- </beans>
- <?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">
- <!-- 配置緩存管理器 -->
- <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <!-- 指定 ehcache 的配置文件 -->
- <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" />
- </bean>
- <!-- 配置进行授权和认证的 Realm -->
- <bean id="myRealm" class="com.sheng.example.MyRealm" init-method="setCredentialMatcher"></bean>
- <!-- 配置 Shiro 的 SecurityManager Bean. -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="sessionManager" ref="sessionManager" />
- <property name="cacheManager" ref="cacheManager" />
- <property name="realm" ref="myRealm" />
- </bean>
- <!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
- <!-- 配置 ShiroFilter bean: 该 bean 的 id 必须和 web.xml 文件中配置的 shiro filter 的
- name 一致 -->
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
- <!-- 装配 securityManager -->
- <property name="securityManager" ref="securityManager" />
- <!-- 配置登陆页面 -->
- <property name="loginUrl" value="/login.jsp" />
- <!-- 登陆成功后的一面 -->
- <property name="successUrl" value="/shiro-success.jsp" />
- <property name="unauthorizedUrl" value="/shiro-unauthorized.jsp" />
- <!-- 具体配置需要拦截哪些 URL, 以及访问对应的 URL 时使用 Shiro 的什么 Filter 进行拦截. -->
- <property name="filterChainDefinitions">
- <value>
- <!--静态资源-->
- /css/** = anon
- /images/** = anon
- /assets/**=anon
- /js/**=anon
- <!-- 配置登出: 使用 logout 过滤器 -->
- /=anon
- /index.jsp=anon
- /login=anon
- /user.jsp = roles[user]
- /admin.jsp = roles[admin]
- /** = authc
- </value>
- </property>
- <property name="filters">
- <map>
- <entry key="authc">
- <bean class="com.sheng.example.AuthcLevelFilter"></bean>
- </entry>
- <!-- <entry key="roles"> <bean class="com.atguigu.shiro.realm.RolesAnyAuthorizationFilter"></bean>
- </entry> -->
- </map>
- </property>
- </bean>
- <!-- 会话管理器 -->
- <bean id="sessionManager"
- class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
- <property name="globalSessionTimeout" value="60000" />
- <property name="deleteInvalidSessions" value="true" />
- <property name="sessionValidationSchedulerEnabled" value="true" /><!-- 定时检查失效的session -->
- <!-- <property name="sessionValidationScheduler" ref="sessionValidationScheduler"/> -->
- <property name="sessionDAO" ref="sessionDAO" />
- <!--<property name="sessionIdCookie.name" value="jsid"/> -->
- <!--<property name="sessionIdCookieEnabled" value="true" />-->
- <!--<property name="sessionIdCookie" ref="sessionIdCookie" />-->
- </bean>
- <!-- 会话验证调度器 -->
- <!--<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
- <property name="sessionValidationInterval" value="1800000"/> <property name="sessionManager"
- ref="sessionManager"/> </bean> -->
- <!-- 会话DAO -->
- <bean id="sessionDAO" class="com.sheng.example.RedisSessionDao"></bean>
- <!--<bean id="sessionDAO"-->
- <!--class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">-->
- <!--<property name="activeSessionsCacheName" value="shiro-activeSessionCache" />-->
- <!--<property name="sessionIdGenerator" ref="sessionIdGenerator" />-->
- <!--</bean>-->
- <!-- 会话ID生成器 -->
- <bean id="sessionIdGenerator"
- class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />
- <!-- 会话Cookie模板 -->
- <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
- <constructor-arg value="sid" />
- <property name="httpOnly" value="true" />
- <property name="maxAge" value="86400" />
- <property name="name" value="daskldj"></property>
- <property name="domain" value="sadf"></property>
- </bean>
- </beans>
ehcache-shiro.xml
- <!--
- ~ Licensed to the Apache Software Foundation (ASF) under one
- ~ or more contributor license agreements. See the NOTICE file
- ~ distributed with this work for additional information
- ~ regarding copyright ownership. The ASF licenses this file
- ~ to you under the Apache License, Version 2.0 (the
- ~ "License"); you may not use this file except in compliance
- ~ with the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing,
- ~ software distributed under the License is distributed on an
- ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- ~ KIND, either express or implied. See the License for the
- ~ specific language governing permissions and limitations
- ~ under the License.
- -->
- <!-- EhCache XML configuration file used for Shiro spring sample application -->
- <ehcache>
- <!-- Sets the path to the directory where cache .data files are created.
- If the path is a Java System Property it is replaced by
- its value in the running VM.
- The following properties are translated:
- user.home - User's home directory
- user.dir - User's current working directory
- java.io.tmpdir - Default temp file path -->
- <diskStore path="java.io.tmpdir/shiro-spring-sample"/>
- <!--Default Cache configuration. These will applied to caches programmatically created through
- the CacheManager.
- The following attributes are required:
- maxElementsInMemory - Sets the maximum number of objects that will be created in memory
- eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the
- element is never expired.
- overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
- has reached the maxInMemory limit.
- The following attributes are optional:
- timeToIdleSeconds - Sets the time to idle for an element before it expires.
- i.e. The maximum amount of time between accesses before an element expires
- Is only used if the element is not eternal.
- Optional attribute. A value of 0 means that an Element can idle for infinity.
- The default value is 0.
- timeToLiveSeconds - Sets the time to live for an element before it expires.
- i.e. The maximum time between creation time and when an element expires.
- Is only used if the element is not eternal.
- Optional attribute. A value of 0 means that and Element can live for infinity.
- The default value is 0.
- diskPersistent - Whether the disk store persists between restarts of the Virtual Machine.
- The default value is false.
- diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
- is 120 seconds.
- memoryStoreEvictionPolicy - Policy would be enforced upon reaching the maxElementsInMemory limit. Default
- policy is Least Recently Used (specified as LRU). Other policies available -
- First In First Out (specified as FIFO) and Less Frequently Used
- (specified as LFU)
- -->
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="false"
- diskPersistent="false"
- diskExpiryThreadIntervalSeconds="120"
- />
- <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
- expirations explicitly. If we set it to false and then set corresponding timeToIdle and timeToLive properties,
- ehcache would evict sessions without Shiro's knowledge, which would cause many problems
- (e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
- Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)
- diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
- even after a JVM restart. -->
- <cache name="shiro-activeSessionCache"
- maxElementsInMemory="10000"
- eternal="true"
- overflowToDisk="true"
- diskPersistent="true"
- diskExpiryThreadIntervalSeconds="600"/>
- <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
- maxElementsInMemory="100"
- eternal="false"
- timeToLiveSeconds="600"
- overflowToDisk="false"/>
- </ehcache>
springmvc.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:context="http://www.springframework.org/schema/context"
- 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">
- <!-- 配置自动扫描的包 -->
- <context:component-scan base-package="com.sheng.example" use-default-filters="false">
- <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
- <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
- </context:component-scan>
- <!--一下内容只能放在springmvc.xml中 不可放在ApplicationContext.xml或ApplicationContext-shiro.xml中-->
- <!--<bean id="exceptionHandler" class="com.sheng.atx.parking.handlers.MyExceptionHandler"/>-->
- <!-- 使 Shiro 的注解起作用, Shiro 的注解标示在方法上. 例如 @RequiresRoles、@RequiresPermissions -->
- <!-- 因为目前是在 Handler 的方法上添加注解, 所以以下的配置需要作用在 SpringMVC 的 IOC 容器中. 而不是其父容器中. -->
- <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
- depends-on="lifecycleBeanPostProcessor"/>
- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
- <property name="securityManager" ref="securityManager"/>
- </bean>
- </beans>
- <!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd" >
- <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">
- <!-- 指定Spring Bean的配置文件所在目录。默认配置在WEB-INF目录下 -->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:applicationContext*.xml</param-value>
- </context-param>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- <servlet>
- <servlet-name>dispatcherServlet</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- <async-supported>true</async-supported>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcherServlet</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- <!-- 配置 Shiro 的 Filter -->
- <filter>
- <filter-name>shiroFilter</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- <async-supported>true</async-supported>
- <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>
- </web-app>
AuthcLevelFilter.java
- package com.sheng.example;
- import org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter;
- import org.apache.shiro.web.util.WebUtils;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.URLEncoder;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Map;
- public class AuthcLevelFilter extends PassThruAuthenticationFilter {
- @SuppressWarnings("deprecation")
- @Override
- protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
- HttpServletResponse httpResponse ;
- HttpServletRequest httpRequest;
- Map<String, Object> map = new HashMap<String, Object>();
- httpResponse = WebUtils.toHttp(response);
- httpRequest = WebUtils.toHttp(request);
- if(isLoginRequest(httpRequest, httpResponse)){
- return true;
- }else {
- WebUtils.saveRequest(request);
- String url = httpRequest.getRequestURI();
- map.put("requestUri", url);
- PrintWriter out=null;
- try {
- httpResponse.setContentType("text/html; charset=utf-8");
- out = httpResponse.getWriter();
- // if (url.equals("/logList.jsp")||url.equals("/parkManager.jsp")) {
- // httpResponse.setContentType("text/html;charset=utf-8");
- // out.append("<script language='javascript'>parent.location='../index.jsp';</script>");
- // }else if(url.equals("/getParkList")||url.equals("/getLogList_admin")||url.equals("/getLogList_park")){
- // PageData pageData=new PageData();
- // pageData.setData(new ArrayList<>());
- // ReturnData ret = new ReturnData();
- // ret.setMessage(URLEncoder.encode("用户未登录,试图访问!","utf-8"));
- // pageData.setOtherData(ret);
- // httpResponse.setCharacterEncoding("UTF-8");
- // httpResponse.setContentType("application/json; charset=utf-8");
- // out.append(JSONObject.toJSONString(pageData));
- // } else if(url.equals("/park/query_coast")) {
- // ReturnData ret = new ReturnData();
- // ret.setStatus(false);
- // ret.setMessage(URLEncoder.encode("用户未登录,试图访问!","utf-8"));
- // out.append(JSONObject.toJSONString(ret));
- // }else{
- // System.out.println("requestUri:" + httpRequest.getRequestURI());
- // httpResponse.setStatus(200, "redirect");
- // httpResponse.setCharacterEncoding("UTF-8");
- // httpResponse.setContentType("application/json; charset=utf-8");
- //
- // ReturnData ret = new ReturnData();
- // ret.setMessage("用户未登录,试图访问!");
- // ret.setData(httpResponse.toString());
- out.append("用户未登录,试图访问!");
- //
- //
- // }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (out != null) {
- out.close();
- }
- }
- return false;
- }
- }
- }
- package com.sheng.example;
- import org.apache.shiro.SecurityUtils;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.UsernamePasswordToken;
- import org.apache.shiro.subject.Subject;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.servlet.ModelAndView;
- /**
- * Created by Administrator on 2017/6/30 0030.
- */
- @Controller
- public class MyController {
- @RequestMapping("test")
- @ResponseBody
- public String index(){
- Subject currentUser = SecurityUtils.getSubject();
- return "Hello:"+currentUser.getPrincipal().toString()+",我是tomcat2";
- }
- @RequestMapping("login")
- public ModelAndView login(String username,String password){
- ModelAndView modelAndView=null;
- Subject subject = SecurityUtils.getSubject();
- UsernamePasswordToken token = new UsernamePasswordToken(username, password);
- try {
- subject.login(token);
- modelAndView=new ModelAndView("test");
- modelAndView.addObject("username",username);
- }catch (AuthenticationException ae){
- modelAndView=new ModelAndView("/");
- modelAndView.addObject("message","用户名或密码错误");
- }
- return modelAndView;
- }
- }
- package com.sheng.example;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.AuthenticationInfo;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.authc.SimpleAuthenticationInfo;
- import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
- import org.apache.shiro.authz.AuthorizationInfo;
- import org.apache.shiro.authz.SimpleAuthorizationInfo;
- import org.apache.shiro.crypto.hash.Md5Hash;
- import org.apache.shiro.crypto.hash.SimpleHash;
- import org.apache.shiro.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.apache.shiro.util.ByteSource;
- /**
- * Created by Administrator on 2017/6/30 0030.
- */
- public class MyRealm extends AuthorizingRealm {
- /**
- * 授权方法:
- * 1. 实际返回的是 SimpleAuthorizationInfo 类的实例
- * 2. 可以调用 SimpleAuthorizationInfo 的 addRole 来添加当前登录 user 的权限信息.
- * 3. 可以调用 PrincipalCollection 参数的 getPrimaryPrincipal() 方法来获取用户信息
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
- SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
- Object principal = principalCollection.getPrimaryPrincipal();
- // User user = userService.getAdmin(principal.toString());
- // if("admin".equals(principal)){
- // info.addRole(user.getRole().getName());
- // System.out.println("用户角色admin");
- // info.addRole("list");
- // }
- // if("user".equals(principal)){
- // info.addRole("list");
- // }
- // info.addRole("user");
- return info;
- }
- /**
- * 认证方法
- * 1. 编写表单: 表单的 action、和 username、password 的参数都是什么 ?
- * 回答: 提交到你想提交的地方, username 和 password 也参数名称都任意.
- * 2. 例如, 提交到了一个 SpringMVC 的 handler:
- * 1). 获取用户名、密码
- * 2).
- * Subject currentUser = SecurityUtils.getSubject();
- * UsernamePasswordToken token = new UsernamePasswordToken(username, password);
- * currentUser.login(token);
- * 3. 当 Subject 调用 login 方法时, 即会触发当前的 doGetAuthenticationInfo 方法. 且把
- * UsernamePasswordToken 对象传入, 然后再该方法中执行真正的认证: 访问数据库进行比对.
- * 1). 获取用户名和密码
- * 2).
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(
- AuthenticationToken token) throws AuthenticationException {
- System.out.println("doGetAuthenticationInfo------->"+token.getPrincipal());
- System.out.println("doGetAuthenticationInfo------->"+token.getCredentials());
- //1. 从 token 中获取登录的 username! 注意不需要获取 password.
- //2. 利用 username 查询数据库得到用户的信息.
- //3. 创建 SimpleAuthenticationInfo 对象并返回. 注意该对象的凭证式从数据库中查询得到的.
- //而不是页面输入的. 实际的密码校验可以交由 Shiro 来完成
- //4. 关于密码加密的事: shiro 的密码加密可以非常非常的复杂, 但实现起来却可以非常简单.
- //1). 可以选择加密方式: 在当前的 realm 中编写一个 public 类型的不带参数的方法, 使用 @PostConstruct
- //注解进行修饰, 在其中来设置密码的匹配方式.
- //2). 设置盐值: 盐值一般是从数据库中查询得到的.
- //3). 调用 new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName)
- //构造器返回 SimpleAuthenticationInfo 对象: credentialsSalt 为
- //ByteSource credentialsSalt = new Md5Hash(source);
- //登陆的主要信息: 可以是一个实体类的对象, 但该实体类的对象一定是根据 token 的 username 查询得到的.
- Object principal = token.getPrincipal();//获取登录名
- //认证信息: 从数据库中查询出来的信息. 密码的比对交给 shiro 去进行比较
- String credentials = "789ecdde95405b37ffafd9c4e460b4a9";
- //设置盐值:
- String source = "abcdefg";
- ByteSource credentialsSalt = new Md5Hash(source);
- // System.out.println(credentialsSalt);
- // User atx_admin=null;
- // try {
- // atx_admin = userService.getAdmin(token.getPrincipal().toString());
- // if(atx_admin.getRole().getName().equals("park_station")){//数据库不加密前台人员密码
- // atx_admin.setPassword(strToMD5(atx_admin.getPassword()));
- // }
- //// System.out.println("数据库密码:" + atx_admin.getPassword());
- // }catch (Exception e){
- // e.printStackTrace();
- // }
- // if(atx_admin==null)
- // throw new AuthenticationException("用户名不存在");
- //当前 Realm 的 name
- String realmName = getName();
- // System.out.println("realmName:"+realmName);
- SimpleAuthenticationInfo info =
- new SimpleAuthenticationInfo(principal, credentials,
- credentialsSalt, realmName);
- return info;
- }
- //@PostConstruct: 相当于 bean 节点的 init-method 配置.
- public void setCredentialMatcher(){
- HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
- credentialsMatcher.setHashAlgorithmName("MD5");
- credentialsMatcher.setHashIterations(1024);
- setCredentialsMatcher(credentialsMatcher);
- }
- public static String strToMD5(String str){
- String saltSource = "abcdefg";
- String hashAlgorithmName = "MD5";//加密方式
- Object salt = new Md5Hash(saltSource);//盐值
- int hashIterations = 1024;//加密次数
- //加密后的密码
- Object result = new SimpleHash(hashAlgorithmName, str, salt, hashIterations);
- return result.toString();
- }
- public static void main(String[] args) {
- String saltSource = "abcdefg";
- String hashAlgorithmName = "MD5";//加密方式
- String credentials = "123";//密码
- Object salt = new Md5Hash(saltSource);//盐值
- int hashIterations = 1024;//加密次数
- //加密后的密码
- Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
- System.out.println(result);
- System.out.println("68f3139a38b232392cc9d3b6ddd762f7".equals(result.toString()));
- }
- }
- package com.sheng.example;
- import org.apache.shiro.codec.Base64;
- import org.apache.shiro.session.Session;
- import redis.clients.jedis.Jedis;
- import redis.clients.jedis.JedisPool;
- import redis.clients.jedis.JedisPoolConfig;
- import java.io.*;
- /**
- * Created by Administrator on 2017/6/30 0030.
- */
- public class RedisClient {
- private static JedisPool pool;
- private static String redisServerIp="192.168.31.7";
- /**
- * 建立连接池 真实环境,一般把配置参数缺抽取出来。
- *
- */
- private static void createJedisPool() {
- // 建立连接池配置参数
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxWaitMillis(1000);
- // 设置最大连接数
- // config.setMaxActive(1000);
- // 设置最大阻塞时间,记住是毫秒数milliseconds
- // config.setMaxWait(1000);
- // 设置空间连接
- config.setMaxIdle(10);
- config.setMaxTotal(100);
- config.setMinIdle(2);
- // 创建连接池
- pool = new JedisPool(config, redisServerIp, 6379);
- }
- /**
- * 在多线程环境同步初始化
- */
- private static synchronized void poolInit() {
- if (pool == null)
- createJedisPool();
- }
- /**
- * 获取一个jedis 对象
- *
- * @return
- */
- private static Jedis getJedis() {
- if (pool == null)
- poolInit();
- return pool.getResource();
- }
- /**
- * 归还一个连接
- *
- * @param jedis
- */
- private static void returnRes(Jedis jedis) {
- pool.returnResource(jedis);
- }
- void set(String sessionId, Session session) {
- jedis = getJedis();
- jedis.append(sessionId, serialize(session));
- returnRes(jedis);
- }
- void replace(String sessionId, Session session) {
- set(sessionId, session);
- }
- Jedis jedis = null;
- void delete(String sessionId) {
- jedis = getJedis();
- jedis.del(sessionId);
- returnRes(jedis);
- }
- Object get(String sessionId) {
- jedis = getJedis();
- Object obj = deserialize(jedis.get(sessionId));
- returnRes(jedis);
- return obj;
- }
- private static Object deserialize(String str) {
- ByteArrayInputStream bis = null;
- ObjectInputStream ois = null;
- try {
- bis = new ByteArrayInputStream(Base64.decode(str));
- ois = new ObjectInputStream(bis);
- return ois.readObject();
- } catch (Exception e) {
- throw new RuntimeException("deserialize session error", e);
- } finally {
- try {
- ois.close();
- bis.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- private static String serialize(Object obj) {
- ByteArrayOutputStream bos = null;
- ObjectOutputStream oos = null;
- try {
- bos = new ByteArrayOutputStream();
- oos = new ObjectOutputStream(bos);
- oos.writeObject(obj);
- return Base64.encodeToString(bos.toByteArray());
- } catch (Exception e) {
- throw new RuntimeException("serialize session error", e);
- } finally {
- try {
- oos.close();
- bos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- public static void main(String[] args){
- Jedis jedisCli = new Jedis("192.168.31.7", 6379); //新建Jedis对象
- jedisCli.select(2); //切换Redis数据库
- jedisCli.set("firstJedis", "hello,Jedis"); //与Redis命令行操作基本一致
- }
- }
RedisSessionDao.java
- package com.sheng.example;
- import org.apache.shiro.session.Session;
- import org.apache.shiro.session.UnknownSessionException;
- import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import java.io.Serializable;
- import java.util.Collection;
- import java.util.Collections;
- /**
- * Created by Administrator on 2017/6/30 0030.
- */
- public class RedisSessionDao extends AbstractSessionDAO {
- private RedisClient sessionCacheClient=new RedisClient();
- Logger log= LoggerFactory.getLogger(getClass());
- public void update(Session session) throws UnknownSessionException {
- log.info("更新seesion,id=[{}]",session.getId().toString());
- try {
- sessionCacheClient.replace(session.getId().toString(), session);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public void delete(Session session) {
- log.info("删除seesion,id=[{}]",session.getId().toString());
- try {
- sessionCacheClient.delete(session.getId().toString());
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public Collection<Session> getActiveSessions() {
- System.out.println("getActiveSessions");
- log.info("获取存活的session");
- return Collections.emptySet();
- }
- @Override
- protected Serializable doCreate(Session session) {
- Serializable sessionId = generateSessionId(session);
- assignSessionId(session, sessionId);
- log.info("创建seesion,id=[{}]",session.getId().toString());
- try {
- sessionCacheClient.set(sessionId.toString(), session);
- } catch (Exception e) {
- log.error(e.getMessage());
- }
- return sessionId;
- }
- @Override
- protected Session doReadSession(Serializable sessionId) {
- log.info("获取seesion,id=[{}]",sessionId.toString());
- Session session = null;
- try {
- session = (Session) sessionCacheClient.get(sessionId.toString());
- } catch (Exception e) {
- log.error(e.getMessage());
- }
- return session;
- }
- }
index.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <!DOCTYPE html>
- <html>
- <body>
- <h2>Hello World!</h2>
- <form action="login">
- <input type="text" name="username">
- <input type="password" name="password">
- <input type="submit" value="提交">
- </form>
- <%=session.getId()%>
- <script>
- <c:if test="${not empty message}">
- alert("${message}");
- </c:if>
- </script>
- </body>
- </html>
打包后放在不同tomcat下 即可实现session共享