`
jimmy.shine
  • 浏览: 397672 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java EE和Domino系统间跨域SSO的实现

阅读更多
(转自http://my.donews.com/chenyf97/2007/06/25/j2ee%e5%92%8cdomino%e7%b3%bb%e7%bb%9f%e9%97%b4%e8%b7%
a8%e5%9f%9fsso%e7%9a%84%e5%ae%9e%e7%8e%b0%ef%bc%88%e4%b8%80%ef%bc%89/)

1. SSO需求

单点登录(Single Sign On, SSO)是企业应用集成中最常见的需求。异构系统间往往都有各自的用户管理和身份验证机制,为

避免用户在进行系统切换时频繁输入用户名和密码,因此必须要实现单点登录。

2. SSO原理

说到SSO的原理,先得说一般Web应用的身份验证原理。Web身份验证之所以能成为问题主要在于HTTP协议的无状态性,这导

致了每次HTTP的请求和响应的无关性。而应用的状态保持是大部分应用系统的一般性需求,因此必须借助其他机制,这就是Cookie。

2.1. Cookie的原理

一个Cookie由name、value、domain、path、expires组成。可以给HTTP响应添加Cookie,然后Cookie就作为HTTP响应的

Headers返回给浏览器,例如Domino的登录成功后的Cookie响应头为:

Set-Cookie: DomAuthSessId=1AD479C4D11CD10278A4C523320A6918; path=/

没有设置expires就表示仅在当前浏览器进程生命期内有效,不保存到客户机上;若expires时间大于当前时间,则浏览器在收到

这个 Cookie以后将其写入到客户机文件中,一般是保存在C:\Documents and Settings\Administrator\Cookies\下。

没有设置domain就表示只在当前域内有效。

当客户机再次请求该域内的其他资源时,浏览器会自动将该域内的Cookie附在请求的Headers一起发送给Web服务器,形如:

Cookie: DomAuthSessId=1AD479C4D11CD10278A4C523320A6918

如此Web应用就能够通过读取HTTP请求Headers里面的Cookie值来判断用户身份,这样也就间接实现了HTTP的状态保持需

求。

2.2. SSO原理

了解的Cookie的原理以后就不难理解SSO的原理了。SSO的目的是为了实现两个或多个应用系统间的单点登录,其实现手段无
非是在登录A系统的 同时自动登录到B系统、C系统……,结合Cookie也就是说在SSO登录时同时去A系统、B系统、C系统进行验证,并将来自各系统的Cookie返回给 浏览器,就是这么简单。

一般情况下,做SSO要统一登录界面,这可以通过将各应用系统的登录界面重定向到指定的登录页来实现。

2.3. Cookie的局限

如果仅仅如上所说这么简单,那也就不会创造什么SSO的概念了。问题出在Cookie的domain上。出于浏览器安全的考虑,HTTP响应 Headers中的Cookie的domain只有与HTTP请求域(a.abc.com)一致或为上级域(abc.com)时,Cookie才能生效。

也就是说:

若A、B系统域名分别为a.abc.com和b.abc.com,登录系统A,同时写来自两个系统的Cookie到浏览器,且Cookie的domain设为.abc.com,那么浏览器是可以接受的,SSO成功。

若A、B系统域名分别为a.abc.com和b.xyz.com,登录系统A,同时写来自两个系统的Cookie到浏览器,其中A Cookie的domain设为.abc.com,B Cookie的domain设为.xyz.com,那么浏览器是不可以接受B Cookie的,因为该HTTP请求是来自.abc.com,因此不能写.xyz.com域中的Cookie。

这也就是跨域SSO难题的原因所在。

2.4. 跨域SSO

了解了Cookie的局限和跨域SSO难题所在,也就不难找到解决跨域问题的办法了:由各应用系统中创建各自域的Cookie并返回给浏览器。不要幻想在一个应用中创建所有域的Cookie,这是徒劳的。

至于如何一次性在各应用系统中创建各自域的Cookie并返回给浏览器,这就仁者见仁智者见智了,一般常见的做法是:

在SSO验证成功的返回页中利用JS脚本动态创建隐藏的IFRAME,并将验证信息通过IFRAME的SRC属性的URL参数传递给各应用系统的某 个资源,这些资源可以是动态程序也可以是JS脚本,由各应用系统的动态程序或JS脚本根据传入的参数来完成该应用的验证过程并返回验证通过的 Cookie。

下文说的做法与上略有不同,我的想法是:只在请求哪个应用系统时才进行哪个应用系统的身份验证,而不是一次性全将所有身份都验证完毕。

3. Domino SSO 实现

Domino 的用户信息和身份验证是通过目录(NAMES.NSF )来实现的;J2EE 系统也往往有自己开发的用户管理和身份验证机制。要实现二者的SSO ,可以通过部署统一的身份认证应用来完成。

要部署唯一的SSO 应用有三个选择:

l 扩展Domino 的身份认证功能,提供SSO 服务;

l 扩展J2EE 系统的身份认证功能,提供SSO 服务;

l 部署单独的SSO 应用,提供SSO 服务;

Domino 的身份认证在names.nsf 中进行,登录界面在domcfg.nsf 中,通过提交包含用户名(username )和密码(password )的请求到路径/names.nsf?Login 即可完成验证过程。但Domino 验证是通过其内在机制实现的,没有给开发者提供任何显示的程序代码(如何进行用户名和口令校验的代码),因此无法对Domino 的验证过程直接进行扩展。

J2EE 系统本身的用户管理和身份认证往往都由我们自行设计的,因此可以在此基础上扩展实现单点登录,我们这里采用的即是这种方案。

此外,也可以开发单独的SSO 应用,集成Domino J2EE 系统登录过程,本质上与在J2EE 系统基础上扩展没有区别,这里不再赘述。

3.1. Domino Cookie

前面已经提过SSO 的原理就是Cookie ,所以有必要了解Domino 系统的Cookie

Domino 系统根据服务器配置的不同有两种Cookie 来进行会话状态的维持。


l 单服务器,服务器返回给浏览器的Cookie 名是:DomAuthSessId

l 多个服务器(SSO ),服务器返回给浏览器的Cookie 名是:LtpaToken ,这是IBM 一套轻量级第三方认证标准,自动支持Websphere Lotus 之间的SSO

3.2. Domino系统设置

1. 配置Domino 的登录页

Notes 打开domcfg.nsf 数据库,打开”Sign In Form Mapping “配置文档,设置登录页为domcfg.nsf 里的SSOLoginForm 表单。


2. Domino 登录页重定向到J2EE

Designer 打开domcfg.nsf\SSOLoginForm ,通过脚本将其重定向到SSO 登录页:

js 代码
 
  1. <script language=”javascript”>  
  2. parent.location.href = “http://www.j2ee.com/loginAction.do?method=login&redirectTo=< 计算文本>”;  
  3. </script>  

其中该计算文本为RedirectTo 值,记录用户原始请求的DominoURL

3.3. J2EE系统SSO开发

3.3.1. SSO 登录界面

SSO登录表单中,除了必要的用户名和口令输入框之外,还应有一个属性redirectTo来记录登录后的重定向路径。当用户访问某个受限资源时,系统自动重定向到该登录界面,同时记录该受限资源的路径,当输入用户名和口令并验证成功以后,系统自动将用户重定向到该受限资源处,而不是简单的返回到缺省首页。

3.3.2. SSO 验证程序

J2EE 系统自身的验证还是才有传统的用户名和口令校验方式。当检查来自客户端的访问请求是去往Domino 系统时,将自动进行Domino 的验证并重定向到相应的Domino 页面。自动Domino 验证分为两个步骤:

1. 程序自动从服务器后台通过Http URLConnection 访问Domino 系统并登录,若验证通过则读取相应的Cookie 值;

单服务器的form-based 方式验证获取Cookie 及重定向URL 代码如下:

java 代码
 
  1. URL url = new URL(httpHost + “names.nsf?Login”);  
  2.   
  3. HttpURLConnection.setFollowRedirects(false);  
  4.   
  5. HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();  
  6.   
  7. urlConnection.setDoOutput(true);  
  8.   
  9. OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());  
  10.   
  11. wr.write(”username=” + userName + “&password=” + password);  
  12.   
  13. wr.flush();  
  14.   
  15. wr.close();  
  16.   
  17. urlConnection.connect();  
  18.   
  19. Map
  20.   
  21. for (Iterator<string> it = headerFields.keySet().iterator(); it.hasNext(); ) {  </string>
  22.   
  23. String key = it.next();  
  24.   
  25. if (key != null && key.equals(”Set-Cookie”)) {  
  26.   
  27. String value = urlConnection.getHeaderField(key);  
  28.   
  29. String[] cookies = value.split(”;\\s*”);  
  30.   
  31. for (int i = 0; i < cookies.length; i++) {  
  32.   
  33. String[] cookie = cookies[i].trim().split(”=”);  
  34.   
  35. if (cookie[0].equals(”DomAuthSessId”)) {  
  36.   
  37. successful = true;  
  38.   
  39. loginURL = httpHost + “domcfg.nsf/SSOLoginAction?OpenAgent”;  
  40.   
  41. loginURL += “&cookeName=DomAuthSessId”;  
  42.   
  43. loginURL += “&cookeValue=” + cookie[1];  
  44.   
  45. break;  
  46.   
  47. }  
  48.   
  49. }  
  50.   
  51. }  
  52.   
  53. }  
  54.   
  55. urlConnection.disconnect();  

多服务器(SSO )方式获取Cookie 及重定向URL 代码如下:

java 代码
 
  1. Session session = NotesFactory.createSession(serverName, userName, password);  
  2.   
  3. if (session != null && session.isValid()) {  
  4.   
  5. successful = true;  
  6.   
  7. loginURL = httpHost + “domcfg.nsf/SSOLoginAction?OpenAgent”;  
  8.   
  9. loginURL += “&cookeName=LtpaToken”;  
  10.   
  11. loginURL += “&cookeValue=” + URLEncoder.encode(session.getSessionToken(), “UTF-8″);  
  12.   
  13. }  

2. 程序将获取的Cookie 名称、Cookie 值以及目的资源地址通过URL 参数的方式传给一个Domino 的代理(也即上述代码中的变量loginURL ),由Domino 代理写Cookie 并重定到向目的资源地址。Domino 代理SSOLoginAction 也非常简单,代码示意如下:

Domino 代码
  1. cookieName$ = request.GetParameter(”cookeName”)  
  2.   
  3. cookieValue$ = request.GetParameter(”cookeValue”)  
  4.   
  5. redirectTo$ = request.GetParameter(”redirectTo”)  
  6.   
  7. Print {Set-Cookie:} + cookieName$ + {=} + cookieValue$ + {; path=/}  
  8.   
  9. Print {Location: } + redirectTo$ + {}  

其中request.GetParameter 是自定义类方法,用以获取URL 中的参数值。

如此,J2EE Domino 系统间的跨域SSO 就顺利实现J

分享到:
评论
1 楼 lygydl 2008-03-29  
很不错的一篇文章,单点登录是企业级应用一个难题,由于不同的系统对用户需求的信息不同,且往往是由不同的人开发,如何设计一个适合于大多数应用,且可以扩展的单点登录系统,将是一个有意义的工作。

相关推荐

    基于Andorid的音乐播放器项目改进版本设计.zip

    基于Andorid的音乐播放器项目改进版本设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。

    uniapp-machine-learning-from-scratch-05.rar

    uniapp-machine-learning-from-scratch-05.rar

    game_patch_1.30.21.13250.pak

    game_patch_1.30.21.13250.pak

    【毕业设计-java】springboot-vue计算机学院校友网源码(完整前后端+mysql+说明文档+LunW).zip

    【毕业设计-java】springboot-vue计算机学院校友网源码(完整前后端+mysql+说明文档+LunW).zip

    机器学习-特征工程算法

    特征变换 特征选择

    吸烟数据集 991张原始图片,平均识别率在88.3% coco json格式标注

    吸烟数据集 991张原始图片,平均识别率在88.3% coco json格式标注

    c++万能头文件picture.h

    c++万能头文件picture.h

    spaceX Ship Flight Test 8

    spaceX 动力学分析

    数据科学_Python手册_在线学习资源_教育辅助_1741398259.zip

    python教程学习

    Uniapp 跨平台开发框架的学习资源汇总与应用指导

    内容概要:本文详细整理了与uniapp有关的一系列学习资源及开发工具。首先对官方文档与教程进行梳理,这是学习uni-app的基础部分,涵盖从基本概念到具体开发指引的全方位资料。接着详细介绍了一款专为uni-app打造的高效开发工具HBuilderX的功能特点及其使用指南,并提到了CLI命令行工具可用于完成开发过程中的常规操作任务。同时,指出uni-app所处的强大社区氛围,无论是社区还是论坛都为开发者解决了实际遇到的问题并分享了大量有价值的经验;还提及多个专门为uni-app量身定制的UI框架和丰富的组件库,进一步提高了开发的便捷性和灵活性;最后列举了几类学习资源,诸如视频教程、博客与文章还有相关书籍均能助力新手成长为熟练工。所有这些资源都将有助于深入学习和理解uni-app这个跨平台框架的相关知识点,进而开发出优秀的多平台应用程序。 适用人群:有意进入跨平台移动应用开发领域的初学者,以及希望提升开发技能的专业人士。 使用场景及目标:为想要深入了解或者开始使用uni-app框架进行开发的人群提供完整路径指导;为目标受众建立起一套完整的学习路径来降低入门难度并提升实际操作能力。

    AI Agent 行业研究报告.pdf

    AI Agent 行业研究报告.pdf

    kibana-7.10.2 docker镜像压缩包,百度网盘

    请到网盘中自取压缩包,此包为kibana-7.10.2 镜像压缩包,是通过现有镜像导出来的,主要是为了解决有些机器无法连接外网,导致无法下载镜像 加载镜像: docker load -i kibana-7.10.2.tar 查看镜像: docker images 备注:elk此镜像配套资源,相同版本的elasticsearch和logstash,请在我的资源中搜索其他镜像

    图解AUTOSAR-CP-TcpIp逻辑图打包

    图解AUTOSAR-CP-TcpIp逻辑图打包

    【毕业设计-java】springboot-vue交友网站平台实现源码(完整前后端+mysql+说明文档+LunW).zip

    【毕业设计-java】springboot-vue交友网站平台实现源码(完整前后端+mysql+说明文档+LunW).zip

    海康相机平场矫正对比图

    海康相机平场矫正对比图

    数据科学_Python基础_数据分析_学习资源.zip

    python教程学习

    基于51单片机的蓝牙家电开关控制的设计与实现

    【论文+PPT+代码+开题+任务书】手机APP遥控的相关测试主要完成设计当中按键控制对应继电器是否正确打开以及关上,可以通过观察按下按键时继电器想匹配的LED是否点亮来进行验证。 进入手机APP后,根据APP中的按键分别控制不同的继电器,继电器1这个按键控制对应1号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,1号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,1号指示灯就可以由亮变暗。 如果点击继电器2则控制对应2号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,2号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,2号指示灯就可以由亮变暗。 如果点击继电器3则控制对应3号继电器的开启和关闭,手机蓝牙按下按键由OFF转变为ON那么电控制器件就可以变化一次,3号指示灯就可以由暗变亮了,再次按下手机蓝牙按键由ON转变为OFF电控制器件又变化一次,3号指示灯就可以由亮变暗。 如果点击继电器4则控制对应4号继电器的开启和关闭

    【毕业设计】java-springboot+vue教师人事档案管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip

    【毕业设计】java-springboot+vue教师人事档案管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip

    ChatGPT付费创作系统V3.1.5独立版 WEB端+H5端+小程序端(优化DeepSeek接口)

    ChatGPT付费创作系统V3.1.5独立版 WEB端+H5端+小程序端 (优化DeepSeek推理模型新增 阿里百炼、腾讯云、硅基流动接口) 是基于国外很火的ChatGPT进行开发的Ai智能多端系统。相比传统的问答系统, ChatGPT可以更加准确地理解用户的意图,提供更加精准的答案。同时系统采用了最新的GPT3.5接口与GPT4模型, 同时还支持DeepSeek,LocalAI、Claude3、豆包AI、文心一言,腾讯混元,讯飞星火,通义千问, 智普等等国内外各种大模型接口,视频音乐支持Pika、Runway、SunoAI接口,可以更好地适应不同的应用场景, 支持站点无限多开,支持WEB端、H5端、小程序端, 可以说ChatGPT付费创作系统目前国内相对体验比较好的一款的ChatGPT及多接口AI软件系统。 新增DeepSeek高级通道新增 阿里百炼、腾讯云、硅基流动3个接口、取消 国内AI通道 的敏感词过滤, 修复”高级版DeepSeek“计费bug,修复DeepSeek的上下文关联,支持AI接口输出的reasoning_content字段

Global site tag (gtag.js) - Google Analytics