2009年9月7日星期一

ADF_007:ADF Security 介绍

ADF Security框架可以为ADF Web应用提供认证与授权服务。
ADF Security是根基于Oracle Platform Security Services (OPSS)架构之上的一个框架,OPSS已经很好地集成到了WebLogic Server中。

首先要明确一点,ADF Security并不是另起炉灶,而是基于JavaEE的安全框架,而JavaEE的安全框架的权限控制模型就是RBAC(Roled-Based Access Control),基于角色的访问权限控制。
在RBAC出现之前,用户和权限是绑定在一起的,当用户或权限发生变化时,都会涉及到对方,这样的设计无法实现复杂的授权。
引入角色这个对象后,用户和权限的之间的关系彻底解耦了:用户的变化只涉及到角色,与权限无关;而权限的变化只涉及到角色,与用户无关。
在一个系统中,角色是相对变化较少的,因此可以先定义好系统中所有的角色,包括每个角色可以行使的权限。
然后给用户授权,实际上就变成给用户授予哪些角色。
这样的权限控制模型非常利于管理:用户就是一个个体,组代表一群用户;角色代表用户或组与权限的映射关系。

1. ADF Security术语
为了说明ADF Security认证和授权原理,我先解释一些ADF Security术语,以免在后面的描述中发生混淆和歧义。
(1)credentials:加密的口令。比如数据库账户的口令或Email账户的口令,供Data Control使用。
(2)credentials store:存储credentials的地方。
(3)identities:身份信息,即企业用户信息。
(4)identities store:存储identities的地方,一般存储在LDAP或数据库中。
(5)policies:策略信息,定义哪些角色可以做哪些事情。
(6)policies store:存储policies的地方。
(7)Users:企业用户信息,每个用户一般都要隶属于一个用户组,一般存储在LDAP或数据库中。
(8)Enterprise Roles: 企业用户组信息,一般存储在LDAP或数据库中。
(9)Application Roles:与应用密切相关的逻辑安全角色,与Enterprise Role有映射关系。

2. OPSS与WebLogic Server的集成架构图

从图中可以看出,ADF认证和授权过程和原理如下:
(1)一个User可以隶属于一个或多个Enterprise Role。
(2)一个Enterprise Role可以隶属于一个或多个Application Role,且Enterprise Role可以嵌套。
(3)Application Roles是与应用密切相关的逻辑安全角色,它规定可以做哪些事情,且Application Role可以嵌套。
你可以直接给某个User赋予某个Application Role,但一般不这样做,而是给某个Enterprise Role赋予某个Application Role,再把User加到该Enterprise Role中。
这样,如果要修改某个用户的权限,只要修改该用户所隶属的组就可以了。
(4)在设计时创建的Enterprise Roles和Users只是临时用于开发环境的测试,生产环境中的用户和组是存储在LDAP中或Database中的。
(5)在设计时,Policy是存储在jazn-data.xml文件中的,运行时是存储在system-jazn-data.xml文件中的。
在生产环境中应该把Policy存储在OID或Database中。
如何把Policy移植到OID中,请参考《》。
如何把Policy移植到Database中,请参考《》。

3. 可以为ADF Page和ADF Task Flows提供保护
与其它安全框架相比,除了能够提供用户认证和针对URL的资源保护之外,ADF还为页面和Task Flows提供了声明式的权限保护,如下图所示:


4. 细粒度的保护级别
ADF Security保护的对象可以非常“细小”,其粒度级别可以达到Entity Object的行数据对象或EO的某个属性。


5. ADF Security EL表达式
ADF Security还提供了丰富的安全Expression Language,你可以为组件属性设置如下EL来动态控制来页面组件。
#{securityContext.authenticated}
#{securityContext.userName}
#{securityContext.userInRole['roleList']}
#{securityContext.userInAllRoles['roleList']}  
#{securityContext.taskflowViewable['target']}  
#{securityContext.regionViewable['target']}
#{securityContext.userGrantedResource['permission']}  
#{securityContext.userGrantedPermission['permission']} 

6. 使用程序访问ADF Security对象
public String getUserName() {
ADFContext adfctx = ADFContext.getCurrent();
return adfctx.getSecurityContext().getUserName();
}

public boolean isUserInRole(String role) {
ADFContext adfctx = ADFContext.getCurrent();
return adfctx.getSecurityContext().isUserInRole(role);
}

7. 建议
(1)如果你使用ADF Security,就不要使用JavaEE Web Container Security。反之亦然。
(2)JavaEE Web Container Security 使用定义在文件web.xml和weblogic.xml中的角色。
(3)ADF Security 不使用定义在文件web.xml和weblogic.xml中的角色。

没有评论: