使用Grails结合acegi开发权限设置总结

最近,研究了一下如何用Grails 结合 Spring acegi 开发一个权限设置的例子。

需求:

   当管理员点开一个role页面后,显示该role具有的权限和系统所有的权限,可以对其修改。




 思路:

1)将uri定义在requestmap中,在运行过程中通过filter判断是否当前用户有权限。涉及的对象Person, Authority, Requestmap
2)借助 acegi提供的 requestmap, 将系统的权限都已requestmap的形式体现出来,如

             /project/create**   项目创建

             /project/list**      项目列表

             /project/edit**     项目编辑

             /project/delete**   项目删除

 

    在查看某个rolerequestmap(比如点击edit),使用如下sql语句 获取该role对应的requestmap,在页面上显示出来
private List findRequestmapsByRole(authority)
    {
        Requestmap.executeQuery(
                
"SELECT rm FROM Requestmap rm " +
                
"WHERE rm.configAttribute LIKE :roleName",
                [roleName: 
'%'+authority.authority+'%'])
    }

显示过程如下,resourceMap中的keyrequestmap, valuetrue 或者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]
    }

当提交某个rolerequestmap修改时,采用如下方法,循环更新所有的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)
        }

 

 具体步骤如下:

  1)      BootStrap中建立几个Role, 建立几个requestmap

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: 
"sebastien@epseelon.com"
             )
             me.save()
             
             def user 
= new Person(
                     
//username: "sarbogast",
                     username: "leiw",
                     userRealName: 
"leiw dandan",
                     passwd: authenticateService.encodePassword(
"111111"),
                     enabled: 
true,
                     email: 
"leiw@epseelon.com"
             )
             user.save()
             
             def projectAdmin 
= new Person(
                     
//username: "sarbogast",
                     username: "project",
                     userRealName: 
"project admin",
                     passwd: authenticateService.encodePassword(
"111111"),
                     enabled: 
true,
                     email: 
"project@epseelon.com"
             )
             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) Acegirequstmap只是对url的过滤,对于grails默认生成的show view中,其editdelete的方式是采用参数来提交的,其提交格式类似/project/index?action_edit=edit, 所以acegi无法正确截获
<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>

 

4) 修改requestmap domain,增加description,方便checkbox显示额外的权限描述信息。

posted on 2012-02-14 17:01 想飞就飞 阅读(744) 评论(0)  编辑  收藏 所属分类: Groovy/Grails


只有注册用户登录后才能发表评论。


网站导航:
 

公告


导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

常用链接

留言簿(13)

我参与的团队

随笔分类(69)

随笔档案(68)

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