jbPM4.4中的用户:
见:http://zybing.iteye.com/admin/blogs/778919
在jbpm.wire.bindings.xml配置中,
这2个和用户相关:
<binding class="org.jbpm.pvm.internal.wire.binding.IdentitySessionBinding" /> <binding class="org.jbpm.pvm.internal.wire.binding.IdentityServiceBinding" />
----------------
先看org.jbpm.pvm.internal.wire.binding.IdentityServiceBinding
这个是对外服务,提供的Identity Service类的绑定:
实现(主要的parse函数):
public Object parse(Element element, Parse parse, Parser parser) {
ObjectDescriptor descriptor = new ObjectDescriptor(IdentityServiceImpl.class);
descriptor.addInjection("commandService",
new ReferenceDescriptor(CommandService.NAME_TX_REQUIRED_COMMAND_SERVICE));
return descriptor;
}
这里加载了IdentityServiceImpl,实现了IdentityService接口;
IdentityServiceImpl实现了对外用户服务的功能,每个功能一个command;如:
public void createUser(String userId, String givenName, String familyName) {
commandService.execute ( new
CreateUserCmd(userId, givenName, familyName));
}
创建用户,其实是创建一个CreateUserCmd命令,然后又commandService去执行;
看CreateUserCmd:
具体的执行是是调用IdentitySession的对应功能:
public Void execute(Environment environment) throws Exception {
IdentitySession identitySession = environment.get(IdentitySession.class);
identitySession.createUser(userId, givenName, familyName, businessEmail);
return null;
}
再看其他的一些方法,也都是如此;都是调用IdentiitySession的对应功能;
--------------------------------------------------------------------------------
IdentitySession:
IdentitySession是内部实现用户功能的接口:
在jbpm.wire.bindings.xml配置中,
<binding class="org.jbpm.pvm.internal.wire.binding.IdentitySessionBinding" />
先看org.jbpm.pvm.internal.wire.binding.IdentitySessionBinding
public Object parse(Element element, Parse parse, Parser parser) {
ObjectDescriptor objectDescriptor = new ObjectDescriptor(IdentitySessionImpl.class);
objectDescriptor.addTypedInjection("session", Session.class);
return objectDescriptor;
}
是在加载IdentitySession:具体的实现是IdentitySessionImpl;
看IdentitySessionImpl中的具体方法:
public String createUser(String userName, String givenName, String familyName,
String businessEmail) {
try {
User user = findUserById(userName);
if (user != null) {
throw new JbpmException("Cannot create user, userId: [" + userName + "] has been used");
}
} catch(Exception ex) {
throw new JbpmException("Cannot create user, error while validating", ex);
}
UserImpl user = new UserImpl(userName, givenName, familyName);
user.setBusinessEmail(businessEmail);
long dbid = EnvironmentImpl.getFromCurrent(DbidGenerator.class).getNextId();
user.setDbid(dbid);
session.save(user);
return user.getId();
}
这个就是在调用数据库,获取数据了;
IdentitySession返回的用户,也是Interface: org.jbpm.api.identity.User;组是Group接口;
jBPM中的实现:org.jbpm.pvm.internal.identity.impl.UserImpl
--------------------------------------------------------------------------------
jBPM4.4改成自己的用户体系:
自己继承IdentitySession,实现接口方法;譬如为MyIdentitySessionImpl;
知道有2种方式把MyIdentitySessionImpl接入到系统中:
1. 自己实现一个IdentitySessionBinding,
在配置文件jbpm.wire.bindings.xml配置中,
把这个注释掉
<binding class="org.jbpm.pvm.internal.wire.binding.IdentitySessionBinding" />
绑定自己写的IdentitySessionBinding
2. 直接在transaction-context中指定自己的Session实现:
在配置文件jbpm.cfg.xml中:
<transaction-context> <object class="MyIdentitySessionImpl" /> </transaction-context>
==============================================================
SpringSecurity的(DB)用户:
见:http://zybing.iteye.com/admin/blogs/548085
SpringSecurity的用户配置为:authenticationManager
用Roller中的配置来说明一下:
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="daoAuthenticationProvider"/> <!-- Uncomment this for LDAP/SSO configuration <ref local="ldapAuthProvider"/> --> <!-- Uncomment this for CAS/SSO configuration <ref local="casAuthenticationProvider"/> --> <ref local="anonymousAuthenticationProvider"/> <!-- rememberMeAuthenticationProvider added programmatically --> </list> </property> </bean>
如果是用的DB的用户管理,authenticationManager配的是daoAuthenticationProvider;
daoAuthenticationProvider的配置:
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="jdbcAuthenticationDao"/> <property name="userCache" ref="userCache"/> </bean>
daoAuthenticationProvider的配置属性有3个:
- userDetailsService: 这个负责从DB中获取用户对象
- userCache : 定义了用户对象如何缓存:
有2个选项:- nullUserCache 不用缓存
- EhCacheBasedUserCache: 通过EhCache进行缓存(见下面的例子)
- passwordEncoder: 定义了用户口令如何加密的:
有3个选项:- PlaintextPasswordEncoder: 就用明文,不加密
- ShaPasswordEncoder: 用Sha加密
- Md5PasswordEncoder:用Md5加密
其中userDetailsService是主角。
cache配置如下:
<bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache"> <property name="cache"> <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/> </property> <property name="cacheName" value="userCache"/> </bean> </property> </bean>
userDetailsService:其中只有一个方法,就是loadUserByUsername,返回UserDetails接口(就是包括获取用户属性的一些方法)
UserDetails接口在SpringSecurity中有一个user类具体的实现;
UserDetails中,有一个方法是获取用户权限的,返回:grantedAuthority[], 这也是一个接口,就是获取到权限的名字,具体的实现GrantedAuthorityImpl。
==============================================================
把jBPM用户和SpringSecurity用户都整合到自己的系统中来:
自己的系统是SSH的,通过Hibernate访问数据库,进行ORM的,
jBPM也配置成通过spring整合Hibernate的方式;
自己系统中,配置自己的userService,
把jBPM以及SpringSecurity的从数据库获取用户的地方,改成通过自己的userService获取用户对象。
不过这样获取的用户对方是自己的类,还要在jBPM中,在SpringSecurity中,通过转换成他们系统的 用户实现类;
如果系统直接绑定了jBPM和SpringSecurity,自己的用户类就直接实现jBPM和SpringSecurity的用户接口,这样转换都省掉了,不过这样代码的适用范围就小了,看个人实际情况吧。