简单实现web单点登录
主要参考文档:http://blog.csdn.net/jimmy609/article/details/18605781
1、工程总体结构:

2、修改C:\Windows\System32\drivers\etc\hosts文件,加入以下一段配置:
127.0.0.1 wangyu.prc.sun.com
这样可以保证3个web应用处于同一个域中(和cookie访问有关),并且不用修改作者提供的示例代码。
3、首先看SSOWebDemo1这个应用第一次访问时,
<filter>
<filter-name>SSOFilter</filter-name>
<filter-class>sso.SSOFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SSOFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
其中SSOFilter的doFilter方法如下:
/**
*
* @param request The servlet request we are processing
* @param result The servlet response we are creating
* @param chain The filter chain we are processing
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (debug) log("SSOFilter:doFilter()");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String result="failed";
String url = request.getRequestURL().toString();
String qstring = request.getQueryString();
if (qstring == null) qstring ="";
String cookieValue ="";
javax.servlet.http.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();
//如果携带有cookie信息,则判断该cookie是否有效(即已经成功通过SSO单点认证服务器)
result = SSOService(cookieValue);
if (debug) log("found cookies!");
}
}
}
if (result.equals("failed")) {
//如果没有携带cookie信息或者cookie验证失效,则需要重新登录SSO验证服务器
response.sendRedirect(SSOLoginPage+"?goto="+url);
} else if (qstring.indexOf("logout") > 1) {
if (debug) log("logout action!");
logoutService(cookieValue);
response.sendRedirect(SSOLoginPage+"?goto="+url);
} else {
request.setAttribute("SSOUser",result);
Throwable problem = null;
try {
chain.doFilter(req, res);
} catch(Throwable t) {
problem = t;
t.printStackTrace();
}
if (problem != null) {
if (problem instanceof ServletException) throw (ServletException)problem;
if (problem instanceof IOException) throw (IOException)problem;
sendProcessingError(problem, res);
}
}
}
其中SSOLoginPage 为"http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp",在首次访问这个web应用时会请求这个URI进行SSO登陆验证,否则会调用SSOService方法验证该客户端是否已经通过验证(通过携带的cookie),SSOService方法如下:
private String SSOService(String cookievalue) throws IOException {
String authAction = "?action=authcookie&cookiename=";
HttpClient httpclient = new HttpClient();
GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue);
try {
httpclient.executeMethod(httpget);
String result = httpget.getResponseBodyAsString();
return result;
} finally {
httpget.releaseConnection();
}
}
其中SSOServiceURL为"http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth",所以这个方法会请求URI:
http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth?action=authcookie&cookiename=xxx验证该客户端是否有效。
如果客户端携带的cookie有效则通过该Filter,继续处理该请求。
4、这里的SSO验证使用的是一个Servlet,主要的功能是验证初始的用户名密码是否合法、产生cookie发送到客户端、以及验证客户端的cookie是否有效。
4.1、定义的成员变量
//保存用户信息(对应的用户名和密码)
static private ConcurrentMap<String, String> accounts;
//保存已经登录的用户信息(对应的cookie信息和用户名)
static private ConcurrentMap<String, String> SSOIDs;
ConcurrentMap为线程安全的集合类。
4.2、假设以下的四个用户为合法用户
public void init(ServletConfig config) throws ServletException {
super.init(config);
SSOIDs = new ConcurrentHashMap<String, String>();
accounts = new ConcurrentHashMap<String, String>();
accounts.put("admin", "admin");
accounts.put("wangyu", "wangyu");
accounts.put("paul", "paul");
accounts.put("carol", "carol");
}
4.3、处理该客户端第一次登陆的代码
private void handlerFromLogin(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
String pass = (String) accounts.get(username);
if ((pass == null) || (!pass.equals(password)))
getServletContext().getRequestDispatcher("/failed.html").forward(
request, response);
else {
String gotoURL = request.getParameter("goto");
String newID = createUID();
SSOIDs.put(newID, username);
//登录的用户名和密码合法,往客户端写入一个cookie,值为自定义生成的id(一段字符串加上当前时间)
Cookie wangyu = new Cookie(cookiename, "22222");
wangyu.setDomain(".sun.com");
// 60分钟之内cookie有效
wangyu.setMaxAge(60 * 60);
wangyu.setValue(newID);
wangyu.setPath("/");
response.addCookie(wangyu); System.out.println("login success, goto back url:" + gotoURL);
if (gotoURL != null) {
PrintWriter out = response.getWriter();
response.sendRedirect(gotoURL);
out.close();
}
}
}
4.4、根据客户端传递过来的cookie的值,来判断该cookie是否合法(已登录并有效)
/*
* authentication from cookie, If exists and hold in MAP, return the user
* name as content else return "failed"
*/
/*
* protected String authCookie(HttpServletRequest request){ Cookie[]
* diskCookies = request.getCookies(); if (diskCookies == null) return
* "failed"; for (Cookie cookie : diskCookies){
* if(cookie.getName().equals(cookiename)){ String sessionContent = (String)
* SSOIDs.get(cookie.getValue()); if (sessionContent == null) return
* "failed"; else return sessionContent; }
*
* } return "failed"; }
*/ // static method used by other servlet in the same container
static public String authCookie(String value) {
String result = (String) SSOIDs.get(value);
if (result == null)
result = "failed";
return result;
}
5、SSOWebDemo2的处理逻辑同SSOWebDemo1,也是一个SSOFilter控制单点登陆以及cookie的验证。因为SSOWebDemo1和SSOWebDemo2处在一个cookie的域中,所以SSO验证服务器为SSOWebDemo1产生的cookie,在SSOWebDemo2访问验证服务器时也会携带。
6、运行效果
6.1、环境tomcat6
6.2、访问SSOWebDemo1并登陆


