单点登陆

转载:http://blog.csdn.net/xqhys/article/details/63920161?locationNum=3&fps=1

一、什么是单点登录SSO(Single Sign-On)

  SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。

二、单点登录解决了什么问题

  解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录

工程说明

SSO的实现一般会有一个SSO Server,也叫认证系统,同时也会有被认证的系统,如OA系统、采购系统等,他们就相当于SSO Server的client。

为了更形象体现SSO,我写的SSO是有三个工程:一个SSO Server端口为8081,一个OA系统端口为8082,一个采购系统端口为8083。如图:

 
  流程介绍

在整个SSO流程当,有两个流程非常重要,第一个是用户没有登录系统到登录系统的过程;第二是用户在一个系统当中已经登录(例如在OA系统中登录 了),但又想进入另一个系统(例如进入PRO系统)的过程,如果把这两个过程搞定了,那么SSO也就搞定了。我画了两幅图来说明这两个过程。

先看用户没有登录系统到登录系统的过程,如图:


 
 1:用户通过URL访问OA系统。

 2:在OA系统中的filter发现这个URL没有ticket(你暂且就把ticket看做是门票),此时就会跳转到SSO Server。

 3:SSO Server中的filter发现该客户端中的cookie中没有相应信息,也即是一个没有登录的用户,那么会跳转到登录页面。

 4:用户在登录页面填写相应信息,然后通过post方式提交到SSO Server中。

 5:SSO Server会校验用户信息(我为了快,我的校验方式就是要用户名为:admin,同时密码为:1111),同时在cookie中放username。

 6:将生成ticket和username放到JVMCache中,在实际项目应该放到Memcached中,它的用处等下分析。

7,8:就是在用户访问OA系统的URL基础上加上了一个ticket参数,这样跳转到OA系统。

(此时进入OA系统时,filter发现URL是带ticket的,则filter会根据带过来的ticket并通过HttpClient的形式去调用SSO Server中的TicektServlet,这样就会返回用户名,其实这个用户名就是从JVMCache拿到的,同时马上将这个ticket从JVMCache中移除,这样保证一个ticket只会用一次,然后把返回的用户名放到session中)

 9:session中有了用户名,说明用户登录成功了,则会去本应该返问的servlet。

10,11:将OA系统返回的视图给用户。

 

第二过程,用户已经登录成功了,但要访问另一个系统,如图:


 
  1:用户通过URL访问PRO系统。

  2:在PRO系统中的filter发现这个URL没有ticket,此时就会跳转到SSO Server。此时,由于用户登录了,所以cookie中有相应的信息(例如用户名),此时SSO Server中的filter会生成一个ticket。

 3:将生成的ticket和username放到JVMCache中。

 4:就是在用户访问PRO系统的URL基础上加上了一个ticket参数,这样跳转到PRO系统。

(此时进入PRO系统时,filter发现URL是带ticket的,则filter会根据带过来的ticket并通过HttpClient的形式去调用SSO Server中的TicektServlet,这样就会返回用户名,其实这个用户名就是从JVMCache拿到的,同时马上将这个ticket从JVMCache中移除,这样保证一个ticket只会用一次,然后把返回的用户名放到session中)

 5:session中有了用户名,说明用户登录成功了,则会去本应该返问的servlet。

5,7:将PRO系统返回的视图给用户。

 

关键代码

 

先看SSO Server工程中的代码:

pom.xml

