J2EE 中的安全第一部分 - J2EE安全介绍

来源:互联网 发布:fastslam算法 编辑:程序博客网 时间:2024/04/30 12:14

http://www-900.ibm.com/developerWorks/cn/wsdd/techjournal/0303_barcia/barcia.shtml

.简介

        现在越来越多的企业应用建置在J2EE平台上,这得益于J2EE为企业应用的开发提供了良好的框架和服务的支持。J2EE为企业应用提供了多方面的服务(SecurityTransactionNaming)。本文将介绍J2EE提供的安全服务 。作者首先介绍J2EE中的安全概念和J2EE的安全架构,然后结合具体的案例向读者展示如何在自己的程序中应用J2EE提供的安全特性。本文所介绍的内容是基于J2EE1.3版本的。

.J2EE中的安全概念

        主体(Principal)︰主体(Principal)是被在企业安全服务验证了的实体。主体(Principal)用主体名作为它的识别数据,透过与主体相关的验证数据进行验证。通常主体名就是使用者的 登入名,验证数据就是登入的密码。J2EE规范中并没有限定J2EE 产品提供商使用怎样的认证方法,因此主体名和验证数据的内容和格式依不同的认证协议而不同。

        
安全原则网域(Security Policy Domain)︰也称安全网域(security domain)或 realm,它是一个逻辑范围或字段,在这一范围或字段中安全服务的管理员定义和实施通用的安全原则。它是从安全原则的角度来划分的字段。比如可以将企业应用系统划分为企业员工、供货商、合作伙伴等不同的安全网域,对这些安全字段采用不同的安全原则。

        
安全技术网域(Security Technology Domain)︰它是从安全技术的角度来划分的字段,在一个安全技术网域中使用同样的安全机制来执行安全原则。一个安全技术网域可以包括多个安全原则网域。

        
安全属性(Security Attributes)︰每个主体(Principal)都有一系列与之相关的安全属性。安全属性可用来存取被保护的资源,检查使用者的身份和完成其它一些安全相关的用途。J2EE产品提供商或具体的验证服务的实作来决定怎样将安全属性与一个主体连络起来。J2EE规范并没有限定什么样的安全属性将与主体相连络。

        
凭证(Credential)︰凭证包括或参照为J2EE 系统验证一个主体的验证讯息(安全属性)。如果成功的透过了验证,主体将获得一个包括安全属性的凭证。如果被容许的话,一个主体也可能获取另一个主体的凭证。在这种情况下两个主体在同一安全网域中具有相同的安全属性。

.J2EE的安全架构

1 基于容器 ( container ) 的安全


        
J2EE的环境中,组件的安全是由他们各自的容器来负责的,组件的开发人员几乎可以不用或者很少在组件中加入有关安全的代码。这种安全逻辑和商业逻辑相对独立的架构,使得企业级应用系统有更好的灵活性和扩充性。J2EE规范要求J2EE 产品必须为应用程序开发者提供两种形式的基于容器的安全性-说明性的安全性和可程序化的安全性。

        a.
说明性的安全性

        
说明性的安全性透过安全结构描述的方式来代表应用程序的安全需求,安全结构一般包括安全角色,存取控制和验证要求等。在J2EE平台中布署描述子作为说明的安全性的主要工具。 布署描述子是组件开发者和应用程序布署者或应用程序组装者之间的交流工具。应用程序的开发者用它来表示应用中的安全需求,应用程序布署者或应用程序组装者将安全 角色与布署环境中的使用者和群组映射起来。

        
在程序执行时容器从布署描述子中提取出相应的安全原则,然后容器根据安全原则执行安全验证。说明的安全性不需要工作人员编写任何安全相关的 程序代码,一切都是透过设定布署描述子来完成的。

        b.
可程序化的安全性

        
可程序化的安全性在说明性的安全性的基础上,使安全敏感的应用可以透过呼叫被容器提供的API来对安全作出决断。这在说明性的安全性不足以满足企业的安全模型的情况是非常有用的。J2EEEJB EjbConext interfaceservlet HttpServletRequest interface中各提供两个方法︰

 
isCallerInRole (EJBContext)
getCallerPrincipal (EJBContext)
isUserInRole (HttpServletRequest)
getUserPrincipal (HttpServletRequest) 
 



        
这些方法容许组件根据呼叫者或远程使用者的安全角色来作出商业判断。在文章的后面部分将有这些方法的详细介绍和范例,以便读者更好的理解可程序化的安全性的用途。

2J2EE的验证模型


        
身份验证是使用者或组件呼叫者向系统证明其身份的过程。使用者透过某种方式向系统提交验证讯息(通常是使用者名称和密码或者是使用者的数字签章),系统用使用者提供的验证讯息和系统的安全原则来验证使用者的身份。
图一 初始验证过程

图二 验证URL

图三 验证EJB方法呼叫 




        
使用者的验证

        
使用者的验证根据其客户端类型不同分为两种︰Web 客户端的验证和Application客户端的验证

        a. Web
客户端的验证

        Web
