posts - 30,  comments - 85,  trackbacks - 0
JAAS 基础认证和授权机制

作者:Bill Kemp, Peter Holditch
安全性是所有可以用来对资源进行保护和验证的机制。有很多种安全模型都可以用来对数据提供保护。这些安全模型可以使用加密、访问控制或其他安全方法。授权 (Authorization),或称为访问控制,可以使用不同的安全服务来对资源进行保护:一种方法是Java认证和授权服务(Java Authentication and Authorization Service,JAAS),另外一种方法是Windows 2000的活动目录(Active Directory)。本文着重于介绍JAAS安全服务。

认证和授权是两种最基本的安全机制。认证就是简单地对一个实体的身份进行判断;而授权则是向实体授予对数据资源和信息访问权限的决策过程。JDK 1.4已经集成了一项提供认证和授权功能的标准服务,该服务就称为Java认证和授权服务。

JAAS通过一个配置文件来定义认证机制,而根本不需要使用任何代码。认证机制之所以需要参数是为了确定用户的身份(对用户进行标识)。用来对用户进行认 证的参数,例如每种认证机制中使用的用户名和口令,都称为验证信息。Subject表示我是的那个人,但是我们也可以使用验证信息(可以理解为驾驶执照) 向巡警证明自己的身份,并使用另外一个验证信息(可以理解为护照)向边防警察证明自己的身份。授权只能在认证之后进行,因为在向用户开放保护资源的访问权 限之前,必须对用户的身份进行确认。JAAS框架对由配置文件指定的认证模块进行了包装。如果认证成功,就会返回一个包含验证信息的Subject,认证 机制所返回的这个验证信息会用于授权过程。

JAAS首先使用一个LoginContext类来查找配置文件中的内容,这些内容可以用来对LoginModules进行初始化(见图1)。所有 LoginContext没有指定的初始化参数都会包含在配置文件中。LoginContext还会向LoginModule传递一个 CallbackHandler,CallbackHandler又会回调适当的应用程序,从而获得其他认证信息。例如,如果LoginContext在 创建CallbackHandler时没有指定用户名和口令,而LoginModule又的确需要这些内容,那么LoginModule就会使用 CallbackHandler来回调LoginContext,以重新获得所需要的信息。

为了让验证信息可用于登录,LoginContext还可以向LoginModule传递Subject。


图1 JAAS初始化序列图

在创建LoginContext时,完成LoginModule的初始化之后,LoginContext就可以调用login( )方法(见图2),它会对Subject进行认证。登录过程需要经过一个由LoginModule组成的菊花链,根据配置文件的内容,每一步都需要一个不 同类型的验证信息。配置文件还可以指定可选而非必须的LoginModule的配置。LoginModule会完成一个两阶段的登录过程:第一个阶段是登 录过程调用LoginModule的login( )方法;第二个阶段是调用commit( )或abort( )方法完成登录过程。commit( )过程是当所有其他LoginModule完成自己的login( )方法之后才在登录过程中被调用的,然后最后一个LoginModule会调用commit方法,之后是下一个,依此类推。如果login( )方法不能成功执行,就会调用abort方法来清除已经执行的操作。如果所有必须的commit( )方法都成功完成了,那么登录过程也就成功地完成了。


图2 JAAS登录序列图


授权过程需要使用在登录过程中确定的验证信息,因此,认证过程通常都是在Subject类中实现的,这并没有什么可奇怪的。Subject类会使用 PrivilegedAction类来执行授权的过程。另外,还有一个扩展的PrivilegedAction类对要进行访问控制的资源进行了包装。不管 验证信息是否有权对资源进行访问,这都是在安全策略文件中定义的。Java安全管理程序会首先读取适当的安全策略文件,并对权限和验证信息进行分析。然 后,安全管理程序会根据这些权限和验证信息使用PrivilegedAction类对资源进行授权(或禁止访问)。如果该资源不允许一个特定的验证信息访 问,就会触发一个访问异常。

