1. 程式人生 > >web sso 單點登入簡單例項原始碼

web sso 單點登入簡單例項原始碼

首先,單點登入主要目的為多個系統共用同一個身份驗證系統,即:使用者登入A系統,也可以訪問共用同一驗證系統的B系統。

廢話不多說,看例項:

採用三個web專案,實現單點登入。

專案一:SSOAuth

servlet類:AuthServlet

package org.servlet;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns="servlet/AuthServlet",loadOnStartup=1)
public class AuthServlet extends HttpServlet {

    private static final long serialVersionUID = -2655740926477469126L;    
    public AuthServlet() {
        super();
    }

    public void destroy() {
        super.destroy();
    }

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

         doPost(request,response);
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to post.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("進入servlet了");
           DomainName= request.getSession().getServletContext().getInitParameter("DomainName");
           CookName = request.getSession().getServletContext().getInitParameter("CookieName");
               
           System.out.println("---------"+DomainName+"----------------跳轉了-------------"+CookName+"----------------");
           String location =request.getContextPath()+"/login.jsp";
           String ccode =(String) request.getSession().getAttribute("ccode");
           String checkcode =request.getParameter("checkcode");
           if(!checkcode.equals(ccode)){
               response.sendRedirect(location);
           }else{
               String username =request.getParameter("username");
               String userpassword =request.getParameter("userpassword");
               String key =accounts.get(username);
               if(key==null){
                  response.sendRedirect(location);
               }else{
                  if(key.equals(userpassword)){
                      String gotoURL = request.getParameter("goto");
                      String sessionId =request.getSession().getId();
                      Cookie  cookie =new Cookie(CookName,sessionId);
//                    cookie.setDomain(gotoURL);
                      cookie.setMaxAge(100);
//                    cookie.setValue(sessionId);
                      cookie.setPath("/");
                       response.addCookie(cookie);   
                       if (gotoURL != null) {
                             response.sendRedirect(gotoURL);
                             System.out.println("登入成功!!!!"+cookie+"----------------"+sessionId);
                         }else{
                           response.sendRedirect(location);
                         }
                  }else{
                      response.sendRedirect(location);
                  }
               }
           }
    }
    
    

    static private ConcurrentMap<String, String> accounts;
//    static private ConcurrentMap SSOIDs;
    String CookName;
    String DomainName;
    @Override
    public void init(ServletConfig config) throws ServletException {
        
//      SSOIDs = new ConcurrentHashMap<String, String>();
        accounts=new ConcurrentHashMap<String, String>();
        accounts.put("joylife", "123456");
        accounts.put("admin", "123456");
        accounts.put("json", "123456");
    }

}

一個login.jsp頁面:

注:jquery 自己網上下載;


<%@ page language="java" pageEncoding="UTF-8"%>

<%
    String path = request.getContextPath();
    String url =request.getParameter("goto");
%>

<%
    response.setHeader("Pragma","No-cache");
    response.setHeader("Cache-Control","no-cache");
    response.setDateHeader("Expires", 0);
%>    

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
       <title>系統登入介面</title>  
       <script type="text/javascript" src="<%=path %>/js/jquery/jquery-1.7.2.min.js"></script>
       <style type="text/css">
body {
    font: normal 11px auto "Trebuchet MS", Verdana, Arial, Helvetica,sans-serif;
    color: #4f6b72;/*background: #E6EAE9;*/
}
table {
    margin-top: 10%;
    margin-left: 30%;
    border: 1px solid #CCCCFF;
}
table td {
    border: 0px solid #CCCCFF;
    font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
    color: #000000;
}
table input {
    width: 180px;
}
.leftTd {
    text-align: right;
    width: 35%;
}
.centerTd {
    text-align: center;
    font: bold 18px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
    color: #000000;
}
.rightTd {
    text-align: left;
    width: 65%;
}
#btn_ok{
    width: 50px;
}
#btn_clear{
    width: 50px;
}
a{
margin:30px;
}
</style>

<script type="text/javascript">
    $(function(){
        $("#btn_reload").bind("click",function(){
              btn_reload();
        });
         $("#btn_clear").bind("click",function(){
              btn_clear();
        });
         $("#btn_ok").bind("click",function(){
              btn_ok();
        });
    });

 function btn_ok(){
    var result =validateform();
    if(!result){
       return ;
    }
    $("#form").attr("action","servlet/AuthServlet");
    $("#form").submit();
 }

 function btn_reload(){
   $("#image").removeAttr("src");   
   $("#image").attr("src", "<%=path%>/image.jsp?random()*1000");
 }

 function btn_clear(){
      $(":input").not("input[type=button]").each(function(){
         $(this).val("");
      });
 }

 function validateform(){
     var result =true;
      $(":input").not("input[type=button]").each(function(){
        if($(this).val() ==""){
            result=false;
        }
      });
      return result ;
 }
</script>
    </head>
    <body>
       <form id="form" action="login.jsp" method="post">
           <table>
              <tbody>
                  <tr>
                     <td colspan="99" class="centerTd">使用者資訊登入 </td>
                  </tr>
                  <tr>
                     <td class="leftTd"><label>使用者名稱</label></td>
                     <td class="rightTd"><input type="text" name="username" /></td>
                  </tr>
                  <tr>
                       <td class="leftTd"><label>密碼</label></td>
                     <td class="rightTd"><input type="password" name="userpassword" /></td>
                  </tr>
                  <tr>
                     <td class="leftTd"><label>驗證碼</label></td>
                     <td class="rightTd"><input type="text" name="checkcode" />
                         <img src="<%=path%>/image.jsp"id="image" />
                     </td>
                  </tr>
                  <tr >
                     <td class="leftTd"><input type="button" id="btn_ok" value="登入" /></td>
                     <td class="rightTd"><input type="button" id="btn_clear" value="重置" />
                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                         <a href ="javascript:void(0);" id="btn_reload">看不清,換一張</a>
                     </td>
                  </tr>
              </tbody>
           </table>
           <input name="goto" type="hidden" value=<%=url%>/>
       </form>
    </body>
</html>

一個image.jsp頁面:

 <%@ page  pageEncoding = "gb2312" contentType="image/jpeg" import = "javax.imageio.*,java.util.*,java.awt.image.*,java.awt.*" %>

<%!

    //在此處 獲取並生成隨機顏色

    Color getRandColor(Random random, int ff, int cc) {

       if (ff > 255)

           ff = 255;

       if (cc > 255)

           cc = 255;

       int r = ff + random.nextInt(cc - ff);

       int g = ff + random.nextInt(cc - ff);

       int b = ff + random.nextInt(cc - ff);

       return new Color(r, g, b);

    } %>

<%

    //在此處 設定JSP頁面無快取

    response.setHeader( "Pragma" , "No-cache" );

    response.setHeader( "Cache-Control" , "no-cache" );

    response.setDateHeader( "Expires" , 0);

    // 設定圖片的長寬

    int width = 130;
    int height = 30;

    //設定被隨機選取的中文字,此處中文字內容過多,不一一列出,只是舉例說明下。
    String base = "\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u538b\u6162\u53d4\u80cc\u7ec6...省略文字。。。" ;

    //設定 備選隨機漢字的個數

    int length = base.length();

    // 建立快取影象

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

    // 獲取影象
    Graphics g = image.getGraphics();

    // 建立隨機函式的例項

    Random random = new Random();

    //此處 設定影象背景色

    g.setColor(getRandColor(random, 188, 235));

    g.fillRect(0, 0, width, height);

    //設定隨機 備選的字型型別

    String[] fontTypes = { "\u5b8b\u4f53" , "\u65b0\u5b8b\u4f53" ,

           "\u9ed1\u4f53" , "\u6977\u4f53" , "\u96b6\u4e66" };

    int fontTypesLength = fontTypes.length;

    // 在圖片背景上增加噪點,增加圖片分析難度

    g.setColor(getRandColor(random, 180, 199));

    g.setFont( new Font( "Times New Roman" , Font.PLAIN, 14));

    for ( int i = 0; i < 4; i++) {

       g.drawString( "@*@*@*@*@*@*@*" ,

       0, 5 * (i + 2));

    }

    // 取隨機產生的驗證碼 (4 個漢字 )

    // 儲存生成的漢字字串

    String sRand = "" ;

    for ( int i = 0; i < 4; i++) {

       int start = random.nextInt(length);

       String rand = base.substring(start, start + 1);

       sRand += rand;

       // 設定圖片上字型的顏色

       g.setColor(getRandColor(random, 10, 150));

       // 設定字型格式

       g.setFont( new Font(fontTypes[random.nextInt(fontTypesLength)],

       Font.BOLD, 18 + random.nextInt(6)));

       // 將此漢字畫到驗證圖片上面

       g.drawString(rand, 24 * i + 10 + random.nextInt(8), 24);

    }

    // 將驗證碼存入S ession中

    session.setAttribute( "rand" , sRand);

    g.dispose();

    //將 圖象輸出到JSP頁面中

    ImageIO.write(image, "JPEG" , response.getOutputStream());

    //關閉流

    out.clear();

    out=pageContext.pushBody();  