客户端通常透过http协议来请求web服务器端的资源,这些web资源通常包括html网页、jspjava server page)档案、java servlet和其它一些二进制或多媒体档案。在企业环境中,企业的某些资源往往要求只容许某些人存取,有些资源甚至是机密的或安全敏感的。因此对企业中各种web资源进行存取控制是十分必要的。为了满足企业中的不同安全层级和客户化的需求,J2EE提供了三种基于web客户端的验证方式︰

        HTTP
基本验证(HTTP Basic Authentication
        HTTP
基本验证 HTTP协议所支持的验证机制。这种验证机制使用使用者的使用者名称和密码作为验证讯息。Web客户端从使用者获取使用者名称和密码,然后传递他们给web服务器,web服务器在指定的字段(realm)中验证使用者。但需要注意的是,这种验证方法是不够安全的。因为这种验证方法并不对使用者密码进行加密,而祇是对密码进行基本的base64的编码。而且目标web服务器对使用者来说也是非验证过的。不能保证使用者存取到的web服务器就是使用者希望存取的。可以采用一些安全措施来克服这个弱点。例如在传输层上应用SSL或者在网络层上使用IPSECVPN技术。

        
基于窗体的验证(Form-Based Authentication

        
基于窗体的验证 使系统开发者可以订做使用者的登入页面和错误页面(error pages)。这种验证方法与基本HTTP的验证方法的唯一区别就在于它可以根据使用者的要求制定登入和 错误页面。基于窗体的验证方法同样具有与基本HTTP验证类似的不安全的弱点。使用者在窗体中填写使用者名称和密码,而后密码以明文形式在网络中传递,如果在网络的某一节点将此验证请求截获,在经过反编码很容易就可以获取使用者的密码。因此在使用基本HTTP的验证方式和基于窗体的验证方法时,一定确定这两种方式的弱点对你的应用是可接受的。

        
基于客户端证书的验证(Client-Certificate Authentication

        
基于客户端证书的验证方式要比上面两种方式更安全。它透过HTTPSHTTP over SSL)来保证验证的安全性。SSL 为验证过程提供了数据加密,服务器端认证,讯息真实性等方面的安全保证。在此验证方式中,客户端必须提供一个公钥证书,你可以把这个公钥证书看作是你的 数位护照。公钥证书也称数位签章,它是被称作证书授权机构(CA)-一个被信任的组织颁发的。这个数字签章必须符合X509公钥体系结构(PKI)的标准。如果你指定了这种验证方式,Web服务器将使用客户端提供的 数字签章来验证使用者的身份。

        b.
应用程序客户端的验证(Application Client User Authentication

        java
客户端程序是执行在使用者本地java虚拟机器上的java程序,它拥有main方法,通常由使用者可透过java.exejavaw.exe直接启动执行。J2EE应用程序客户端与java客户端程序相似,也拥有main方法,但他们在执行时存在一定的差别。J2EE应用程序客户端和其它J2EE组件一样执行在自己的容器中。使用者透过容器来执行J2EE应用程序客户端。这样J2EE应用程序客户端容器就有机会在J2EE应用程序客户端被执行之前完成使用者身份的验证。J2EE提供了一种可订做的方式来获取使用者的验证讯息。可以选择使用容器提供的 预设的方式来获取J2EE应用客户端程序的使用者的验证讯息,也可以选择订做的方式来获取使用者的验证讯息。当选择订做方式时,应用程序开发者必须提供一个实作了javax.security.auth.callback.CallbackHandler interfce的类别,并且在J2EE布署描述档application-client.xml中的元素callback-handler中加入这个类别的 类别名。这样,当系统需要验证使用者身份时,客户端程序的容器将布署描述档中的CallbackHandler实作类别的类别名传递给系统的 登入模块(验证模块),登入模块再案例化这个实作类别。这个类别的案例负责收集使用者验证讯息,并将收集到的使用者验证讯息传递给登入模块,登入模块用这些验证讯息来验证使用者。这个实作 类别可以是具有使用者界面的,或是透过要求使用者输入来收集使用者验证讯息,也可以是透过指令行来获取使用者验证讯息,还可能是透过读取本地或在线的使用者证书库来获取使用者的电子证书。选取哪种方式取决于验证讯息的储存方式。

        
有些J2EE产品厂商把容器的验证服务和本地系统的验证服务或其它应用系统产品的验证服务整合起来,从而在一定的应用系统的范围内实作单一登入的能力。

        
单一登入 Single Sign-On

        
单一登入从使用者的角度来看,是指使用者在特定的逻辑安全字段中,只需进行一次登入即可在存取在此逻辑安全字段中不同应用系统中的被授权的资源,祇有超越了安全字段边缘时 才要求再次 登入。这种能力对多种IT应用系统共存的企业显得更有价值。随着企业讯息化建设程度的不断提高,企业中的应用系统也越来越多。在传统的应用系统中,各系统各自维护自己的安全原则,这些安全原则典型的包括组织结构定义,安全 角色定义,使用者身份验证,资源存取控制等。由于各系统互相独立,一个使用者在使用每一应用系统之前,都必须按照相应的系统身份进行系统 登入。这对于使用者来说必须记住每一个系统的使用者名称和密码,给使用者带来了不小的麻烦。针对于这种情况,单一登入的概念随之产生,并不断的应用到企业的应用系统的整合当中。J2EE1.3也在规范中建议J2EE产品应为应用系统提供单 一登入的能力。但J2EE1.3规范并没有规定J2EE产品应遵循何种标准,因此不同的厂商的产品在单一登入上的实作和应用各不相同。有的J2EE产品实作了在本产品环境范围内的单 一登入,有的实作了特定系统环境之间的单一登入(如IBM WebSphere Application 4.0 AE 实作了WebSphere Application ServerWebSphere Application ServerWebSphere Application ServerLotus Domino server 之间的单一登入能力)。在J2EE中单一登入是透过传递凭证(Credential)来实作的。当使用者进行系统登入时,客户端容器(包括WEB客户端和应用程序客户端)根据使用者的凭证(Credential)为使用者建立一个安全 性内容(security Context),安全性内容包括用于验证使用者的安全信息,系统用这个安全性内容和安全原则来判断使用者是否有存取系统资源的权限。遗憾的是J2EE规范并没有规定安全 性内容的格式,因此不能在不同厂商的J2EE产品之间传递安全性内容。到目前为止还很少有在不同的J2EE产品间互相共享安全性内容,因此在不同J2EE产品间实作单 一登入只能透过第三方产品(如LDAP server等)整合的方式。

        
惰性验证(Lazy Authentication

        
身份验证是有代价的。例如,一次验证过程也许包括多次透过网络讯息交换。因此惰性验证就非常有用了。惰性验证 是当使用者存取受保护的资源时才执行验证过程,而不是在使用者第一次发起请求时就执行验证过程。

3. J2EE的授权模型


        
程序代码授权(Code Authorization

        J2EE
产品透过java 2 安全模型来限制特定J2SE的类别和方法的执行,以保护和确保操作系统的安全。详细描述请参阅《J2SE规范文件》。

        
呼叫者授权(Caller Authorization

        
安全角色︰安全角色是具有相同安全属性的逻辑组。它是由应用程序的组装者(Application Assembler)或应用程序的布署者(Application Deployer)指派的。

        
安全角色参照

        
安全角色参照是应用程序提供者(Application Provider)用来参照安全角色的识别数据。应用程序提供者(Application Provider)可以用安全角色参照来为安全角色指派资源存取的权限。也在安全相关的程序代码中参照安全角色。

        
使用者和群组

        
使用者和群组是在实际系统环境下的使用者和使用者的集合。它们对应者现实当中的人和群体

        
存取控制

        
存取控制可以确保安全角色只能存取已授予它安全权限的授权对象。授权对象包括EJB的远程方法、web资源(html网页,jsp/servlet和多媒体或二进制 档案)等。在J2EE中存取控制在应用程序描述文件中与安全角色关联起来。

        
映射

        
透过映像应用程序的系统管理员将实际系统环境中的使用者和角色与安全角色连络起来,让实际的使用者拥有对企业资源存取的适当授权。

        
被传播的呼叫者身份识别数据(Propagated Caller Identities

        
J2EE 1.3中可以选择用传播呼叫者识别数据作为web组件和ejb组件呼叫者的识别数据以便进行验证。在这种方式下,整个ejb组件的呼叫链中interface EJBContext的方法getCallerPrincipal传回相同的主体名(principal name)。如果呼叫链中的第一个ejb是被jsp/servlet呼叫的,interface EJBContext的方法getCallerPrincipal传回的主体名(principal name)应与interface HttpServletRequest的方法getUserPrincipal 传回值相同。要注意的是在呼叫链中传递的是使用者的识别数据,而不是凭证(credentials),这一点非常重要,因为在呼叫链的每个节点上使用者可能使用不同的安全属性。

        Run As Identities

        J2EE 1.3
中提供了容许组件开发者和布署这来指定组件以什么身份执行的方法。符合J2EE1.3规范的产品会提供将组件设定成Run As Identities方式的方法。如果Run As Identities方式被选中,在执行中被设定为Run As Identities的组件的呼叫者不再是呼叫链中第一个节点的呼叫者了,而是在布署时被指定的呼叫者。而呼叫链中随后节点的呼叫者也变为与被设定为Run As Identities的组件的呼叫者相同。
图四 使用者识别数据传递 

        
这一部分介绍了J2EE的安全概念,意在使读者能够对J2EE在安全方面有一定的了解,后面还会有应用这些概念的具体例子。

结论

        J2EE为我们提供了对于验证和授权的安全服务,在开发基于J2EE的应用时应该尽可能的使用J2EE为我们提供的这些服务。因为祇有遵循J2EE标准,才能使你的应用具有良好的移植性、扩充性和可维护性。祇有在所选J2EE产品不能满足特定的安全需求时,才应该考虑使用第三方安全产品或自己开发安全服务。

原创粉丝点击