在WebLogic中使用JAAS
WebLogic Application Server(WLS)7.0并没有对JAAS进行任何修改,JAAS依然是一个独立的扩充框架。WLS 7.0包含了自己的认证和授权机制,它并不需要策略文件。配置文件会对WLS LoginModule进行定义,使其用来包装WLS的认证机制。WLS LoginModule通常需要一个用户名、一个口令以及一个指向适当WLS服务器的URL。WLS 7.0还包含了一种授权机制,可以对映射资源和角色进行授权。由于WLS 7.0在WebLogic的安全框架中实现了一种授权机制,因此策略文件和Java安全管理程序都不需要定义。在调用PrivilegedAction类 时,需要使用weblogic.security.Security类。

WebLogic 7.0给出了一个例子来展示如何执行基于JAAS的认证和授权,该例是在一个Java客户端应用程序中调用EJB来使用JAAS授权开放对资源的访问限制。这个例子对下面Sun的例子稍微进行了修改:
http://java.sun.com/j2se/1.4/docs/guide/security/jaas/JAASRefGuide.html#Sample.

这个例子包括一个JAAS配置文件,该文件指定了以下内容:EJB客户端用来执行认证的LoginModule的类名;用来搜集客户端证书和认证服务器的 URL的CallbackHandler;一个PrivilegedAction类,该类包含了执行EJB访问操作的代码;以及一个客户端应用程序,该程 序会创建一个LoginContext,调用login( )方法,并通过weblogic.security.Security.runAs方法来调用PrivilegedAction类。这个例子的流程如图3 所示。你可以查看/weblogic700/samples/server/src/examples/security/jaas文件来参考完整的例 子。本文后面的内容会参考这个例子,从远程客户端的角度来讨论WLS中基于JAAS的认证和授权,并将其与服务器端的组件(例如servlet)进行比 较。


图3 WLS 7.0的认证机制

Java客户端认证
需要直接访问WebLogic Server上的EJB或JMS Destination的客户端应用程序使用一个单独的Java客户端认证程序进行认证。BEA在WLS 7.0版中提供了一个客户端的例子,它使用一个JAAS策略文件sample_jaas.config为应用程序指定一个LoginModule: weblogic.security.auth.login.UsernamePasswordLoginModule。该文件的内容如下:

Sample {
weblogic.security.auth.login.UsernamePasswordLoginModule required debug=false;
};

UsernamePasswordLogin- Module的代码没有包含在示例包中,不过类文件位于weblogic.jar中。代码的详细内容见http: //edocs.bea.com/wls/docs70/security/cli_apps.html#1096287。

它使用weblogic.security.auth.Authenticate类(WebLogic专用的类)来对通过URLCallback指定给 LoginModule的实例进行认证。该应用程序的CallbackHandler提供了服务器的URL,服务器通过自己已配置的 Authentication Provider进行认证。

LoginModule会向CallbackHandler传递NameCallback和PasswordCallback来获得客户端的用户名和口 令,其中该客户端开始了应用程序。一旦用户通过认证,LoginContext就会将Subject传递给LoginModule。然后,应用程序使用 LoginContext.getSubject方法获得认证过的Subject。Subject中包含了WebLogic 验证信息--它可以是一个WLSUser,也可以是一个WLSGroup--它会在把Subject传递给Security.runAs方法时用来进行认 证。整个JAAS认证过程是由应用程序在实例化LoginContext类并调用LoginContext.login( )方法时进行初始化的。LoginContext会寻找一个已经装载了在JAAS策略文件中发现的信息的Configuration对象。它使用 Configuration来创建一个LoginModule的实例,该实例会用于此后的认证过程。

// Create LoginContext; specify username/password login module
loginContext = new LoginContext("Sample", new SampleCallbackHandler(username, password, url));

这个LoginContext的实例化过程会定位一个在Configuration中找到的LoginModule并对其进行实例化,它使用 "Sample"名字在Configuration中查找LoginModule,并将SampleCallbackHandler传递给它的初始化方 法。从sample_jaas.config文件的内容中,你可以看到LoginContext会对一个 UsernamePasswordLoginModule的实例进行实例化,从而进行认证。

