您的位置:首页 > 其它

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

2017-01-12 19:53 337 查看
单点登陆系统,像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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: