正在做的2个系统都是采用ralasafe中间件来实现权限的控制,不过都是各自有独立的应用库和ralasafe权限库。但是考虑到未来有可能2个系统会整合或有更多的系统会采用相同的权限控制,这时会遇到的问题是:
1、ralasafe的权限、查询、用户分类等等表在增加相应记录时是采用sequence增长的(在ralasafe_sequence表里有处理各表的当前值),那么如果各个系统各自拥有自己的ralasafe库,在系统整合时会导致这些表的id值冲突。
2、另外在权限库里的ralasafe_ralasafe_userrole里保存的userid也会存在冲突。
3、即时userid不冲突,但是登录时若不采用userid,而是用户自己申请的针对不同系统的登录帐号,也可能存在冲突(如两个系统都有“admin”帐号“)
于是考虑做集中权限控制:让不同系统应用使用同一个权限库!
(通过更改配置文件ralasafe-db.properties指定同一个权限库即可)
采用同一个权限库,可以解决上述的问题1,但是对于问题2就要设法保证各个系统的userid都不冲突!
最简单的可以把userid设计为保存UUID值的varchar(32)类型,这样要实现的就是更改元数据映射类型(可参考另一篇博文):
<table ds="app" name="mainTable" sqlName="UserView"
uniqueFields="loginName">
<field name="id" columnName="id" sqlType="varchar(32)" javaType="java.lang.String" />
<field name="loginName" columnName="loginName" sqlType="varchar(12)"
javaType="java.lang.String" />
<field name="password" columnName="password" sqlType="varchar(100)"
javaType="java.lang.String" />
若不是初始化ralasafe元数据,要手动修改的话则要把ralasafe_ralasafe_userrole的userid类型也更改成varchar(32)。
但是对于登录名和密码的冲突,我参考了ralasafe的配置手册,发现可以通过组合键进行登录控制。
1、在元数据上设置uniqueFields为组合键,appName为应用模块的标识值,如”OA“,”CRM“等等
<table ds="app" name="mainTable" sqlName="UserView"
uniqueFields="appName,loginName">
<field name="id" columnName="id" sqlType="varchar(10)" javaType="java.lang.String" />
<field name="appName" columnName="appName" sqlType="varchar(3)"
javaType="java.lang.String" displayName="appName" show="true" />
<field name="loginName" columnName="loginName" sqlType="varchar(12)"
javaType="java.lang.String" />
2、在web.xml配置登录的Filter
<filter>
<filter-name>ralasafe/LoginFilter</filter-name>
<filter-class>org.ralasafe.webFilter.LoginFilter</filter-class>
<init-param>
<param-name>loginPage</param-name>
<param-value>/jsp/admin/login.jsp</param-value>
</init-param>
<init-param>
<param-name>uniqueFieldsParams</param-name>
<param-value>appName,loginName</param-value> <!--此处增加组合登录验证-->
</init-param>
3、jsp的登录表单上除了loginName,password,还要增加一个appName(不同的应用系统的值会不同)
<form id="_form" method="post" action="admin_base/loginAdmin_login.action" >
<input type="hidden" name="appName" value="CRM"/>
4、数据库记录demo:
ralasafe_ralasafe_userrole表数据:
而应用系统的userview视图数据:
OA库:
CRM库:
这样,使用ralasafe自带的登录验证时,会根据appName和loginName来进行验证,获取唯一的id(此处我没采用UUID了,直接使用appName作为前缀)后处理获取各自应用系统的userid值即可!
5、对于要部署一个应用时只需要把相关的数据导出来。所以在配置权限、查询时需要注意的是:一个应用里的相关配置要设置一个根节点,这样方便导出。如:权限树里配置一个OA系统节点,然后OA系统相关的权限都在此节点下配置。
目前先这么解决了(我们环境:只在开发系统阶段有更新ralasafe权限等表,部署阶段只是导出。),而且ralasafe表现很好,权限数据库放服务器上,应用库放开发机器上也没有问题,呵呵~ 不知有没有其他更好的方式哈!
另:做的过程遇到一个问题,就是userview视图的设计上,如果采用
select `sysuser`.`userRsNo` AS `id`,'CRM' AS `appName`,... from `sysuser` 创建视图时程序都运行正常。
但是如果采用
select concat('OA.',`sysuser`.`userNo`) AS `id` AS `id`,'CRM' AS `appName`,... from `sysuser` 来创建,会抛异常。
操作异常:java.lang.ClassCastException: [B cannot be cast to java.lang.String
调试跟踪ralasafe,发现对于id的值,从ResultSet获取出来后不能强转为String类型,有空再研究一下看看
转载于:https://www.cnblogs.com/windelk/archive/2011/09/24/2189335.html