在一些典型的公司Web应用程序安全部署中,访问受保护应用程序的用户通过企业身份/访问管理产品,如Netegrity 的 SiteMinder,IBM 的WebSEAL 和Oblix 的 Oblix COREid。然而,身份验证服务被委派给应用程序自身的提供程序或应用服务器。
应用服务器根据Web应用程序部署描述文件中定义的安 全约束来授权用户。然而,在已配置安全约束用于提供身份验证之前,Web容器需要确定用户经过了身份验证才能开始工作。也就是说,前端访问管理器需要提供 一些信息给后端Web容器,以保证Web容器不会试图重新认证经过身份验证的用户。要实现这一点,前端访问管理器可能需要把用户凭证(用户名/密码)交给 后端服务器。然而,这会由于下面两个原因受挫:
- 在典型部署中,前端身份管理软件和后端应用服务器之间的连接不通过安全套接字层(SSL),这意味着用户证书将以非加密的纯文本形式传递。
- 即使连接是安全的,后端服务器仍会用前端访问管理器传来的证书,对已认证的用户再进行一次身份验证,除非它能验证请求来自一个可靠来源,即已认证的用户。
这一情形需要进行周边身份验证,也就是只能在前端访问管理器对用户进行身份验证。BEA WebLogic Server 为实现身份断言提供了Identity Assertion。本文为您详细分析了WebLogic Server中Identity Assertion的实现。建议您先回顾http://e-docs.bea.com/wls/docs81/dvspisec/ia.html中Identity Assertion提供程序的产品文档。
简介
从高级观点出发,Identity Assertion是通过从前端访问管理器向后端应用服务器传递令牌来实现的。从根本上来说,断言是关于主体(比如用户)的一些事实(陈述)的声明。令牌 是从一个系统传到另一系统的一条信息,它可被用于确认某个特定用户的身份。令牌和断言相结合,即构成了Identity Assertion的基础。本质上,Identity Assertion提供程序是一种特殊的身份验证形式,它让用户或系统流程能使用令牌进行身份断言。
Web应用程序安全
在介绍Identity Assertion的实现细节前,让我们简要说明Web应用程序安全模式的原理。servlet规 范提供了通过servlet容器实现Web应用程序安全的指导方针。规范指定的两种安全形式是声明性的和程序性的。当Web应用程序安全为声明性时,安全 性通过部署符(web.xml)在应用程序之外进行配置。身份验证方法,或者说提示用户登录的方法,将通过Web描述符文件web.xml中 的<login-config>元素来指定。如果登录配置出现并且包含一个不为零的值,在访问任何<security- constraint>约束的资源之前,用户必须进行身份验证。
当用户试图访问受保护的Web资源时,Web容器就会激活身份验证机制,该身份验证机制已经为部署描述文件(web.xml)中的资源进行了配置,它位于<login-config>元素内部的<auth-method>标签之间,就像这样:
<login-config><auth-method>BASIC</auth-method></login-config>
以下是实现Web应用程序安全的有效身份验证方法:
- NONE:不提示用户进行身份验证。
- BASIC:Web服务器提示用户输入用户名/密码并对提供的信息进行身份验证。在此身份验证方式中,用户不能定制搜集用户名/密码的表单。
- FORM:在这种情况下,您可以定制通过HTTP浏览器显示给终端用户的登录屏幕和错误页。
- CLIENT-CERT:这是一种比基本方法或表单方法更安全的身份验证方法。它使用服务器的SSL和HTTP,或者带有公共密钥证书(Public Key Certificates(的客户端身份验证。安全套接字层(SSL)为TCP/IP连接提供了数据加密、服务器身份验证、消息完整性和可选的客户身份验证。后面您会看到,WebLogic Server 正是使用这种身份验证形式执行身份断言的。
当Web应用程序安全是程序式时,servlet 容器能实现某些HttpServletRequest 接口的方法,用于身份验证/授权试图访问受保护资源的用户。Servlet 容器为程序式安全提供了额外的方法,这些方法在规范中都没有提到。在WebLogic Server 中,提供额外方法的类是weblogic.servlet.security.ServletAuthentication。 ServletAuthentication 允许servlet 中基于表单的身份验证和程序式身份验证。它通过Security Realm 执行身份验证调用,并为会话设置用户信息。weak()方法用于密码认证而strong()用于基于证书的身份验证。后面我们将使用来自该类的方法,允许 通过相同Web应用程序的多重身份验证机制来对Web应用程序用户进行身份验证。
Web应用程序部署
图1代表Web应 用程序常用的部署模型。如图所示,当用户试图访问受保护的Web应用程序时,前端访问管理器将对这些用户进行身份验证,并把认证过的用户路由到后端应用服 务器。如果Web应用程序在部署描述文件中定义了安全约束而且角色/属性存储在目录服务器上,servlet容器调用安全API从底层目录获得用户/组的 信息。
图1 Web 应用程序部署
让我们大概了解一下有效用户访问受保护资源必须经过的步骤,如部署模型中所示。
- 用户请求受保护的Web资源。
- 前端Web服务器/身份验证服务器对用户进行认证。
- 如果用户通过认证,请求就被传给后端应用服务器。
- 然而,由于身份验证规则/安全约束配置在Web应用程序描述文件中,servlet 容器需要从底层目录存储器中获得用户/组信息。
- 应用服务器为了使传入的主题与底层存储器的属性相关联,它需要确保用户是经过认证的。
- 为执行上述安全需求,应用服务器应该重新认证用户,或假定来自前端访问管理器的请求是已认证用户发出的。
- 然而,不推荐从应用服务器进行额外的重新认证,因为这需要额外的系统开销。为避免额外的重新认证调用,应用服务器的另一选择是假定来自前端访问管理器的请求来自已认证用户,从而绕过身份验证步骤。
Identity Assertion或周边身份验证为应用服务器提供了一种机制,用于断言前端请求是来自已认证用户的,从而避免了重新认证。这通过配置令牌来实现,令牌能与HTTP头部请求一起从前端访问管理器传递到后端应用服务器。下一节对此进行了详细的解释。
令牌概述
令牌主要是两方之间传递的秘密代码。本质上,令牌是关于主体的断言或声明,该主体被断言方看作是声明性的(可信任的)。当接收方收到令牌,它会进行一组 操作验证传入的令牌。如果令牌被验证过,就假定请求来自可信任的资源,接收方就不会进行额外的身份验证。在典型的Web环境中,令牌是通过HTTP头部或 cookie传递的。
在当前实现中,WebLogic Server 的默认Identity Assertion 提供程序支持下列令牌:X.509、CSI.PrincipalName、CSI.ITTAnonymous 和CSI.X509CertChain CSI.DistinguishedName。“支持”令牌类型本质上意味着Identity Assertion 提供程序的运行时类(也就是IdentityAsserter SSPI实现)能用assertIdentity方法来验证令牌类型。
由于上述令牌可能无法满足所有应用程序的需求,您可以为自己的环境轻松地建立新的自定义令牌。建立自定义令牌需要编写自定义Identity Assertion 提供程序,该程序能实现IdentityAsserter Security Service Provider Interface (SSPI)。WebLogic Server 的SSPI 提供了开发自定义安全提供程序的途径。自定义令牌类型可以像一段字符串那样简单。例如,在Custom Identity Assertion Provider Implementation中定义下列代码片段,也就定义了一种新的令牌类型。
public final static String MY_TOKEN_TYPE = "MyCustomIAToken";
定义了新的令牌类型后,可以按BEA产品文档中描述的WebLogic Console 一样,对其进行配置。一旦配置完成并进行了激活,这些令牌就可被WebLogic Security 架构用于断言传入请求的身份。
序列图
图2给出了执行Identity Assertion 期间的步骤顺序:
图2 身份断言序列
- Web应用程序部署过程中,Web容器首先确定Web应用程序的身份验证方法被配置为CLIENT-CERT。
- Web容器创建并初始化相应的SecurityModule 在本例中,它创建了CertSecurityModule 。
- 当客户端访问Web资源时,服务器的ServletSecurityManager 调用CertSecurityModule,来检查用户访问该资源的权限。
- 然 后CertSecurityModule 调用服务器的安全模块,寻找请求对象中的所有令牌。CertSecurityModule 寻找在Identity Assertion 配置期间在HTTP头部或cookie中配置的令牌。实质上,它迭代头部值,并试图让头部值和WebLogic 控制台中预定义的令牌相匹配。
- 如果请求中出现了有效的令牌,SecurityModule 就试图断言用户的身份。
- 此时,服务器的安全模块将控制传递给自定义Identity Assertion 提供程序实现。
- 自定义Identity Assertion 验证程序验证令牌的有效性并从中提取用户名。
- 自 定义Identity Assertion 提供程序生成JAAS CallBackHandler 。Java Authentication and Authorization Service (JAAS) 是一组API,它启用身份验证服务,并执行用户访问控制。更多关于JAAS 的细节,请参考http://java.sun.com/products/jaas/。
- CallBackHandler 验证包含一个回调名的回调清单(否则它会抛出一个异常),并适当地设定用户名。
- NameCallBack 确保用户出现在底层安全领域,并且基于定义的规则授权用户访问。
与JAAS的关系
有一点很重要,Identity Assertion不受到JAAS 的保护,也就是说JAAS对实现Identity Assertion不提供任何特定的指导。Assertion和JAAS唯一的关联是Identity Assertion 的实现返回一个javax.security.auth.callback.CallbackHandler(http://java.sun.com/j2se/1.4.2/docs/api/javax/security/ auth/callback/CallbackHandler.html)。 您可能会想起,当 JAAS LoginModule 需要与用户通信时(例如,要求用户输入用户名和密码),它是通过调用CallBackHandler 实现的。然后CallBackHandler()方法生成适当的 CallBack 来获得请求的信息。在Identity Assertion的情况下,自定义安全提供程序验证请求中传递的令牌是有效的,随后生成唯一的NameCallBack。
多重身份验证机制
在本文前面,我们回顾了Web应用程序安全模型。在登录配置中关于指定身份验证方法的问题之 一是,在某个指定时间,一个Web应用程序只能配置一个身份验证方法。然而在某些情况下,需要从多个源为用户提供服务,也就是说,来自包含已定义令牌的可 信任来源(前端访问管理器)的用户和那些不是来自可信任来源的用户。可能包括来自内部网络的用户,他们可以直接访问应用服务器。换句话说,依赖于请求的来 源,servlet 安全实现可能需要生成两种不同的CallBackHandlers。然而,servlet 规范中没有规定允许多重身份验证方法。这需要调用特定于Web容器提供程序的编程式解决方案。正如我前面指出的,WebLogic 为Web应用程序内部的程序式身份验证提供weblogic.servlet.security.ServletAuthentication。 ServletAuthentication 方法为身份验证提供了两种重要的方法:
- weak():从请求中获取用户名和密码后,为AUTHENTICATED或FAILED_AUTHENTICATION返回一个int值,对该用户进行认证,并将其设置到会话中。
- strong():与“WebLogic”(默认)域相反,强身份验证使用客户端证书链作为身份验证凭证。
图3提供了此配置的步骤。在Identity Assertion 中,servlet 容器调用ServletAuthentication的strong()方法。为相同的Web应用程序实现多重身份验证方法(基于CLIENT-CERT 和FORM方法),选项包含在登录表单通过编程调用方法。也就是说,登录表单先执行强身份验证(CLIENT-CERT)。如果在请求头部或cookie 中出现了一个有效令牌,就允许用户对资源进行访问。如果强身份验证失败,登录表单会提示输入用户名和密码。要注意的是,因为BASIC形式的身份验证不提 供定制身份验证表单的能力,也没有在表单中提供编程能力,所以不可能通过编程方式对BASIC和CLIENT-CERT身份验证方法进行组合。
图3 使用多重身份验证方法时的步骤
替代解决方案
Identity Assertion不是这个问题唯一可行的解决方案。其他解决方案包括在两方之间传递共享秘钥(或令牌)。在这种情况下,发送方和接收方要事先都同意共享 的秘钥。如果带有正确共享秘钥值的请求到达时,接收方就能相信请求是来自可信任来源并允许访问底层资源。
其他解决方案诸如基于IP的信任也可以在此使用。在这种情况下,在请求被授权进行访问之前,应用程序会检查请求是否来自预配置的、可信任的IP地址。通常是DMZ中Web服务器的IP。
结束语
本文详细介绍了BEA WebLogic Server 如何提供一种机制来通过Identity Assertion执行周边身份验证。当前端访问管理器执行身份验证,而多个后端服务器相信来自前端的请求是经过认证的,并且不需要额外身份验证时,这种 方法就非常有用。
来源:http://middleware123.com/weblogic/security/520.html