%>

最後web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    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_2_5.xsd">
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>AuthServlet</servlet-name>
    <servlet-class>org.servlet.AuthServlet</servlet-class>
  </servlet>
    
  <servlet-mapping>
    <servlet-name>AuthServlet</servlet-name>
    <url-pattern>/servlet/AuthServlet</url-pattern>
  </servlet-mapping>
 
  <context-param>
  <param-name>DomainName</param-name>
  <param-value>localhost</param-value>
  </context-param>
   <context-param>
  <param-name>CookieName</param-name>
  <param-value>XiaoHaibingDesktopSSOID</param-value>
  </context-param>
 
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

web專案二:SSOWebDemo1

一個index.jsp頁面:

<%@ page language="java"  pageEncoding="UTF-8"%>

<%
String SSOLoginPage =request.getSession().getServletContext().getInitParameter("SSOLoginPage");
String CookieName =request.getSession().getServletContext().getInitParameter("CookieName");
CookieName =CookieName.toLowerCase().trim();
Cookie[] cookies=   request.getCookies();
Cookie loginCookie =null;
String cookname ="";
if(cookies!=null){
    for(Cookie cookie:cookies){
        cookname =cookie.getName().trim().toLowerCase();
       if(CookieName.equals(cookname)){
           loginCookie =cookie;
           break;
       }
    }
}
if(loginCookie==null){
    String url =request.getRequestURL().toString();
    response.sendRedirect(SSOLoginPage+"?goto="+url);
}
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>ssowebdemo1</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">   
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <body>
   <h1 align="center">WELCOME SsoWebDemo1 !</h1>
  </body>
</html>

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    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_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>  
  <context-param>
       <param-name>CookieName</param-name>
       <param-value>
            XiaohaibingDesktopSSOID
       </param-value>
    </context-param>
    <context-param>
       <param-name>SSOLoginPage</param-name>
       <param-value>
           http://localhost:8080/SSOAuth/login.jsp
       </param-value>
    </context-param>  
</web-app>

web專案二:SSOWebDemo2

一個index.jsp頁面:

<%@ page language="java"  pageEncoding="UTF-8"%>

<%
String SSOLoginPage =request.getSession().getServletContext().getInitParameter("SSOLoginPage");
String CookieName =request.getSession().getServletContext().getInitParameter("CookieName");
CookieName =CookieName.toLowerCase().trim();
Cookie[] cookies=   request.getCookies();
Cookie loginCookie =null;
String cookname ="";
if(cookies!=null){
    for(Cookie cookie:cookies){
        cookname =cookie.getName().trim().toLowerCase();
       if(CookieName.equals(cookname)){
           loginCookie =cookie;
           break;
       }
    }
}
if(loginCookie==null){
    String url =request.getRequestURL().toString();
    response.sendRedirect(SSOLoginPage+"?goto="+url);
}
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>ssowebdemo1</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">  
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <body>
    <h1 align="center">WELCOME SsoWebDemo2 !</h1><br>
  </body>
</html>

web.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
    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_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>  
  <context-param>
       <param-name>CookieName</param-name>
       <param-value>
            XiaohaibingDesktopSSOID
       </param-value>
    </context-param>
    <context-param>
       <param-name>SSOLoginPage</param-name>
       <param-value>
            http://localhost:8080/SSOAuth/login.jsp
       </param-value>
    </context-param>    
</web-app>


如此:簡單的單點登入便可實現。本人是將三個專案都是部署到本機上的,但是分別在2個tomcat上,

SSOAuth作為身份驗證系統單獨部署在了一個tomcat上,SSOWebDemo1和SSOWebDemo2是部署在同一個tomcat上。