最简单的单点登陆SSO系统的实现思路

单点登陆系统,像CAS这样的东西大都比较复杂,上首慢,上来就要配个SSL,然后才能走下去,但很多时候我要搞这个SSL干吗呢?我只是需要一个单点登陆系统。至于SSL加密不加密,那是另外一事情,不想一开始就把事情搞得那么复杂!

其实单点登陆的主要思想是:

如果在一个中央(Central)服务器上已经登陆,当我再次登陆一个结盟(Federal)站点的时候,应该能识别我在中央服务器的登陆信息,从而在结盟服务器通过身份验证。主要的活动就是这个。

当在一个服务器上登陆时,我可以产生会话对象,并保存在服务器端,但是我如何在另外一个网站读取它呢?简而言之,就在中央(Central)服务器和结盟(Federal)站点服分别设立如下程序

中央(Central)服务器:

SSOMain,包含如下3个基本功能:

1) SaveSessionToMap

2)ReadTicketFromCookie

3)VlidateTicket

结盟(Federal)站点:

SsoClient,包含如下2个基本功能:

1)请求主站的ReadTicketFromCookie,返回结盟(Federal)站点:

2)请求主站的VlidateTicket,给出当前登陆信息。

废话少说,下面贴出代码。

SSOServlet.java

package sso;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import sso.SSOUserMap;

/**
 * Handles logins for the Central Authentication Service.
 */
public class SSOServlet extends HttpServlet
{
    public SSOUserMap          ssoUserMap = null;

    public static final String CookieName = "ssocookie";

    public void init(ServletConfig config) throws ServletException
    {
        ssoUserMap = new SSOUserMap();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, NullPointerException
    {
        doGet(request, response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, IllegalArgumentException,NullPointerException
    {
        String action = request.getParameter("action");
        if ( action == null )
        {
            if ( request.getParameter("username") != null )
            {
                try
                {
                    String userName = request.getParameter("username");
                    userName = URLEncoder.encode(userName,"GBK");
                    System.out.println("*******************userName=" + userName);
                    ssoUserMap.addUser(userName);

                    Cookie wangyu = new Cookie(CookieName, userName);
                    // wangyu.setDomain(domainname);
                    wangyu.setMaxAge( 24 * 60 * 60 );
                    // String s = "wangzheng";
                    wangyu.setValue(userName);
                    wangyu.setPath("/");
                    response.addCookie(wangyu);
                    response.sendRedirect("ReadCookie2.jsp");
                } catch (Exception e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    response.sendRedirect("ReadCookie2.jsp");
                }
            }    
        } else if ( action.equals("readCookie") )
        {
            String cookieValue = "";
            String ticket = "";
            Cookie[] diskCookies = request.getCookies();

            if ( diskCookies != null )
            {
                for (int i = 0; i < diskCookies.length; i++)
                {
                    if ( diskCookies[i].getName().equals(CookieName) )
                    {
                        cookieValue = diskCookies[i].getValue();
                        // out.print(cookieValue);
                    }
                }
            }
            System.out.println("*******************readCookie=" + cookieValue);
            if ( cookieValue != null && !cookieValue.equals("") )
            {
                //cookieValue = URLDecoder.decode(cookieValue,"GBK");
                ticket = ssoUserMap.getTicket(cookieValue);
                if( ticket == null || ticket.equals("") ){
                    ssoUserMap.addUser(cookieValue);
                    ticket = ssoUserMap.getTicket(cookieValue);
                }
            }
            String gotoURL = request.getParameter("goto");
            if ( gotoURL != null && !gotoURL.equals("") )
                response.sendRedirect(gotoURL + "?ticket=" + ticket);

        } else if ( action.equals("validate") )
        {
            String ticket = request.getParameter("ticket");
            String userName = "";

            try
            {
                userName = ssoUserMap.getUser(ticket);

                System.out.println("*******************ticket=" + ticket
                        + ",userName=" + userName);
                
                userName = URLDecoder.decode(userName,"GBK");
                System.out.println("*******************ticket=" + ticket
                        + ",userName2=" + userName);
                
                response.setContentType("text/html; charset=gb2312");

                PrintWriter out = response.getWriter();
                if ( userName != null && !userName.equals("") )
                    out.println("yes\n" + userName + "\n");
                else
                    out.println("no\n\n");
            } catch (UnsupportedEncodingException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NullPointerException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else if ( action.equals("viewMap") )
        {
            try
            {
                response.setContentType("text/html");

                PrintWriter out = response.getWriter();

                for (Iterator i = ssoUserMap.sso_user_map.entrySet().iterator(); i
                        .hasNext();)
                {
                    Map.Entry e = (Map.Entry) i.next();
                    out.println("<br>*****" + e.getKey() + "=" + e.getValue());
                }
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

java端的 sso.jsp

<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="java.net.*,java.io.*"%>
<%

	//这个程序一般是运行在结盟的服务器上。request.getContextPath()要换成主站的网址.

	String ticket = request.getParameter("ticket");
	if (ticket == null ) {

        //没有ticket,直接调用主站程序去调用读Cookie的程序,读出ticket,再拿过来验证。

		String url = "http://www.centralserver.com:8080/sso/ssoservlet?action=readCookie&goto=goto.jsp";
		response.sendRedirect(url);
		return;

	} else {
		//out.println("====" + ticket);

		//如果有Ticket,那么直接验证,返回用户名。
		String url = "http://www.centralserver.com:8080/sso/ssoservlet?action=validate&ticket=" + ticket;

        URL weblogic = new URL(url);
        BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                    weblogic.openStream()));

        String ret = in.readLine();
		out.println(ret);

	}

%>

PHP client段的代码主要用curl来实现调用central段的VlidateTicket, sso.php

<?php
    $url = 'http://10.144.176.110:6080/share/page/dologin?username=xxxx&password=111111&success=/share&failure=/share/page/type/login';
    $post = 1;
    $returntransfer = 1;
    $port = 80;
    $header = 0;
    $nobody = 0;
    $followlocation = 1;

    $request = '';

    $ch = curl_init();

    $options = array(CURLOPT_URL => $url,
                        CURLOPT_HEADER => $header,
                        CURLOPT_NOBODY => $nobody,
                        CURLOPT_PORT => $port,
                        CURLOPT_POST => $post,
                        CURLOPT_POSTFIELDS => $request,
                        CURLOPT_RETURNTRANSFER => $returntransfer,
                        CURLOPT_FOLLOWLOCATION => $followlocation,
                        //CURLOPT_COOKIEJAR => $cookie_jar,
                        //CURLOPT_COOKIEFILE => $cookie_jar,
                        CURLOPT_ENCODING=>"UTF-8",
                        CURLOPT_REFERER => $url
                        );
    curl_setopt_array($ch, $options);
    
    $temp = "";
    
    echo "<br>temp=".$temp;
    $temp = curl_exec($ch);
    curl_errno($ch);
    curl_close($ch);

    echo "<br>temp=".$temp;
        
?>    

 本文参考了:

 http://www.cnblogs.com/huc87/archive/2009/08/21/1551398.html

 自己的源码:CuteSSO.rar

转载于:https://www.cnblogs.com/youcanwin/archive/2012/11/05/2755398.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值