根据WebLogic文档,在WLS 7.0版本中并不推荐使用weblogic.jndi.Environment类。然而,该例子中提供的LoginModule使用 weblogic.jndi.Environment对象,通过向Authenticate.authenticate方法传递Environment来 执行认证。其中Environment中包括用户名、口令以及服务器的URL。这是一个很明显的矛盾,因此我们还要在其中加入LoginModule的可 插入特性这一优点。示例LoginModule的机制,也就是Authenticate类的用法,对于客户端应用程序自己试图向WebLogic服务器进 行认证时是不可见的。由于LoginModule是可插入认证模块(Pluggable Authentication Module,PAM)的一个实例,因此它可以方便地进行替换或重写,而不会影响到客户端的应用程序。这是展示LoginModule可插入特性是如何防 止开发脆弱的应用程序代码的一个很好的例子。 Authenticate.authenticate方法会连接到在URL中指定的WebLogic服务器上,并可以向服务器传递Subject或 Environmet(其中包含了证书),从而由为服务器的WebLogic安全区域配置的Authentication提供程序进行认证。服务器的安全 成员域中配置的Authentication提供程序也实现了LoginModule。Authentication提供程序的实现可以使用各种技术实现 认证,例如LDAP或关系数据库。如果认证成功,Authentication提供程序就向Subject中增加认证过的Principal。在将验证信 息加入Subject之前,它会向验证信息验证器发起一个请求,从而对验证信息进行数字签名。这样,在调用Security.runAs返回 Subject并试图执行关键授权检查时,可以防止恶意的客户端篡改所返回的Subject中嵌入的验证信息。验证信息验证器会在授权过程中进行查询,从 而确保所返回的Subject和在认证过程中进行数字签名过的Subject完全相同。

基于浏览器的认证
即便不是大多数,也有很多基于WebLogic的应用程序是通过基于浏览器的客户端来访问的。这些应用程序通常由servlet、JSP、EJB等组成。 对这些应用程序的认证在元素中定义为BASIC或者FORM,是Web应用程序中web.xml部署描述文件中的元素,可以表示应用程序的初始访问页。例 如:


BASIC

当我们使用其中一个方法对Web客户端进行认证时,Web容器根据客户端的行为调用Web安全框架,并访问Authentication 提供程序。这种机制的结果是生成了一个JAAS Subject,其中包含一个经过认证的验证信息,保存在一个内部会话对象之中。从该客户端发来的后续请求通过HttpRequest中传来的 cookie中的会话ID,就可以在内部会话中定位这个Subject,从而完成授权。此处的要点在于,WebLogic上的资源容器,像Web容器,也 要使用基于JAAS的认证,根据Web客户端的行为,调用Authentication提供程序,获取一个填充有经过认证的验证信息的Subject。 Authentication提供程序使用的LoginModule并没有在JAAS配置文件中配置,这一点与Java客户端的例子不同。通过管理控制台 将Authentication提供程序增加到活动的安全成员域中,就可以实现对Authentication提供程序的配置。WLS 7.0 默认配置的Authentication提供程序和LoginModul都是即装即用的,使用了一个内嵌的LDAP服务器。服务器端用来认证基于Web的 客户端的LoginModule就是Java客户端应用程序的UsernamePasswordLoginModule调用 Authenticate.authenticate方法传递Subject和Environment对象进行认证时使用的那个LoginModule。 这个Subject没有传回Web客户端,而是由Web容器保存在内部会话对象中,稍后通过会话ID访问。

基于JAAS的授权

尽管WLS中的授权没有使用JAAS的Subject.doAs方法,它仍然是基于JAAS Subject的。要求访问受保护的WebLogic资源的应用程序通过weblogic.security.Security.runAs方法请求访 问。Subject和PrivilegedAction被传递给这个WLS安全框架方法,以执行有关一项WebLogic资源的任务。

WebLogic资源

通过Jave安全策略文件中的安全策略,我们可以对Java系统资源进行保护,而WebLogic的资源与此不同,对这些资源的保护是通过将 WebLogic角色与WebLogic资源关联起来的安全策略进行的。一项WebLogic资源定义为一个结构化的对象,表示服务器端实体,可以保护这 些实体拒绝未经授权的用户进行访问。WebLogic资源的例子有:EJB方法、servlet以及JMS Destination。有关更多可以用WebLogic角色保护的WebLogic资源类型实例,请参看http: //edocs.bea.com/wls/docs70/dvspisec/atz.html#1134702处的文档,

WebLogic角色

