使用Grails结合acegi开发权限设置总结
最近,研究了一下如何用Grails 结合 Spring acegi 开发一个权限设置的例子。
需求:
思路:
只能将 form 改成原 HTML 原始的方式
当管理员点开一个role页面后,显示该role具有的权限和系统所有的权限,可以对其修改。
1)将uri
定义在requestmap
中,在运行过程中通过filter
判断是否当前用户有权限。涉及的对象
Person, Authority, Requestmap
2)借助 acegi
提供的 requestmap,
将系统的权限都已requestmap
的形式体现出来,如
/project/create** 项目创建
/project/list** 项目列表
/project/edit** 项目编辑
/project/delete** 项目删除
在查看某个
role
的
requestmap
时
(
比如点击
edit)
,使用如下
sql
语句
获取该
role
对应的
requestmap
,在页面上显示出来
private
List findRequestmapsByRole(authority)
{
Requestmap.executeQuery(
" SELECT rm FROM Requestmap rm " +
" WHERE rm.configAttribute LIKE :roleName " ,
[roleName: ' % ' + authority.authority + ' % ' ])
}
{
Requestmap.executeQuery(
" SELECT rm FROM Requestmap rm " +
" WHERE rm.configAttribute LIKE :roleName " ,
[roleName: ' % ' + authority.authority + ' % ' ])
}
显示过程如下,resourceMap中的key为requestmap, value为true 或者false,然后就可以在前台的checkbox中显示出来
private
Map buildAuthorityModel(authority) {
List requestmaps = Requestmap.list()
requestmaps.sort { r1, r2 ->
r1.url <=> r2.url
}
List ownedRequestmaps = findRequestmapsByRole(authority)
Set authResourcesNames = []
for (requestmap in ownedRequestmaps) {
authResourcesNames << requestmap.url
}
LinkedHashMap < Requestmap, Boolean > resourceMap = [:]
for (requestmap in requestmaps) {
resourceMap[(requestmap)] = authResourcesNames.contains(requestmap.url)
}
System.out.println(resourceMap);
return [authority: authority, resourceMap: resourceMap]
}
List requestmaps = Requestmap.list()
requestmaps.sort { r1, r2 ->
r1.url <=> r2.url
}
List ownedRequestmaps = findRequestmapsByRole(authority)
Set authResourcesNames = []
for (requestmap in ownedRequestmaps) {
authResourcesNames << requestmap.url
}
LinkedHashMap < Requestmap, Boolean > resourceMap = [:]
for (requestmap in requestmaps) {
resourceMap[(requestmap)] = authResourcesNames.contains(requestmap.url)
}
System.out.println(resourceMap);
return [authority: authority, resourceMap: resourceMap]
}
当提交某个role的requestmap修改时,采用如下方法,循环更新所有的requestmap
private
void
updateRequestmaps(authority) {
List requestmaps = Requestmap.list()
for (requestmap in requestmaps)
{
String configAttribute = requestmap.configAttribute
Set parts = configAttribute.split( ' , ' ) as Set
String roleName = authority.authority
String value = params.get(requestmap.url)
// request map checked
if ( ' on ' == value)
{
parts.add(roleName)
}
else
{
parts.remove(roleName)
}
requestmap.configAttribute = parts.join( ' , ' )
System.out.println(parts)
}
List requestmaps = Requestmap.list()
for (requestmap in requestmaps)
{
String configAttribute = requestmap.configAttribute
Set parts = configAttribute.split( ' , ' ) as Set
String roleName = authority.authority
String value = params.get(requestmap.url)
// request map checked
if ( ' on ' == value)
{
parts.add(roleName)
}
else
{
parts.remove(roleName)
}
requestmap.configAttribute = parts.join( ' , ' )
System.out.println(parts)
}
具体步骤如下:
2) 将这些requestmap 分配给一个超级管理员(ROLE_ADMIN)
class
BootStrap {
def authenticateService
def init = { servletContext ->
Person.withTransaction {
def me = new Person(
// username: "sarbogast",
username: " admin " ,
userRealName: " Sebastien Arbogast " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
me.save()
def user = new Person(
// username: "sarbogast",
username: " leiw " ,
userRealName: " leiw dandan " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
user.save()
def projectAdmin = new Person(
// username: "sarbogast",
username: " project " ,
userRealName: " project admin " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
projectAdmin.save()
def adminAuth = new Authority(
description: " administrator " ,
authority: " ROLE_ADMIN "
)
adminAuth.save()
def projectAdminAuth = new Authority(
description: " project administrator " ,
authority: " ROLE_PROJECT_ADMIN "
)
projectAdminAuth.save()
def userAuth = new Authority(
description: " user " ,
authority: " ROLE_USER "
)
userAuth.save()
me.addToAuthorities(adminAuth)
me.addToAuthorities(userAuth)
projectAdmin.addToAuthorities(projectAdminAuth)
user.addToAuthorities(userAuth)
def authorityMap = new Requestmap(
url: ' /authority/** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 角色管理 '
)
authorityMap.save()
def requestmapMap = new Requestmap(
url: ' /requestmap/** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 资源管理 '
)
requestmapMap.save()
def projectListMap = new Requestmap(
url: ' /project/list** ' ,
configAttribute: ' ROLE_USER, ROLE_ADMIN, ROLE_PROJECT_ADMIN ' ,
description: ' 项目查看 '
)
projectListMap.save()
def projectCreateMap = new Requestmap(
url: ' /project/create** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目新增 '
)
projectCreateMap.save()
def projectEditMap = new Requestmap(
url: ' /project/edit** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目修改 '
)
projectEditMap.save()
def projectDelMap = new Requestmap(
url: ' /project/delete** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目删除 '
)
projectDelMap.save()
new Project(title: ' test1 ' , description: '' ).save();
new Project(title: ' test2 ' , description: '' ).save();
new Project(title: ' test3 ' , description: '' ).save();
}
}
def destroy = {
}
}
3)
Acegi
的
requstmap
只是对
url
的过滤,对于
grails
默认生成的
show view
中,其
edit
和
delete
的方式是采用参数来提交的,其提交格式类似
/project/index?action_edit=edit,
所以
acegi
无法正确截获
def authenticateService
def init = { servletContext ->
Person.withTransaction {
def me = new Person(
// username: "sarbogast",
username: " admin " ,
userRealName: " Sebastien Arbogast " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
me.save()
def user = new Person(
// username: "sarbogast",
username: " leiw " ,
userRealName: " leiw dandan " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
user.save()
def projectAdmin = new Person(
// username: "sarbogast",
username: " project " ,
userRealName: " project admin " ,
passwd: authenticateService.encodePassword( " 111111 " ),
enabled: true ,
email: " [email protected] "
)
projectAdmin.save()
def adminAuth = new Authority(
description: " administrator " ,
authority: " ROLE_ADMIN "
)
adminAuth.save()
def projectAdminAuth = new Authority(
description: " project administrator " ,
authority: " ROLE_PROJECT_ADMIN "
)
projectAdminAuth.save()
def userAuth = new Authority(
description: " user " ,
authority: " ROLE_USER "
)
userAuth.save()
me.addToAuthorities(adminAuth)
me.addToAuthorities(userAuth)
projectAdmin.addToAuthorities(projectAdminAuth)
user.addToAuthorities(userAuth)
def authorityMap = new Requestmap(
url: ' /authority/** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 角色管理 '
)
authorityMap.save()
def requestmapMap = new Requestmap(
url: ' /requestmap/** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 资源管理 '
)
requestmapMap.save()
def projectListMap = new Requestmap(
url: ' /project/list** ' ,
configAttribute: ' ROLE_USER, ROLE_ADMIN, ROLE_PROJECT_ADMIN ' ,
description: ' 项目查看 '
)
projectListMap.save()
def projectCreateMap = new Requestmap(
url: ' /project/create** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目新增 '
)
projectCreateMap.save()
def projectEditMap = new Requestmap(
url: ' /project/edit** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目修改 '
)
projectEditMap.save()
def projectDelMap = new Requestmap(
url: ' /project/delete** ' ,
configAttribute: ' ROLE_ADMIN ' ,
description: ' 项目删除 '
)
projectDelMap.save()
new Project(title: ' test1 ' , description: '' ).save();
new Project(title: ' test2 ' , description: '' ).save();
new Project(title: ' test3 ' , description: '' ).save();
}
}
def destroy = {
}
}
<
g:form
>
< g:hiddenField name = " id " value = " ${projectInstance?.id} " />
< span class = " button " >< g:actionSubmit class = " edit " action = " edit " value = " ${message(code: 'default.button.edit.label', default: 'Edit')} " /></ span >
< span class = " button " >< g:actionSubmit class = " delete " action = " delete " value = " ${message(code: 'default.button.delete.label', default: 'Delete')} " onclick = " return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}'); " /></ span >
</ g:form >
< g:hiddenField name = " id " value = " ${projectInstance?.id} " />
< span class = " button " >< g:actionSubmit class = " edit " action = " edit " value = " ${message(code: 'default.button.edit.label', default: 'Edit')} " /></ span >
< span class = " button " >< g:actionSubmit class = " delete " action = " delete " value = " ${message(code: 'default.button.delete.label', default: 'Delete')} " onclick = " return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}'); " /></ span >
</ g:form >
只能将 form 改成原 HTML 原始的方式
<
form action
=
"
/todolist/project/edit
"
>
</form>
< form action = " /todolist/project/delete " method = " post " ></ form >
< form action = " /todolist/project/delete " method = " post " ></ form >
4) 修改requestmap 的domain,增加description,方便checkbox显示额外的权限描述信息。