SSO(Single Sign-On)即所谓的单点登录。用户在一处登录后访问其他网站时不需要再次输入用户名和口令,即可完成身份验证。
文章《体验WebLogic Server 8.1 SP4新增功能之WebLogic Single Sign-On》(http://dev2dev.bea.com.cn/techdoc/200507499.html)中介绍了使用WLS8.1 SP4版本中的Single Pass Negotiate Identity Assertion Provider完成与Windows平台的SSO。但有更多的人可能希望在不借助,或者不与Windows集成的情况下完成Single Sign-On。Kerberos当然可以是其中的一种解决办法,但是目前互联网上应用更多的是SAML,一个用于在网络实体间交换安全认证信息的基于XML的框架。
本文据此提出一种适用(针对)于WebLogic Server的,简单、可行的SSO解决方案。这个方案以集中统一的用户信息为基础,但不包括通常理解的权限管理,而仅仅提供一个身份验证的服务。因为一般情况下,一个企业内部的多个成熟系统通常分别有自己的已经比较完善的用户身份验证和权限管理功能。在这种情况下,为整合多个业务系统而提供包括权限管理在内的多种安全服务,常常将问题复杂化(尽管SAML可以做到这一点)。
因此本文提出的方案将只解决用户的身份验证,即实现SSO的本义。在SSO帮助用户完成身份验证后,由各个业务系统本身的权限管理进行用户行为的进一步控制。这样不仅完成了用户帐号的集中管理(SAML可以完成不同系统间不同帐号的federated但不在本文讨论范围内),又不失原有系统灵活的权限控制。而且方案简单可行,不需要对原有应用做较大更改,适合快速解决Single Sign-On问题。
如果有更复杂的需求,完全可以在本文的基础上,参考Shibboleth(http://shibboleth.internet2.edu/)项目以及SourceID(http://www.sourceid.org/index.html)的项目进行深入的研究和了解,以找出最适合自己的解决方案。
名词
SAML
本文将以SAML 1.1实现SSO。SAML定义了一个用于在线商业系统间交换安全信息的基于XML的框架,它由OASIS (the Organization for the Advancement of Structured Information Standards)组织的Security Services Technical Committee (SSTC)开发。详情参考文章后面的参考资料部分。
OpenSAML
一个开源的SAML1.1实现,本文使用opensaml1.1完成与SAML相关的逻辑处理。OpenSAML是Shibboleth项目的一部分。Shibboleth是一个针对SSO的开源项目。
WebLogic Server
业界领先的J2EE应用服务器。本文的方案以WebLogic Server 8.1SP4为基础。本文附带的Demo应用只能跑在WLS8.1 SP4上,如果8.1SP3等版本需要适当改动。
Identity Assertion Provider
Identity Assertion Provider是WebLogic 7以后提供的众多Provider的一种,它其实就是一个Authentication Provider,只不过它不需要口令来完成用户的身份验证;如果在其他平台比如Tomcat上实现,也可以是一个普通的LoginModule,只需要通过CallbackHandler获取Token然后验证就可以了。
本文附带一个示例的Identity Assertion Provider。
Java KeyStore
本文将附带一个自签名的java key store,它由JDK带的Keytool生成并签名。
Service Provide
服务提供者。就是我们一般理解的业务系统,它通过配置在其上的Identity Assertion Provider完成对用户提交Token的校验,一般又称为SAML Assertion Consumer。文章后面简称为SP。
Identity Provider
身份认证提供者。通过它对用户进行身份验证,以及生成SAML Assertion Token,又称为SAML Assertion Productor。本方案的实现中核心为一个Servlet。文章后面简称为IDP。
Use Case
本文描述的方案实现了SAML 1.1 提供的POST Profile User Case,并有适当修改。
- 用户打开浏览器访问Service Provider 网站,访问受SAML Auth Filter保护的页面
- SP网站的SAML Auth Filter 检查到用户没有登录,那么将用户请求的页面地址(TARGET)附加在IDP的URI之后,并将用户的浏览器重定向到IDP网站
- 否则SP网站接受用户请求
- IDP网站接受到用户请求,判断用户是否已经登录
- 如果用户已经在IDP登录,那么到10
- 如果用户没有在IDP登录,那么向用户响应登录表单
- 用户通过IDP传回的登录表单,输入用户名和口令并提交登录请求
- IDP接受到用户登录请求,使用用户提交的用户名和口令进行身份验证
- 如果验证失败,向用户响应登录失败页面
- 如果登录成功,并且提交的Query String中指定了TARGET,那么会向用户响应一个自动提交表单,将SAML Assertion Token提交到TARGET指定的URL
- SP网站接受到用户提交的SAML Assertion Token,并将Token传递给Identity Assertion Provider
- Identity Assertion Provider校验Token是否合法,并从中读取用户信息
- 如果Token通过验证,Identity Assertion Provider返回经过验证的Subject,否则抛出验证异常
- SP获取到Identity Assertion Provider返回的Subject,表示用户登录成功,返回用户请求的页面
- 否则SP获取到Identity Assertion Provider抛出的LoginException,向用户响应登录失败页面,用户登录失败
技术实现
这里描述一下前面Use Case中涉及的几个技术方面。
- 从安全角度考虑,用户到IDP和SP间的连接必须通过HTTPS,尤其是在外网Internet;对于内部网络Intranet应用可以通过其他办法强化网络安全
- 使用SAML Auth Filter控制哪些页面加入SSO
<filter-mapping>
<filter-name>SAMLAuthFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
这里表示SP全部的页面受SAMLAuthFilter保护。
我们使用 WebLogic提供的 API进行用户身份验证,这样才能完成一个让 WebLogic Server认为是合法的登录。这个weblogic.servlet.security.ServletAuthentication提供的方法具体实现在不同的SP版本中总有变化,比如WLS8.1 SP3和8.1 SP4,因此需要留意这一点。本文方案的实现,以WELS8.1SP4为准。
public static int login(java.lang.String username,
java.lang.String password,
javax.servlet.http.HttpServletRequest request)
throws javax.security.auth.login.LoginException
Returns an int value for AUTHENTICATED or FAILED_AUTHENTICATION after using the username and password to authenticate the user and setting that user information into the session. This method is similar to "weak", except that the LoginException is propogated to caller.
Parameters:
username - String
password - String
request - HttpServletRequest
Returns:
int authentication value
Throws:
javax.security.auth.login.LoginException -
- IDP根据用户信息生成相应的SAML Assertion Token
这里的代码来自于opensaml提供的POSTProfileTest.java,用于生成 SAMLResponse并进行签名
SAMLResponse r = SAMLPOSTProfile.prepare(
"www.opensaml.org",
"www.opensaml.org",
Collections.singleton("http://www.opensaml.org"),
"foo",
"foo",
null,
"127.0.0.1",
"foo",
new Date(),
Collections.singleton(
new SAMLAuthorityBinding(SAMLBinding.SAML_SOAP_HTTPS,
"http://www.opensaml.org",
new QName(XML.SAMLP_NS,"AttributeQuery")
)
)
);
assertNotNull("No SAMLResponse was generated.",r);
Iterator i = r.getAssertions();
((SAMLAssertion)i.next()).sign(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
ks.getKey(alias,password),
Arrays.asList(ks.getCertificateChain(alias))
);
r.sign(
XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1,
ks.getKey(alias,password),
Arrays.asList(ks.getCertificateChain(alias))
);
- Identity Assertion Provider校验IDP生成的Token
具体Identity Assertion Provider的实现超出了本文讨论的篇幅。这里只描述其需要实现的主要逻辑,同样来自于POSTProfileTest.java
assertTrue("SAMLResponse is not signed.",r.isSigned());
System.err.println("================ Generated Response ===============");
r.toStream(System.err);
System.err.println();
r.verify(ks.getCertificate(alias));
SAMLResponse r2 = SAMLPOSTProfile.accept(r.toBase64(), "www.opensaml.org", 60, true);
assertTrue("SAMLResponse is not signed.",r2.isSigned());
SAMLPOSTProfile.getSSOAssertion(r2,Collections.singleton("http://www.opensaml.org")).verify(ks.getCertificate(alias));
r2.verify(ks.getCertificate(alias));
System.err.println("================ Verified Response ===============");
r2.toStream(System.err);
System.err.println();
只要将上面的逻辑放入在Identity Assertion Provider中就可以了。
在IDP响应给用户的页面包含了一个自动提交的表单,将SAML Assertion Token通过HTTP POST提交给用户请求的SP页面。这部分由SAML1.1中的Browser/POST Profile定义。由于生成的SAML Assertion往往比较大,不能通过HTTP GET提交,因此通过自动提交表单完成。这样用户仍然可能会感受到短暂的跳转,如果使用Browser/Artifact Profile,那么将由SP和IDP进行沟通,用户感受会好一点,但是开发,部署均麻烦一些,SP和IDP需要双向SSL,并且opensaml没有提供这个实现,这里就不深入讨论了。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Auto Submit</title>
</head>
<body onLoad="document.myform.submit()">
<form name="myform" action="">
</form>
</body>
</html>
综上,大家看是不是很简单呢?J
Demo的部署和演示
这里介绍附带的几个文件
sp.war
Service Provider应用,可以直接部署在WebLogic Server上。
idp.war
Identity Provider应用。可以直接部署在WebLogic Server上。其中主要就是一个LogonServlet
samlIdentityProvider.jar
这里提供的SAML Identity Assertion Provider只是为了演示使用,如果需要应用在具体的生产环境中,则需要详尽的测试,调优,以及适当的修改。
opensaml.jar
运行OpenSAML需要的jar包,同时它使用了很多第三方的类库,因此这些第三方的jar包也需要,由于文件太大,不在附件中,大家可以去www.opensaml.org下载最新版本。
xbean.jar
包含在WLS8 ${WL_HOME}/server/lib目录下,需要在启动WLS的脚本中加入到classpath中
endorsed
OpenSAML要求使用的XML Parser,在附件中
idp.jks
使用keytool生成的KeyStore,存放了一对密钥
idp.cer
密钥对中的公钥,SP使用它校验Token是否有效
下面介绍Demo的部署过程。
- 解开附件的压缩包,将opensaml.jar以及其使用到的第三方jar包和xbean.jar放在适当地方;将endorsed目录放在适当地方,将在2步骤中使用
- 修改启动WebLogic的脚本,在CLASSPATH中增加指向opensaml.jar以及其第三方jar和xbean.jar(WebLogic8中也带有该jar)的路径,并设置系统变量-Djava.endorsed.dirs=<endorsed目录>
- 为验证SSO需要将sp.war和idp.war分别部署在两台WebLogic Server上。修改idp.war/WEB-INF/web.xml中在path参数中指明idp.jks的文件路径,以及访问keystore的口令123456(这里keystore口令和alias的主口令设置为一致,否则此处需要多设置一个配置项);修改sp.war/WEB-INF/web.xml,在redirectURL参数配置IDP网站的地址,指向SAMLLogon 这个Servlet在IDP上映射的URL。
- 在SP上配置SAML Identity Assertion Provider(IDP所在的WLS不需要配置)
- 将samlSecurityProvider.jar拷贝至 ${WL_HOME}/server/lib/mbeantypes下。如果有Managed Server并且Managed Server在另外一台物理机器上或另外一个独立的WL安装目录下,那么同样需要将samlSecurityProvider.jar拷贝至对应的mbeantypes目录下
- 重新启动全部的Server
- 通过WebLogic Console配置SAML Identity Assertion Provider,在Detail中指明idp.cer证书的路径,别名,以及口令。需要注意一点就是,需要将Base64的选择取消
- 重新启动全部的WebLogic Server
- 在SP和IDP两个系统的WebLogic Server Realm中增加一个测试用户,为sso_user并设置口令,如果SP和IDP部署在同一个WLS Domain,那在WLS Admin Console上做一次就可以了;如果有统一的用户存储,那么部署对应的Authentication Provider就可以了
至此,部署成功。
下面是演示过程:
演示一:
- 访问SP网站的受保护页面http://localhost:19001/sp/index.jsp
- 浏览器被重定向到IDP网站被要求登录
- 输入用户sso_user以及用户口令登录
- 登录成功后浏览器返回 http://localhost:19001/sp/index.jsp页面内容
演示二:
- 访问IDP网站的登录页面 http://localhost:18000/logon
- 在登录表单中输入用户名sso_user和口令
- 登录成功后,显示IDP欢迎页面以及用户登录成功的帐号
- 手工在浏览器中输入地址 http://localhost:19001/sp/index.jsp
- 浏览器显示SP页面内容而不需要再登录
演示三(图片省略):
如果IDP网站当机,那么只是丧失SSO而已,不会影响业务系统的使用,这一点对大的应用来说很重要。
- 访问SP的登录页面 http://localhost:19001/sp/logon.jsp
- 在登录表单中输入用户名sso_user和口令,进行登录
- 登录成功后,欢迎页面显示用户的帐号信息
参考资料
分享到:
相关推荐
WebLogic应用优化解决方案是针对Oracle WebLogic Server这一企业级Java EE应用服务器的性能提升策略。WebLogic Server作为业界广泛使用的中间件平台,其性能优化对于整个企业应用的效率和稳定性至关重要。以下是一些...
weblogic10 与hibernate冲突解决方案 错误如下:org.hibernate.QueryException: ClassNotFoundException: org.hibernate.hql.ast.HqlToken linux windows 环境解决方案全解 Linux 启动脚本添加如下: export USER_...
解决weblogic反序列化安全问题,文档中有详细的操作步骤,已经验证
Yale CAS 是耶鲁大学开发的一种开源的单点登录(SSO)解决方案,提供了一个通用的身份验证框架,允许用户使用单个身份验证来访问多个应用程序。CAS 服务器充当着身份验证服务器的角色,负责验证用户的身份,生成 ...
### WebLogic 9忘记密码解决方案详解 #### 一、问题背景与解决思路 在日常运维工作中,有时因为长时间未操作WebLogic服务器或者设置的密码过于复杂而忘记了密码,这将给系统的管理和维护带来不便。本文将详细介绍...
"将应用部署在Weblogic中与Axis2冲突的问题及解决方案" 问题描述 在将应用部署到Weblogic Server 10.3时,出现了一个错误,抛出ClassCastException异常,具体错误信息为: `java.lang.ClassCastException: ...
【BEA WebLogic Enterprise Platform和ORACLE RAC解决方案】 BEA WebLogic Enterprise Platform是一个全面的Java应用服务器平台,专门设计用于构建、集成、部署和管理大规模的分布式Web、网络和数据库应用程序。它...
在Web应用程序中,`weblogic.xml`文件是一个非常重要的配置文件,用于指定Web应用程序在WebLogic服务器中的特定行为。这个文件通常位于Web应用程序的`WEB-INF`目录下。通过在`weblogic.xml`文件中定义不同的元素,...
WebLogic Web 服务器安全配置基线 本文档规定了 WebLogic Web 服务器安全配置基线,旨在指导系统管理人员进行 WebLogic Web 服务器的安全配置。本文档适用于中国移动集团公司管理信息系统部运行的 WebLogic Web ...
Tomcat和WebLogic中文乱码问题解决方案 在 Java Web 开发中,中文乱码问题一直是困扰开发者的主要问题之一。 Tomcat 和 WebLogic 是两个常用的 web 服务器,都是支持 Servlet 和 JSP 的。然而,在使用这些服务器时...
升级或降级应用的JAR包至与WebLogic兼容的版本也是一个解决方案。 7. **分析类加载顺序**:通过WebLogic的日志或工具,如`jarscan`,可以分析类加载顺序,找出冲突的根源。 8. **使用Maven或Gradle的依赖管理**:...
linux 下weblogic部署web项目,先新建新端口,然后配置用shartxxxx.sh后台启动项目,最后部署项目
财政系统WebLogic服务器负载均衡解决方案 根据预设的负载策略,将不同的访问请求分发到相应的服务器
在IT行业中,开发Java Web项目是一项常见的任务,而Eclipse作为一款强大的集成开发环境(IDE)和WebLogic作为企业级的Java应用服务器,是许多开发者首选的工具组合。本篇文章将详细阐述如何利用Eclipse进行Java Web...
解决方法是修改 web.xml 文件的版本号,将其降低到 2.4 或更低,以便 Weblogic 9.2 能够正确地加载该文件。 在 Weblogic 中,Unmarshaller 是一个将 XML 文件解析为 Java 对象的工具,但是在某些情况下,该工具可能...
在IT行业中,搭建Web工程和部署WebLogic开发环境是开发者必备的技能之一。WebLogic Server是由Oracle公司提供的一个企业级Java EE应用服务器,它为构建、部署和管理企业级应用程序提供了强大的支持。以下是对这个...
但是,安装 Weblogic 可能会遇到各种问题,本文将提供详细的安装步骤和报错解决方案,以帮助用户顺利安装和使用 Weblogic。 一、配置 JDK 环境 在安装 Weblogic 之前,需要先配置 JDK 环境。首先,创建一个目录来...