6.3、访问SSOWebDemo2,这次不需要登陆

7、整理代码zip
http://download.csdn.net/detail/hx888/6888221
简单实现web单点登录的更多相关文章
- Web 单点登录(SSO) 实现模型
有网友问起, 前后端分离 架构下的 Web 单点验证 怎么做, 我画了个图 : Temp Token 就 相当于 短信验证码 . Web 单点登录 都可以用这个 模型, 不仅仅是 前后端分离 .
- 也谈SSO,一个简单实用的单点登录Demo
关于SSO(单点登录),百度百科解释如下 : “SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要 ...
- 简单实现Shiro单点登录(自定义Token令牌)
1. MVC Controller 映射 sso 方法. /** * 单点登录(如已经登录,则直接跳转) * @param userCode 登录用户编码 * @param token 登录令牌,令牌 ...
- 常用的两种web单点登录SSO的实现原理
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...
- 使用 JSONP 实现简单的 SSO 单点登录
SSO 即 Single Sign On(单点登录). 一.二级域名之间的单点登录 不需要用到JSONP 或者 p3p 协议,直接使用 COOKIE 就行了,因为顶级域名相同就能实现 COOKIE ...
- 用RSA实现Web单点登录密码的加密传输
在使用通用权限管理系统(吉日嘎拉)的单点登录功能时,对登录密码使用了RSA加密(非对称加密),有使用这个权限管理系统的可参考下. 前端部分,请引用以下几个js文件: <script type=& ...
- SSO单点登录在web上的关键点 cookie跨域
概述 其实WEB单点登录的原理挺简单的,抛开那些复杂的概念,简单来讲讲如何实现一个最基本的单点登录 首先需要有两个程序 例如:http://www.site-a.com 我们简称A http://ww ...
- SSO单点登录PHP简单版
前面做了一个新项目,需要用户资源可以需要共享.由于之前没有做过这样的东西,回家之后,立马网站百度"单点登录".帖子很多,甄别之后,这里列几篇认为比较有营养. http://blog ...
- 基于SAML的单点登录介绍
http://blog.csdn.net/csethcrm/article/details/20694993 一.背景知识: SAML即安全断言标记语言,英文全称是Security Assertion ...
随机推荐
- jQuery clone()方法绑定事件
先看如下代码: (function ($) { var div = $("<div></div>").css({width: "100px&quo ...
- js中style,currentStyle和getComputedStyle的区别
1.style只能获取元素的内联样式,内部样式和外部样式是获取不到的.例子: <div id="test" style="width:100px;height:20 ...
- XPath语法 在C#中使用XPath示例 【转http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html】非常详细的文章
XPath语法 在C#中使用XPath示例 XPath可以快速定位到Xml中的节点或者属性.XPath语法很简单,但是强大够用,它也是使用xslt的基础知识. 示例Xml: <?xml ve ...
- jquery上传插件Jquery.uploadify.js-转
Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示.不过官方提供的实例时php版本的,本文将详细介绍Uploadify在Aspnet中的使用,您也可以点击下面的链接进行演示 ...
- Java 迭代器理解
1.Iterator(迭代器) 作为一种设计模式,迭代器可以用于遍历一个对象,对于这个对象的底层结构不必去了解. java中的Iterator一般称为“轻量级”对象,创建它的代价是比较小的.这里笔者不 ...
- ABAP简单表维护的制作
为了知识的积累,特作了个简单的表维护. 因为自己之前做dynpro程序的时候建了一个Tree node的表,所以就不在此重复.(在表的交付和维护页签中标的属性要是‘允许标准表维护的’) 直接Alt+U ...
- 采用SHELL,通过SQL LOAD导入一定格式的txt文件至数据库中
1. 准备工作,window中可直接通过sqlload直接导入文件,linux下,需要有sqlload的相关软件. 2. SQL脚本(MID_DFDZ.ctl) LOAD DATA INTO TABL ...
- python与字符集编码
讲的比较明白的博客:http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html 以上面博文的汉为例子,汉字的GBK编码是baba, UNIC ...
- 用c#开发苹果应用程序 xamarin.ios方式
NetworkComms网络通信框架序言 Networkcomms网络通信框架来自于英国,支持以xamarin.ios的方式开发苹果应用程序 其开源版本2.3.1中带有一个示例程序,实现聊天功能,只要 ...
- 3D MAX在立方体的使用
3D MAX不会“复用”立方体的顶点-----它直接计算该立方体需要12个三角面,每个三角面需要3个顶点,这样一共是36个顶点-----其实有大量顶点的位置是相同的,但3D MAX不管这些.它认为 ...