(注意:端口为8081)

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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.cloud.sso.server</groupId>  
  5.     <artifactId>sso-server</artifactId>  
  6.     <packaging>war</packaging>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <name>sso-server Maven Webapp</name>  
  9.     <url>http://maven.apache.org</url>  
  10.     <dependencies>  
  11.         <dependency>  
  12.             <groupId>javax.servlet</groupId>  
  13.             <artifactId>servlet-api</artifactId>  
  14.             <version>2.5</version>  
  15.             <scope>provided</scope>  
  16.         </dependency>  
  17.     </dependencies>  
  18.     <build>  
  19.         <finalName>sso-server</finalName>  
  20.         <plugins>  
  21.             <plugin>  
  22.                 <groupId>org.mortbay.jetty</groupId>  
  23.                 <artifactId>jetty-maven-plugin</artifactId>  
  24.                 <version>8.1.9.v20130131</version>  
  25.   
  26.                 <configuration>  
  27.                     <!-- 配置jetty的容器 端口等 -->  
  28.                     <connectors>  
  29.                         <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">  
  30.                             <port>8081</port>  
  31.                             <maxIdleTime>30000</maxIdleTime>  
  32.                         </connector>  
  33.                     </connectors>  
  34.   
  35.                     <!-- 添加一个特殊的端口和控制键(mvn jetty:stop 停止jetty服务) -->  
  36.                     <stopKey>stop</stopKey>  
  37.                     <stopPort>9977</stopPort>  
  38.   
  39.                     <!-- 发现内容改变,进行热部署,默认是0,不热部署 -->  
  40.                     <scanIntervalSeconds>1</scanIntervalSeconds>  
  41.   
  42.                     <!-- 配置web容器 -->  
  43.                     <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>  
  44.   
  45.                     <webAppConfig>  
  46.                         <!-- 项目的根目录,默认是"/" -->  
  47.                         <contextPath>/sso-server</contextPath>  
  48.                         <!-- <descriptor></descriptor> --> <!-- The path to the web.xml file for your webapp -->  
  49.                         <!-- <defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor>   
  50.                             webdefault.xml的路径,若没有配置就是用jetty默认,这个文件在web.xml加载之前加载 -->  
  51.                     </webAppConfig>  
  52.   
  53.                     <!-- 自动部署默认是 automatic -->  
  54.                     <reload>automatic</reload>  
  55.   
  56.                     <systemProperties>  
  57.                         <systemProperty>  
  58.                             <name>org.mortbay.util.URI.charset</name>  
  59.                             <value>UTF-8</value>  
  60.                         </systemProperty>  
  61.                     </systemProperties>  
  62.   
  63.                 </configuration>  
  64.             </plugin>  
  65.         </plugins>  
  66.     </build>  
  67. </project>  

SSO Server中的filter

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.server.filter;  
  2. import java.io.IOException;  
  3. import javax.servlet.Filter;  
  4. import javax.servlet.FilterChain;  
  5. import javax.servlet.FilterConfig;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.http.Cookie;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12. import com.cloud.sso.server.JVMCache;  
  13.   
  14. public class SSOServerFilter implements Filter {  
  15.   
  16.     @Override  
  17.     public void destroy() {  
  18.     }  
  19.   
  20.     @Override  
  21.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  22.         HttpServletRequest request = (HttpServletRequest) servletRequest;  
  23.         HttpServletResponse response = (HttpServletResponse) servletResponse;  
  24.         String service = request.getParameter("service");  
  25.         //String ticket = request.getParameter("ticket");  
  26.         Cookie[] cookies = request.getCookies();  
  27.         String username = "";  
  28.           
  29.         //判断用户是否已经登陆认证中心  
  30.         if (null != cookies) {  
  31.             for (Cookie cookie : cookies) {   
  32.                 if ("sso".equals(cookie.getName())) {  
  33.                     username = cookie.getValue();                
  34.                     break;  
  35.                 }  
  36.             }  
  37.         }  
  38.   
  39. //        if (null == service && null != ticket) {  
  40. //            filterChain.doFilter(servletRequest, servletResponse);  
  41. //            return;  
  42. //        }  
  43.           
  44.         //实现一处登录处处登录  
  45.         if (null != username && !"".equals(username)) {  
  46.             long time = System.currentTimeMillis();  
  47.             //生成认证凭据--ticket  
  48.             String ticket = username + time;  
  49.             JVMCache.TICKET_AND_NAME.put(ticket, username);  
  50.             StringBuilder url = new StringBuilder();  
  51.             url.append(service);  
  52.               
  53.             if (0 <= service.indexOf("?")) {  
  54.                 url.append("&");  
  55.             } else {  
  56.                 url.append("?");  
  57.             }  
  58.             //返回给用户一个认证的凭据--ticket  
  59.             url.append("ticket=").append(ticket);  
  60.             response.sendRedirect(url.toString());  
  61.               
  62.         } else {  
  63.             filterChain.doFilter(servletRequest, servletResponse);  
  64.         }  
  65.     }  
  66.   
  67.     @Override  
  68.     public void init(FilterConfig arg0) throws ServletException {  
  69.     }  
  70.   
  71. }  

两个servlet:

[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.server.servlet;  
  2. import java.io.IOException;  
  3. import javax.servlet.ServletException;  
  4. import javax.servlet.http.Cookie;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8. import com.cloud.sso.server.JVMCache;  
  9.   
  10. public class LoginServlet extends HttpServlet {  
  11.     private static final long serialVersionUID = -3170191388656385924L;  
  12.   
  13.     @Override  
  14.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  15.         this.doPost(request, response);  
  16.     }  
  17.   
  18.     @Override  
  19.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  20.         String username = request.getParameter("username");  
  21.         String password = request.getParameter("password");  
  22.         String service = request.getParameter("service");  
  23.   
  24.         //判断用户名和密码是否正确  
  25.         if ("admin".equals(username) && "1111".equals(password)) {  
  26.             Cookie cookie = new Cookie("sso", username);  
  27.             cookie.setPath("/");  
  28.             response.addCookie(cookie);  
  29.   
  30.             long times = System.currentTimeMillis();  
  31.             //生成认证凭据--ticket  
  32.             String ticket = username + times;  
  33.             JVMCache.TICKET_AND_NAME.put(ticket, username);  
  34.   
  35.             if (null != service) {  
  36.                 StringBuilder url = new StringBuilder();  
  37.                 url.append(service);  
  38.                 if (0 <= service.indexOf("?")) {  
  39.                     url.append("&");  
  40.                 } else {  
  41.                     url.append("?");  
  42.                 }  
  43.                 //返回给用户一个认证的凭据--ticket  
  44.                 url.append("ticket=").append(ticket);  
  45.                 response.sendRedirect(url.toString());  
  46.                   
  47.             } else {  
  48.                 response.sendRedirect("/sso-server/index.jsp");  
  49.             }  
  50.               
  51.         } else {  
  52.             response.sendRedirect("/sso-server/index.jsp?service=" + service);  
  53.         }  
  54.     }  
  55.   
  56. }  
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.server.servlet;  
  2. import java.io.IOException;  
  3. import java.io.PrintWriter;  
  4. import javax.servlet.ServletException;  
  5. import javax.servlet.http.HttpServlet;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8. import com.cloud.sso.server.JVMCache;  
  9.   
  10. /**  
  11.  * HttpClient调用这个Servlet获取username  
  12.  * @author Hys  
  13.  *  
  14.  */  
  15. public class TicketServlet extends HttpServlet {  
  16.     private static final long serialVersionUID = 5964206637772848290L;  
  17.   
  18.     @Override  
  19.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  20.         super.doGet(request, response);  
  21.     }  
  22.   
  23.     @Override  
  24.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  25.         String ticket = request.getParameter("ticket");  
  26.         String username = JVMCache.TICKET_AND_NAME.get(ticket);  
  27.         //保证一个ticket只会用一次  
  28.         JVMCache.TICKET_AND_NAME.remove(ticket);  
  29.         PrintWriter writer = response.getWriter();  
  30.         writer.write(username);  
  31.     }  
  32.   
  33. }  

JVMCache.Java

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.server;  
  2. import java.util.HashMap;  
  3. import java.util.Map;  
  4.   
  5. public class JVMCache {  
  6.     //存放username,再通过HttpClient获取(在实际项目应该放到Memcached中)  
  7.     public static Map<String, String> TICKET_AND_NAME = new HashMap<String, String>();  
  8. }  