WebLogic角色的概念是在WLS 7.0中建立的,它代替了以前发布的WebLogic中基于ACL的授权。根据WLS的文档,一个角色定义为一个抽象的逻辑用户集合,与组的概念类似。但 是角色与组不一样,因为角色是根据用户名、组成员以及时间动态更改的。角色与资源一起用,可以创建WebLogic安全策略。基于JAAS的安全策略在 Java安全策略文件中定义,其作用是授权允许访问codebase、签名以及验证信息的权限。将WebLogic角色与WebLogic资源关联在一 起,就建立了一个WebLogic安全策略。WebLogic在应用安全策略时并不会考虑Java的策略文件。只要当决定对某项资源的访问权限时,一个用 户在这项资源的安全策略定义的角色中,那么这个用户就可以访问这项资源。

WebLogic角色可以是全局的,即可以将角色与所有的WebLogic资源关联;也可以是局部的,即与特定的WebLogic资源关联。全局角色通过 管理控制台定义。安全策略是用局部角色,通过部署描述文件为Web应用程序和EJB动态创建的。对于Web应用程序组件,这些角色的声明及与资源的关联是 在web.xml文件;而对于EJB,则是ejb-jar.xml文件的元素。声明好的角色分别通过提供商特定的部署描述文件、weblogic.xml 和weblogicejb-jar.xml,用元素赋予Principals。控制台中也可以配置动态角色,不过控制台改变之后,组件的部署描述文件不会 跟着改变。RoleMapper完成的工作是在部署的时候将赋予Principal的角色关联起来。

WebLogic授权

当应用程序通过调用Security.runAs方法执行PrivilegedAction时,Java客户端应用程序的授权过程就开始了(见图4)。当 调用这个方法时,应用程序将认证过的Subject和PrivilegedAction传递给WebLogic安全框架。在WLS中, PrivilegedAction内部激活了一个EJB方法,SampleAction.java,调用的身份标识就是已经通过认证的Subject。服 务器上的EJB容器从PrivilegedAction的上下文中的客户端EJB stub对象那里接收到请求。然后调用服务器上的安全框架,确定是否允许该Subject访问这个EJB方法。这样就激活了Authorization提 供程序和Role Mapper,由他们来决定那个Subject是否能访问它所调用的EJB方法。Role Mapper的作用是决定Pricipals中保持的Roles是否允许访问那个方法。如果允许,容器继续进行方法调用。应该注意的是,在授权过程开始之 前,验证信息验证器会验证传来的Subject中的验证信息,看认证之后它有没有被篡改。

图4 WLS 7.0的授权机制

基于浏览器的客户端使用与服务器相同的授权机制。区别在于Subject是由Web容器保存在服务器上,还是从客户端应用程序中传过来。浏览器发送cookie中的会话 ID,Web容器在内部线程中定位subject,然后调用安全框架进行授权。


结论

JAAS是一种认证授权机制,它由JAAS规范定义,在JDK 1.4中实现。JAAS为了实现对认证和授权的检查,采用了SecurityManager、AccessController、 LoginModule、以及Subject。我们通过Java安全及策略文件配置这些机制,达到保护系统资源和属性的目的。WebLogic用JAAS 中的LoginModule和Subject进行认证和授权;不过Configuration并不是特指Java的安全和策略文件,也不一定非要从这些文 件中获取。

Security提供程序可通过WebLogic控制台进行配置,它在WebLogic服务器上实现了Java中SecurityManager和 AccessController的角色。通过定义WebLogic角色和WebLogic资源之间关联的安全策略,Security提供程序可以控制对 WebLogic资源的访问。角色既可以通过控制台,也可以通过配置描述文件来配置。WebLogic的Authentication提供程序用 LoginModule和Subject建立一个用户的身份标识。WebLogic的Authorization提供程序通过一个认证Subject,并 基于定义的资源安全策略,以及认证Subject的Principal中保存的角色,赋予或者拒绝对WebLogic资源的访问。
posted on 2006-10-24 10:41 安文豪 阅读(1032) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 

<2006年10月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

常用链接

留言簿(6)

随笔档案(28)

文章分类(3)

文章档案(4)

最新随笔

搜索

  •  

积分与排名

  • 积分 - 86222
  • 排名 - 665

最新评论

阅读排行榜

评论排行榜