`
zhouxwyeah
  • 浏览: 20398 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

简述WPS独立定制安全性与WPS流程人工任务权限分配

    博客分类:
  • java
阅读更多
   这段时间一直在用IBM的WPS做一些工作流的东西,暂不谈其好坏,毕竟产品我们也做不了决定。下面将写一些在使用流程经常碰到的安全性和权限分配的问题。

   使用WPS,避免不了要配置其安全性,常用安全性方案分几种形式:联合存储库,本地操作系统,LDAP注册表,独立定制注册表。
 
   由于各种业务系统的特殊性,前面两种一般满足不了要求,而且当权限认证是通过一个通用的系统时候,LDAP也满足不了,独立定制注册表这种方式最为灵活,可以很好的和各种安全方案相结合,毕竟这种安全性是由你自己编码去决定的。

 


    定制用户注册表需要实现WebSphere Application Server的UserRegistry Java接口,只要实现了这个java接口,定制注册表可以支持任意类型的数据源,比如最常见的关系型数据库,文件系统等等。
用户安全名字(User Security Name):用于验证的用户名字,就如本地操作系统验证方式的用户名。
用户唯一ID(User Unique ID):每个用户对应的唯一ID。
用户显示名字(User Display Name):可选项,用于显示该用户的名字,比如在欢迎界面,相当于本地操作系统验证方式下的该用户的全名。
组安全名字(Group Security Name):用于验证的组的名字,就如本地操作系统的用户。
组唯一ID(Group Unique ID):每个组对应的唯一ID。
组显示名字(Group Display ID):可选项,用于显示该组的名字,比如在欢迎界面,相当于本地操作系统验证方式下的该组的全名。
UserRegistry接口的下列方法必须实现:
initialize:读取WPS中配置的连接信息,对变量进行初始化
checkPassword:此方法用来验证用户名以及密码是否合法,是整合用户数据库的关键
mapCertificate:mapCertificate方法从浏览器中X.509安全证书链映射成为用户名
getRealm:返回注册表所在域,比如在OS/400或是AIX上,应该返回系统的主机名,其他情况可以返回默认值"customRealm"。
getUsers:根据输入的用户pattern(样式)查找符合条件的用户列表,如A*,则返回所有A开头的用户,开发人员可以根据自己的要求来开发。返回的用户数如果过多,可以使用limit参数进行限制
getUserDisplayName:根据安全用户名(Security User Name),得到显示用户名(Display User Name),一般情况返回同样的名字即可。
getUniqueUserId:根据安全用户名,得到该用户的唯一ID。
getUserSecurityName:根据用户的唯一ID得到用户的安全用户名。
isValidUser:检查用户名是否合法。
getGroups:根据pattern(样式)查找符合条件的组列表,用法同getUsers。
getGroupDisplayName:根据组的安全名字,得到组的显示名字。
getUniqueGroupId:根据组的安全名字,得到组的唯一ID。
getUniqueGroupIds:得到包含某个用户的所有组唯一ID列表。
getGroupSecurityName:根据组的唯一ID得到组的安全名字。
isValidGroup:检查用户组是否合法。
getGroupsForUser:得到包含某个用户的所有组的安全名字列表。
getUsersForGroup :得到某个组的所有用户列表。
createCredential:在底层的WAS实现中,这个方法不会被call到,返回null即可。

   前面简单介绍了UserRegistry 接口,这里我将不讨论UserRegistry接口的实现和WPS安全性的配置,而主要是介绍安全性的应用和WPS人工任务分配的关系,相信大家应该都可以配置好安全性。

下面将介绍独立定制注册表安全性配置结束后,和应用结合的几个情况:

1.WEB登录。
在web.xml配置加入:
    <login-config>
  <auth-method>FORM</auth-method>
  <form-login-config>
  <form-login-page>/login.jsp</form-login-page>
  <form-error-page>/loginError.jsp</form-error-page>
  </form-login-config>
  </login-config>
  <security-role>
  <role-name>WebClientRole</role-name>
  </security-role>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>

    表明你使用的FORM登录方式,登录页面为/login.jsp,登录成功跳转到/index.jsp,登录失败跳转到/loginError.jsp。
而且login.jsp必须为以下写法
<FORM ACTION=’ j_security_check’>
<input name=’ j_username’ type=’text’/>
<input name=’ j_password’ type=’password/>
<input type=’submit’>
</FORM>
   假设我们已经配置了自定义安全性,独立定制注册表,安全性相关的类已经实现了UserRegistry的接口。

   这时登录,我们ACTION=’ j_security_check’,无需编写登录servlet,WPS容器会自动调用我们安全性的方法,顺序如下:

   首先我们会调用UserRegistry实现类的的checkPassword方法,该方法可实现业务系统自己的登录认证,参数j_username和j_password会传递给该方法。如果登录(即checkPassword验证成功)成功,该用户将获取一个身份(subject,类似javax.security.auth安全框架的subject),然后会依次调用UserRegistry实现类的getUniqueUserId,getUniqueGroupIds,getUserSecurityName方法,给该subject一些其他信息。

   根据前面的介绍,当登录成功后,该用户能够获取一个subject,该subject拥有他的userid,userSerurityName,以及根据getUniqueGroupIds他可以操作的机构。
用户通过认证,获得subject之后,有什么用处呢?下面继续看看。

2. EJB的调用安全性。
   其实这个很简单,也就是一些EJB,包括自己编写的,以及WPS自带的,都能对于自己的EJB程序进行安全保证,需要通过认证的用户才能调用他。
如以下配置:
<assembly-descriptor>
<security-role>
<role-name>serviceUser</role-name>
</security-role>
<container-transaction>
<method>
<ejb-name>AuditService</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
   规定了该EJB存在安全的配置,存在了角色对应某些方法的安全性映射,比如这里角色serviceUser就对应了EJB AuditService所有方法,对应WPS中的配置如下:



    其中配置就说明了,EJB中的某些角色对应的某些方法,什么情况能够被外界调用,上图是WPS中默认的BPM API 的配置,其中大部分说明了,BPM的API只有被认证的用户才能调用,这也是前面为什么配置安全性的原因之一,只有通过安全认证,获得了subject,这样才能调用符合配置的EJB。


3. 人工任务的分配。

   总所周知,WPS的人工任务分配是项目中的重点,流程大部分存在的原因也是因为人工任务的,毕竟业务是人来参与的,人参与就涉及到权限的分配,这种我们将讨论常用的几种任务分配方式,毕竟分配权限的方案实在太多,很多时候可能WPS的任务分配甚至也完成不了业务需求,我们针对常用的几种方式讨论一下:
PS: 一下讨论默认分配的为potenion owner,其它 administrator,editor的是一样的。

  3.1  User by userID



   该方案分配到人,下面有个必填选项UserID变量,当我们将业务变量赋与 UserID变量,这样的该人工任务就分配到UserID,这样我们将可以在流程编排器里面看到该任务的potenion owner就是该变量的值。


   对应于自定义安全性,当我们的subject登录之后,会调用UserRegistry接口实现类的getUniqueUserId方法,当他的返回值和UserId 变量一致时,该subject是该任务的potenion owner

总结:
分配:  User by userID  的 UserId 对应UserRegistry接口实现类的getUniqueUserId方法

3.2 Users By user id

该任务是分配给多个人的,也需要至少配置一个参数 UserId.

当流程到达该人工任务时,WPS会调用UserRegistry的getUsers方法,返回该任务所有的潜在所有者集合。

只有通过认证的subject的getUniqueUserId返回的值在getUsers方法的结果集合中,该subject就能操作该人工任务。

总结:   Users By user id   对应UserRegistry接口实现类的getUsers方法。

3.3  Group Members

   任务分配给组员,需要配置两个参数,groupNames(组名), IncludeSubgroups(是否包含子组)

  配置了组名之后,当流程到达该任务的时候,会调用UserRegistry实现类的getUsersForGroup方法,返回一个人员的集合
和上面一样这个任务一样是分配到人的只有通过认证的subject的getUniqueUserId返回的值在getUsersForGroup方法的结果集合中,该subject就能操作该人工任务。

总结:   Group Members   对应UserRegistry接口实现类的getUsersForGroup方法。

3.4 Group

   该任务分配到组。
   注意到该任务和前面的不一样,前面的部分都是分配到人,这样对于业务场景可用性比较低,分配到组的话,我们可以对相同权限的人分组,这样对于业务场景下的人工任务分配或者是WPS的BPEDB的压力缓解都很有效。

   这里配置了变量分配给GroupID,这样流程到达该节点的时候,该人工任务的潜在所有者为该变量groupId的值。

   前面我们论述过了,一个通过认证的subject,会调用UserRegistry接口实现类的getUniqueGroupIds得到他所能操作的组,只要该SUBJECT能操作的组包括了groupId,该SUBJECT就能操作该人工任务。

  3.5 Group Search

    其实该分配方式和Group Member基本相似,都是通过组来查找组员。只是查找的方式不一样,这里的Group Search是先调用UserRegistry接口实现类的getGroups,得到匹配的多个组,然后通过多个组作为参数,调用UserRegistry接口实现类的getUsersForGroup,得到多个组符合要求的人员列表,都是该任务的潜在所有者。

   和前面一样,subject的getUniqueUserId返回的值在getUsersForGroup方法的结果集合中,该subject就能操作该人工任务。

  总结: Group Search对应UserRegistry  的 getGroups,getUsersForGroup方法。
 
    其实分配的方式有很多,这里我只是谈到我用到的这几种,还有其他的分配方式我没有试过,没有发言权,这是我最近这段时间使用WPS流程做项目的一点心得,WPS这东西,我也不骂他,也不恨他,也不喜欢他,但是我还是要用他。。。上面只是我自己的最近的一些总结,写的肯定不是很完善,也肯定有很多错误,希望大家来指正。
    希望写的东西对有需要的人有所帮助。
  • 大小: 15.8 KB
  • 大小: 12.9 KB
  • 大小: 10.4 KB
3
0
分享到:
评论
1 楼 jianghs 2009-05-08  
写的好,希望楼主能多发这样的学习文章。

相关推荐

Global site tag (gtag.js) - Google Analytics