web.xml

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  3.     <welcome-file-list>  
  4.         <welcome-file>index.jsp</welcome-file>  
  5.     </welcome-file-list>  
  6.   
  7.     <filter>  
  8.         <filter-name>ssoServerFilter</filter-name>  
  9.         <filter-class>com.cloud.sso.server.filter.SSOServerFilter</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>ssoServerFilter</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15.   
  16.     <servlet>  
  17.         <servlet-name>login</servlet-name>  
  18.         <servlet-class>com.cloud.sso.server.servlet.LoginServlet</servlet-class>  
  19.     </servlet>  
  20.     <servlet-mapping>  
  21.         <servlet-name>login</servlet-name>  
  22.         <url-pattern>/user/login</url-pattern>  
  23.     </servlet-mapping>  
  24.   
  25.     <servlet>  
  26.         <servlet-name>ticket</servlet-name>  
  27.         <servlet-class>com.cloud.sso.server.servlet.TicketServlet</servlet-class>  
  28.     </servlet>  
  29.     <servlet-mapping>  
  30.         <servlet-name>ticket</servlet-name>  
  31.         <url-pattern>/ticket</url-pattern>  
  32.     </servlet-mapping>  
  33. </web-app>  

下面是OA系统中的代码:

pom.xml

(注意:端口为8082)

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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.cloud.sso.oa</groupId>  
  5.     <artifactId>sso-oa</artifactId>  
  6.     <packaging>war</packaging>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <name>sso-oa Maven Webapp</name>  
  9.     <url>http://maven.apache.org</url>  
  10.     <dependencies>  
  11.         <dependency>  
  12.             <groupId>javax.servlet</groupId>  
  13.             <artifactId>servlet-api</artifactId>  
  14.             <version>2.5</version>  
  15.             <scope>provided</scope>  
  16.         </dependency>  
  17.         <dependency>  
  18.             <groupId>commons-httpclient</groupId>  
  19.             <artifactId>commons-httpclient</artifactId>  
  20.             <version>3.1</version>  
  21.         </dependency>  
  22.     </dependencies>  
  23.     <build>  
  24.         <finalName>sso-oa</finalName>  
  25.         <plugins>  
  26.             <plugin>  
  27.                 <groupId>org.mortbay.jetty</groupId>  
  28.                 <artifactId>jetty-maven-plugin</artifactId>  
  29.                 <version>8.1.9.v20130131</version>  
  30.   
  31.                 <configuration>  
  32.                     <!-- 配置jetty的容器 端口等 -->  
  33.                     <connectors>  
  34.                         <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">  
  35.                             <port>8082</port>  
  36.                             <maxIdleTime>30000</maxIdleTime>  
  37.                         </connector>  
  38.                     </connectors>  
  39.   
  40.                     <!-- 添加一个特殊的端口和控制键(mvn jetty:stop 停止jetty服务) -->  
  41.                     <stopKey>stop</stopKey>  
  42.                     <stopPort>9966</stopPort>  
  43.   
  44.                     <!-- 发现内容改变,进行热部署,默认是0,不热部署 -->  
  45.                     <scanIntervalSeconds>1</scanIntervalSeconds>  
  46.   
  47.                     <!-- 配置web容器 -->  
  48.                     <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>  
  49.   
  50.                     <webAppConfig>  
  51.                         <!-- 设置项目的虚拟根目录,默认是"/" -->  
  52.                         <contextPath>/sso-oa</contextPath>  
  53.                         <!-- <descriptor></descriptor> --> <!-- The path to the web.xml file for your webapp -->  
  54.                         <!-- <defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor>   
  55.                             webdefault.xml的路径,若没有配置就是用jetty默认,这个文件在web.xml加载之前加载 -->  
  56.                     </webAppConfig>  
  57.   
  58.                     <!-- 自动部署默认是 automatic -->  
  59.                     <reload>automatic</reload>  
  60.   
  61.                     <systemProperties>  
  62.                         <systemProperty>  
  63.                             <name>org.mortbay.util.URI.charset</name>  
  64.                             <value>UTF-8</value>  
  65.                         </systemProperty>  
  66.                     </systemProperties>  
  67.   
  68.                 </configuration>  
  69.             </plugin>  
  70.         </plugins>  
  71.     </build>  
  72. </project>  

OA系统中的filter:

