SSO单点登录解决方案——Filter方式
SSO单点登录解决方案
2008-11-21 14:26:57| 分类:单点登录 | 标签:|字号大中小 订阅
一般来说,Web应用需要SSO的功能,应该通过以下的交互过程来调用身份认证服务的提供的认证服务:
Web应用中每一个需要安全保护的URL在访问以前,都需要进行安全检查,如果发现没有登录(没有发现认证之后所带的cookie),就重新定向到SSOAuth中的login.jsp进行登录。
登录成功后,系统会自动给你的浏览器设置cookie,证明你已经登录过了。
当你再访问这个应用的需要保护的URL的时候,系统还是要进行安全检查的,但是这次系统能够发现相应的cookie。
有了这个cookie,还不能证明你就一定有权限访问。因为有可能你已经logout,或者cookie已经过期了,或者身份认证服务重起过,这些情况下,你的cookie都可能无效。应用系统拿到这个cookie,还需要调用身份认证的服务,来判断cookie时候真的有效,以及当前的cookie对应的用户是谁。
如果cookie效验成功,就允许用户访问当前请求的资源。
以上这些功能,可以用很多方法来实现:
在每个被访问的资源中(JSP或Servlet)中都加入身份认证的服务,来获得cookie,并且判断当前用户是否登录过。不过这个笨方法没有人会用:-)。
可以通过一个controller,将所有的功能都写到一个servlet中,然后在URL映射的时候,映射到所有需要保护的URL集合中(例如*.jsp,/security/*等)。这个方法可以使用,不过,它的缺点是不能重用。在每个应用中都要部署一个相同的servlet。
Filter是比较好的方法。符合Servlet2.3以上的J2EE容器就具有部署filter的功能。(Filter的使用可以参考JavaWolrd的文章http://www.javaworld.com/javaworld/jw-06-2001/jw-0622-filters.html)Filter是一个具有很好的模块化,可重用的编程API,用在SSO正合适不过。本样例就是使用一个filter来完成以上的功能。
package SSO;
import java.io.*; import java.net.*; import java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.*; import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.methods.GetMethod; public class SSOFilter implements Filter { private FilterConfig filterConfig = null; private String cookieName="WangYuDesktopSSOID"; private String SSOServiceURL= "http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth"; private String SSOLoginPage= "http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp"; public void init(FilterConfig filterConfig) { this.filterConfig = filterConfig; if (filterConfig != null) { if (debug) { log("SSOFilter:Initializing filter"); } } cookieName = filterConfig.getInitParameter("cookieName"); SSOServiceURL = filterConfig.getInitParameter("SSOServiceURL"); SSOLoginPage = filterConfig.getInitParameter("SSOLoginPage"); } ..... ..... } |
以上的初始化的源代码有两点需要说明:一是有两个需要配置的参数 SSOServiceURL和 SSOLoginPage。因为当前的Web应用很可能和身份认证服务(SSOAuth)不在同一台机器上,所以需要让这个filter知道身份认证服务部署的URL,这样才能去调用它的服务。另外一点就是由于身份认证的服务调用是要通过http协议来调用的(在本样例中是这样设计的,读者完全可以设计自己的身份服务,使用别的调用协议,如RMI或SOAP等等),所有笔者引用了apache的commons工具包(详细信息情访问apache 的网站http://jakarta.apache.org/commons/index.html),其中的“httpclient”可以大大简化http调用的编程。
下面看看filter的主体方法doFilter():
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 =""; //检查http请求的head是否有需要的cookie 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则效验其有效性 result = SSOService(cookieValue); if (debug) log("found cookies!"); } } } if (result.equals("failed")) { //效验失败或没有找到cookie,则需要登录 response.sendRedirect(SSOLoginPage+"?goto="+url); } else if (qstring.indexOf("logout") > 1) {//logout服务 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); } } } |
doFilter()方法的逻辑也是非常简单的,在接收到请求的时候,先去查找是否存在期望的cookie值,如果找到了,就会调用SSOService(cookieValue)去效验这个cookie的有效性。如果cookie效验不成功或者cookie根本不存在,就会直接转到登录界面让用户登录;如果cookie效验成功,就不会做任何阻拦,让此请求进行下去。在配置文件中,有下面的一个节点表示了此filter的URL映射关系:只拦截所有的jsp请求。
<filter-mapping>
<filter-name>SSOFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> |
下面还有几个主要的函数需要说明:
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(); } } private void logoutService(String cookievalue) throws IOException { String authAction = "?action=logout&cookiename="; HttpClient httpclient = new HttpClient(); GetMethod httpget = new GetMethod(SSOServiceURL+authAction+cookievalue); try { httpclient.executeMethod(httpget); httpget.getResponseBodyAsString(); } finally { httpget.releaseConnection(); } } |
这两个函数主要是利用apache中的httpclient访问SSOAuth提供的认证服务来完成效验cookie和logout的功能。
其他的函数都很简单,有很多都是我的IDE(NetBeans)替我自动生成的。
4 当前方案的安全局限性
当前这个WEB-SSO的方案是一个比较简单的雏形,主要是用来演示SSO的概念和说明SSO技术的实现方式。有很多方面还需要完善,其中安全性是非常重要的一个方面。
我们说过,采用SSO技术的主要目的之一就是加强安全性,降低安全风险。因为采用了SSO,在网络上传递密码的次数减少,风险降低是显然的,但是当前的方案却有其他的安全风险。由于cookie是一个用户登录的唯一凭据,对cookie的保护措施是系统安全的重要环节:
cookie的长度和复杂度
在本方案中,cookie是有一个固定的字符串(我的姓名)加上当前的时间戳。这样的cookie很容易被伪造和猜测。怀有恶意的用户如果猜测到合法的cookie就可以被当作已经登录的用户,任意访问权限范围内的资源
cookie的效验和保护
在本方案中,虽然密码只要传输一次就够了,可cookie在网络中是经常传来传去。一些网络探测工具(如sniff, snoop,tcpdump等)可以很容易捕获到cookie的数值。在本方案中,并没有考虑cookie在传输时候的保护。另外对cookie的效验也过于简单,并不去检查发送cookie的来源究竟是不是cookie最初的拥有者,也就是说无法区分正常的用户和仿造cookie的用户。
当其中一个应用的安全性不好,其他所有的应用都会受到安全威胁
因为有SSO,所以当某个处于 SSO的应用被黒客攻破,那么很容易攻破其他处于同一个SSO保护的应用。
这些安全漏洞在商业的SSO解决方案中都会有所考虑,提供相关的安全措施和保护手段,例如Sun公司的Access Manager,cookie的复杂读和对cookie的保护都做得非常好。另外在OpneSSO (https://opensso.dev.java.net)的架构指南中也给出了部分安全措施的解决方案。
5 当前方案的功能和性能局限性
除了安全性,当前方案在功能和性能上都需要很多的改进:
当前所提供的登录认证模式只有一种:用户名和密码,而且为了简单,将用户名和密码放在内存当中。事实上,用户身份信息的来源应该是多种多样的,可以是来自数据库中,LDAP中,甚至于来自操作系统自身的用户列表。还有很多其他的认证模式都是商务应用不可缺少的,因此SSO的解决方案应该包括各种认证的模式,包括数字证书,Radius, SafeWord ,MemberShip,SecurID等多种方式。最为灵活的方式应该允许可插入的JAAS框架来扩展身份认证的接口
我们编写的Filter只能用于J2EE的应用,而对于大量非Java的Web应用,却无法提供SSO服务。
在将Filter应用到Web应用的时候,需要对容器上的每一个应用都要做相应的修改,重新部署。而更加流行的做法是Agent机制:为每一个应用服务器安装一个agent,就可以将SSO功能应用到这个应用服务器中的所有应用。
当前的方案不能支持分别位于不同domain的Web应用进行SSO。这是因为浏览器在访问Web服务器的时候,仅仅会带上和当前web服务器具有相同domain名称的那些cookie。要提供跨域的SSO的解决方案有很多其他的方法,在这里就不多说了。Sun的Access Manager就具有跨域的SSO的功能。
另外,Filter的性能问题也是需要重视的方面。因为Filter会截获每一个符合URL映射规则的请求,获得cookie,验证其有效性。这一系列任务是比较消耗资源的,特别是验证cookie有效性是一个远程的http的调用,来访问SSOAuth的认证服务,有一定的延时。因此在性能上需要做进一步的提高。例如在本样例中,如果将URL映射从“.jsp”改成“/*”,也就是说filter对所有的请求都起作用,整个应用会变得非常慢。这是因为,页面当中包含了各种静态元素如gif图片,css样式文件,和其他html静态页面,这些页面的访问都要通过filter去验证。而事实上,这些静态元素没有什么安全上的需求,应该在filter中进行判断,不去效验这些请求,性能会好很多。另外,如果在filter中加上一定的cache,而不需要每一个cookie效验请求都去远端的身份认证服务中执行,性能也能大幅度提高。
另外系统还需要很多其他的服务,如在内存中定时删除无用的cookie映射等等,都是一个严肃的解决方案需要考虑的问题。
文章摘自:http://blog.163.com/anly_liu/blog/static/428323142008102122657786/
SSO单点登录解决方案——Filter方式相关推荐
- 著名ERP厂商的SSO单点登录解决方案介绍一
著名ERP厂商的SSO单点登录解决方案介绍一 参考文章: (1)著名ERP厂商的SSO单点登录解决方案介绍一 (2)https://www.cnblogs.com/wintersun/p/557148 ...
- sso单点登录(票据方式)
sso 单点登录思路,1台服务器作为主站服务器,用来做登录校验产生令牌的 !!!重要一点是 一级域名一致,这样才可以cookie共享. 简单介绍下: 1.用户访问服务器A. 2.A判断他没有登录就携带 ...
- SSO 单点登录解决方案
转自:http://www.blogjava.net/Jack2007/archive/2014/03/11/191795.html 1 什么是单点登陆 单点登录(Single Sign ...
- SSO单点登录解决方案
1 什么是单点登陆 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相 ...
- SSO单点登录三种情况的实现方式详解
SSO单点登录三种情况的实现方式详解 单点登录(SSO--Single Sign On)对于我们来说已经不陌生了.对于大型系统来说使用单点登录可以减少用户很多的麻烦.就拿百度来说吧,百度下面有很多的子 ...
- SSO单点登录重定向解决方案
关注 "Java艺术" 我们一起成长! 继上篇<实现SSO单点登录的思考> 当我们写好SSO单点登录服务的代码后,通过调用接口方式验证,流程看似正常,但开始与前端联调就 ...
- cas跨域单点登录原理_CAS实现SSO单点登录原理
1. CAS 简介 1.1. What is CAS ? CAS ( Central Authentication Service ) 是 Yale 大学发起的一个企业级的.开源的项目,旨 ...
- 构建和实现单点登录解决方案(转载于IBMdeveloperWorks)
将一个开放源码的基于 Java 的身份验证组件集成进 Web 门户中 在现有的应用程序中实现单点登录解决方案(single sign-on,SSO,即登录一次,就可以向所有网络资源验证用户的身份)是非 ...
- 构建和实现单点登录解决方案
将一个开放源码的基于 Java 的身份验证组件集成进 Web 门户中 在现有的应用程序中实现单点登录解决方案(single sign-on,SSO,即登录一次,就可以向所有网络资源验证用户的身份)是非 ...
最新文章
- Azkaban-two_server模式-job任务运行
- JDK 8_jstack命令使用
- 区块链基础语言(二十)——Go语言结构体
- 最强联合!北大清华互相开放本科课程(附课程名单)
- 数据库设计工具-----PD
- 服务器PHPWAMP_IN2安装redis
- matlab中提取裂缝图像,灰度图像中裂缝自动识别和检测方法与流程
- 深度学习笔记:利用预训练模型之特征提取训练小数据集上的图像分类器
- 暑期计划安排+作息时间表
- win10打不开计算机配置似乎是正确的,Win10系统软件打不开提示“并行配置不正确”如何解决...
- 飞凌嵌入式-基于国产A40i核心板-医用呼吸机解决方案
- 2015年腾讯阿里实习生招聘面试经历
- Wopus问答第一期
- 《如何阅读一本书》—[美]莫提默.J.艾德勒、查尔斯.范多伦
- docker 的安装以及简单centos镜像制作、启动
- javax.servlet.ServletException: Could not resolve view with name 'destination/isOtherExist' in servl
- 合并后的58赶集为何驶入新的赛道?
- 王码五笔输入教程(转自电脑报)
- 论文阅读 End-to-End Multi-View Fusion for 3D Object Detection in Lidar Point Clouds
- 【网络安全】MS17-010“永恒之蓝”漏洞的利用
热门文章
- 大数据疫情可视化平台1_基于Hadoop3.2.1、Hive3.1.2、搭建疫情信息可视化系统
- os.environ[‘CUDA_VISIBLE_DEVICES‘]指定GPU后,还是用的“0“卡
- 把php数据转成json格式转换,php将从数据库中获得的数据转换成json格式并输出的方法...
- 怎样能让大腿变细方法 揭秘如何瘦大腿和小腿
- 数据库05子查询,union
- 基于Unity开发实现的坦克游戏设计
- STM32F105RBT6 uart调试
- 第19章 特殊工具与技术【C++】
- 智慧档案室改造建设方案 - 一站式建设智慧档案馆建设方案
- cocoscreator初学笔记001