SSOClientFilter.java

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.oa.filter;  
  2. import java.io.IOException;  
  3. import java.net.URLEncoder;  
  4. import javax.servlet.Filter;  
  5. import javax.servlet.FilterChain;  
  6. import javax.servlet.FilterConfig;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.ServletRequest;  
  9. import javax.servlet.ServletResponse;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12. import javax.servlet.http.HttpSession;  
  13. import org.apache.commons.httpclient.HttpClient;  
  14. import org.apache.commons.httpclient.methods.PostMethod;  
  15.   
  16. public class SSOClientFilter implements Filter {  
  17.   
  18.     @Override  
  19.     public void destroy() {  
  20.     }  
  21.   
  22.     @Override  
  23.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  24.         HttpServletRequest request = (HttpServletRequest) servletRequest;  
  25.         HttpServletResponse response = (HttpServletResponse) servletResponse;  
  26.         HttpSession session = request.getSession();  
  27.         String username = (String) session.getAttribute("username");  
  28.         String ticket = request.getParameter("ticket");  
  29.         String url = URLEncoder.encode(request.getRequestURL().toString(), "UTF-8");  
  30.         System.out.println("用户名1:"+username);  
  31.         //判断用户是否已经登录oa系统  
  32.         if (null == username) {           
  33.             //1.判断用户是否有认证凭据--ticket(认证中心生成)  
  34.             if (null != ticket && !"".equals(ticket)) {  
  35.                 PostMethod postMethod = new PostMethod("http://localhost:8081/sso-server/ticket");  
  36.                 //给url添加新的参数  
  37.                 postMethod.addParameter("ticket", ticket);  
  38.                 HttpClient httpClient = new HttpClient();  
  39.                 try {  
  40.                     //通过httpClient调用SSO Server中的TicektServlet  
  41.                     httpClient.executeMethod(postMethod);  
  42.                     //将HTTP方法的响应正文(如果有)返回为String  
  43.                     username = postMethod.getResponseBodyAsString();  
  44.                     //释放此HTTP方法正在使用的连接  
  45.                     postMethod.releaseConnection();  
  46.                 } catch (Exception e) {  
  47.                     e.printStackTrace();  
  48.                 }  
  49.                   
  50.                 //2.判断认证凭据是否有效  
  51.                 if (null != username && !"".equals(username)) {  
  52.                     //session设置用户名,说明用户登录成功了  
  53.                     session.setAttribute("username", username);  
  54.                     filterChain.doFilter(request, response);  
  55.                 } else {  
  56.                     response.sendRedirect("http://localhost:8081/sso-server/index.jsp?service=" + url);  
  57.                 }  
  58.                   
  59.             } else {//第一次访问oa系统,需要到sso-server系统验证  
  60.                 response.sendRedirect("http://localhost:8081/sso-server/index.jsp?service=" + url);  
  61.             }  
  62.               
  63.         } else {  
  64.             filterChain.doFilter(request, response);  
  65.         }  
  66.     }  
  67.   
  68.     @Override  
  69.     public void init(FilterConfig arg0) throws ServletException {  
  70.     }  
  71.   
  72. }  

OAServlet.java

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.oa.servlet;  
  2. import java.io.IOException;  
  3. import javax.servlet.ServletException;  
  4. import javax.servlet.http.HttpServlet;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7.   
  8. public class OAServlet extends HttpServlet {  
  9.     private static final long serialVersionUID = 3615122544373006252L;  
  10.   
  11.     @Override  
  12.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  13.         request.getRequestDispatcher("/WEB-INF/jsp/welcome.jsp").forward(request, response);  
  14.     }  
  15.   
  16.     @Override  
  17.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  18.         this.doGet(request, response);  
  19.     }  
  20.   
  21.       
  22. }  

web.xml

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  3.     <welcome-file-list>  
  4.         <welcome-file>index.jsp</welcome-file>  
  5.     </welcome-file-list>  
  6.   
  7.    <filter>  
  8.         <filter-name>ssoClientFilter</filter-name>  
  9.         <filter-class>com.cloud.sso.oa.filter.SSOClientFilter</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>ssoClientFilter</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15.   
  16.     <servlet>  
  17.         <servlet-name>list</servlet-name>  
  18.         <servlet-class>com.cloud.sso.oa.servlet.OAServlet</servlet-class>  
  19.     </servlet>  
  20.     <servlet-mapping>  
  21.         <servlet-name>list</servlet-name>  
  22.         <url-pattern>/list</url-pattern>  
  23.     </servlet-mapping>  
  24.       
  25. </web-app>  

下面是PRO系统的代码:

pom.xml

(注意:端口为8083)

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  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.cloud.sso.pro</groupId>  
  5.   <artifactId>sso-pro</artifactId>  
  6.   <packaging>war</packaging>  
  7.   <version>0.0.1-SNAPSHOT</version>  
  8.   <name>sso-pro Maven Webapp</name>  
  9.   <url>http://maven.apache.org</url>  
  10.     
  11.   <dependencies>  
  12.     <dependency>  
  13.           <groupId>javax.servlet</groupId>  
  14.           <artifactId>servlet-api</artifactId>  
  15.           <version>2.5</version>  
  16.           <scope>provided</scope>  
  17.       </dependency>  
  18.       <dependency>  
  19.           <groupId>commons-httpclient</groupId>  
  20.           <artifactId>commons-httpclient</artifactId>  
  21.           <version>3.1</version>   
  22.       </dependency>  
  23.   </dependencies>  
  24.     
  25.   <build>  
  26.     <finalName>sso-pro</finalName>  
  27.     <plugins>  
  28.             <plugin>  
  29.                 <groupId>org.mortbay.jetty</groupId>  
  30.                 <artifactId>jetty-maven-plugin</artifactId>  
  31.                 <version>8.1.9.v20130131</version>  
  32.                   
  33.                 <configuration>                 
  34.                     <!-- 配置jetty的容器 端口等 -->  
  35.                     <connectors>  
  36.                         <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">  
  37.                             <port>8083</port>  
  38.                             <maxIdleTime>30000</maxIdleTime>  
  39.                         </connector>  
  40.                     </connectors>  
  41.                       
  42.                     <!-- 添加一个特殊的端口和控制键(mvn jetty:stop 停止jetty服务) -->  
  43.                     <stopKey>stop</stopKey>  
  44.                     <stopPort>6000</stopPort>  
  45.                       
  46.                     <!-- 发现内容改变,进行热部署,默认是0,不热部署 -->  
  47.                     <scanIntervalSeconds>1</scanIntervalSeconds>  
  48.                       
  49.                     <!-- 配置web容器 -->  
  50.                     <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>  
  51.                       
  52.                     <webAppConfig>  
  53.                         <!-- 设置项目的虚拟根目录,默认是"/" -->  
  54.                         <contextPath>/sso-pro</contextPath>  
  55.                         <!-- <descriptor></descriptor> --> <!-- The path to the web.xml file for your webapp -->  
  56.                         <!-- <defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor>  webdefault.xml的路径,若没有配置就是用jetty默认,这个文件在web.xml加载之前加载 -->  
  57.                     </webAppConfig>  
  58.                       
  59.                     <!-- 自动部署默认是 automatic -->  
  60.                     <reload>automatic</reload>  
  61.                       
  62.                     <systemProperties>  
  63.                         <systemProperty>  
  64.                             <name>org.mortbay.util.URI.charset</name>  
  65.                             <value>UTF-8</value>  
  66.                         </systemProperty>  
  67.                     </systemProperties>  
  68.                       
  69.                 </configuration>  
  70.             </plugin>  
  71.         </plugins>  
  72.   </build>  
  73. </project>  

PRO系统中的filter

SSOClientFilter.java

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.pro.filter;  
  2. import java.io.IOException;  
  3. import java.net.URLEncoder;  
  4. import javax.servlet.Filter;  
  5. import javax.servlet.FilterChain;  
  6. import javax.servlet.FilterConfig;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.ServletRequest;  
  9. import javax.servlet.ServletResponse;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12. import javax.servlet.http.HttpSession;  
  13. import org.apache.commons.httpclient.HttpClient;  
  14. import org.apache.commons.httpclient.methods.PostMethod;  
  15.   
  16. public class SSOClientFilter implements Filter {  
  17.   
  18.     @Override  
  19.     public void destroy() {  
  20.     }  
  21.   
  22.     @Override  
  23.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {  
  24.         HttpServletRequest request = (HttpServletRequest) servletRequest;  
  25.         HttpServletResponse response = (HttpServletResponse) servletResponse;  
  26.         HttpSession session = request.getSession();  
  27.         String username = (String) session.getAttribute("username");  
  28.         String ticket = request.getParameter("ticket");  
  29.         String url = URLEncoder.encode(request.getRequestURL().toString(), "UTF-8");  
  30.   
  31.         if (null == username) {  
  32.             if (null != ticket && !"".equals(ticket)) {  
  33.                 PostMethod postMethod = new PostMethod("http://localhost:8081/sso-server/ticket");  
  34.                 postMethod.addParameter("ticket", ticket);  
  35.                 HttpClient httpClient = new HttpClient();  
  36.                 try {  
  37.                     httpClient.executeMethod(postMethod);  
  38.                     username = postMethod.getResponseBodyAsString();  
  39.                     postMethod.releaseConnection();  
  40.                 } catch (Exception e) {  
  41.                     e.printStackTrace();  
  42.                 }  
  43.                 if (null != username && !"".equals(username)) {  
  44.                     session.setAttribute("username", username);  
  45.                     filterChain.doFilter(request, response);  
  46.                 } else {  
  47.                     response.sendRedirect("http://localhost:8081/sso-server/index.jsp?service=" + url);  
  48.                 }  
  49.             } else {  
  50.                 response.sendRedirect("http://localhost:8081/sso-server/index.jsp?service=" + url);  
  51.             }  
  52.         } else {  
  53.             filterChain.doFilter(request, response);  
  54.         }  
  55.     }  
  56.   
  57.     @Override  
  58.     public void init(FilterConfig arg0) throws ServletException {  
  59.     }  
  60.   
  61. }  

ProServlet.java

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package com.cloud.sso.pro.servlet;  
  2. import java.io.IOException;  
  3. import javax.servlet.ServletException;  
  4. import javax.servlet.http.HttpServlet;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7.   
  8. public class ProServlet extends HttpServlet {  
  9.     private static final long serialVersionUID = -1334093914490423930L;  
  10.   
  11.     @Override  
  12.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  13.         request.getRequestDispatcher("/WEB-INF/jsp/welcome.jsp").forward(request, response);  
  14.     }  
  15.       
  16.     @Override  
  17.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  18.         super.doPost(request, response);  
  19.     }  
  20.   
  21. }  

web.xml

 
[html]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">  
  3.     <welcome-file-list>  
  4.         <welcome-file>index.jsp</welcome-file>  
  5.     </welcome-file-list>  
  6.   
  7.     <filter>  
  8.         <filter-name>ssoClientFilter</filter-name>  
  9.         <filter-class>com.cloud.sso.pro.filter.SSOClientFilter</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>ssoClientFilter</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15.   
  16.     <servlet>  
  17.         <servlet-name>list</servlet-name>  
  18.         <servlet-class>com.cloud.sso.pro.servlet.ProServlet</servlet-class>  
  19.     </servlet>  
  20.     <servlet-mapping>  
  21.         <servlet-name>list</servlet-name>  
  22.         <url-pattern>/list</url-pattern>  
  23.     </servlet-mapping>  
  24. </web-app>  

运行结果:

1:分别启动这三个工程。

2:访问OA系统,URL:http://localhost:8082/oa/list

3:这样到登录页面,如图:

  
 
 

4:用户名为:admin,密码为:1111,点击登录则会显示,如图:


 
 

 

5:然后去进入PRO系统,URL:http://localhost:8083/pro/list,则就不需要登录了,直接进入,如图:



奉上源码:http://pan.baidu.com/s/1qYHbhRe 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值