BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

用Acegi Security来保护Grails应用

| 作者 Fadi Shami 关注 0 他的粉丝 ,译者 宋玮 关注 0 他的粉丝 发布于 2008年3月15日. 估计阅读时间: 15 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

目录

简介
建立RaceTrack例子应用
安装Grails Acegi plugin
创建Acegi Security组件
配制Acegi Security来保护应用
测试

简介

本文论述了grails-acegi plugin与一个简单Grails应用的集成。集成使用了三个主要组件——Groovy, GrailsAcegi Security.

Groovy是一个针对Java平台的强大的高级语言,其代码最终被编译为Java字节码。在概念上,它类似于Ruby或Python,可是它与Java平台紧密地集成在一起。这就使你既可利用强大简明的编码语法,又可继续停留在JVM上,从而保护你在已有Java平台和相关类库上的投资。

Grails是一个用Groovy实现的全功能框架。Grails试图通过其核心技术及相关plug-in来解决Web开发中的许多难题。开箱即用的功能包括:

  • 建立在Hibernate之上的对象/关系映射(ORM)层
  • 被称为Groovy Server Pages(GSP)的富于表现的视图(View)技术
  • 构建在Spring MVC之上的控制器(controller)层
  • 构建在Gant(基于Groovy的Ant)之上的一个命令行脚本环境
  • 一个内嵌Jetty容器,被配制为可实时进行资源重载
  • 通过内置Spring容器支持依赖注入(dependency injection)
  • 支持国际化(i18n),这一功能是使用Spring的MessageSource API来构建的
  • 事务服务层,其利用了Spring的事务管理功能
  • 广泛应用了领域特定语言(Domain-Specific Languages——DSLs)

Acegi Security是为企业级软件提供的一个强大的、灵活的安全解决方案,尤其是那些使用了Spring的应用。Acegi提供了全面的认证、授权、基于实例的访问控制、信道安全以及人类用户检测能力。

本文假定你已经阅读过了Grails指南——由Jason Rudolph所编写的Grails入门指南,而且已经实现了其中示例的RaceTrack应用。Grails-acegi plugin将被集成进RaceTrack,为你的应用提供安全性。利用grails-acegi plugin为你免除了在应用中实现Grails拦截器所需的开支,提供了比拦截器更加灵活的解决方案,也节约了你利用Acegi重新实现自己的安全系统所要花费的时间。

建立RaceTrack例子应用

首先,你需要下载Grails 1.0grails-acegi-0.2 plugin以及Java SE JDK 5.0或更新版。

这里,我们假定你已经实现了Grails入门指南中所描述的RaceTrack应用的大部分功能。但是,为了测试grails-acegi plugin,你不必完成整个指南。测试grails-acegi plugin所需的全部东西包括:领域类(domain classes)和controller,controller的脚手架对于测试来说已经足够了。

图 1 —— 创建完racetrack应用后的目录结构

图 1 —— 创建racetrack应用后的目录结构

你的RaceTrack应用目录看起来应该和图1显示的类似。现在,打开\grails-app\domain目录:

图 2 —— 领域类目录

图 2 —— 领域类目录

正如你从图2中看到的,“domain”目录只包含了两个domain类:Race和Registration。现在,打开\grails-app\controllers目录,确认一下每个domain类都有一个对应的controller,如图3所示:

图 3 —— Controllers目录

图 3 —— Controllers目录

这些controller可以是空的、脚手架(scaffold)controller,例如:

  class RaceController { def scaffold = Race }

class RegistrationController { def scaffold = Registration }

这足以让程序跑起来了。在你开始运行RaceTrack应用之后,你将能够在如图4所示的contoller list中看到两个你所创建的controller:

图 4 —— Grails-Acegi Plugin之前的首页

图 4 —— 使用Grails-Acegi Plugin之前的首页

安装Grails Acegi plugin

下一步是安装grails-acegi plugin,这样RaceTrack就可以利用该plugin所提供的基于角色的安全防护。在命令提示行中,进入到“racetrack”目录并运行如下命令:

grails install-plugin [path-to]/grails-acegi-0.2.zip 

这一命令会在“racetrack”目录下创建一个plugins目录,如图5所示:

图 5 —— 安装plugin之后所创建的plugins目录

图 5 —— 安装plugin之后所创建的plugins目录

创建Acegi Security组件

下一步是创建代表用户帐号(Accounts)和角色(Roles)的领域类。运行如下命令开始这一过程:

grails create-auth-domains AuthUser Role

这一命令将创建两个领域类(AuthUser和Role)、建立AcegiConfig类、并创建Login和Logout两个controller。AuthUser领域类代表你的用户,因此每个新用户都将在Auth_User表中创建一条新的记录。Role领域类代表每个用户所拥有的安全角色,Role将被指派给AuthUser。所有这些类都显示在图6中。

AcegiConfig类(图7)定义了你的应用的安全配置。配置中包括:用户领域类的名字(本例为AuthUser)以及角色领域类的名字(本例为Role),使用动态还是静态安全Urls,怎样设置email警报(打开或关闭它们)。

图 6 —— AuthUser.groovy、Role.groovy和Requestmap.groovy(在AcegiConfig中使用)

图 6 —— AuthUser.groovy、Role.groovy和Requestmap.groovy(在AcegiConfig中使用)

图 7 —— 已创建的AcegiConfig.groovy

图 7 —— 已创建的AcegiConfig.groovy

为了创建新的AuthUser,创建新的Role并指派给AuthUser,我们还得运行两个命令。其一是产生领域类的CRUD控制:

grails generate-manager

第二个是为controller和domain产生registration:

grails generate-registration

这些命令给了用户注册并创建其用户名和口令的能力,默认的安全角色将被指派给该用户。从图8可以看到所产生的这一controller集合:

图 8 —— CRUD controllers (Login和Logout controller是在AuthUser和Role被创建的时候创建的)

图 8 —— CRUD controllers (Login和Logout controller是在AuthUser和Role被创建的时候创建的)

图 9 —— 安装grails-acegi-plugin之后可用的Controller

图 9 —— 安装grails-acegi-plugin之后可用的Controller

访问RaceTrack首页——它看上去类似于图9所示内容。

配制Acegi Security来保护应用

我们现在创建一个用户角色和管理者角色——首先点击RoleController,输入角色名“user”以及角色描述(图10)。注意RoleController将会把“user”转换成“ROLE_USER”,数据库中和Acegi的配置中将使用“ROLE_USER”。重复同样的步骤创建一个管理者角色。

图 10 —— 创建一个用户角色

图 10 —— 创建一个用户角色

回到首页,点击UserController。现在创建一个拥有“user”角色的用户和另一个拥有“manager”角色的用户,如图11所示:

图 11 —— 创建一个标准用户,激活该帐户并为其指派“user”角色

图 11 —— 创建一个标准用户,激活该帐户并为其指派“user”角色

我们创建的角色和用户现在已经足够用作配置了,下一步是保护RaceTrack应用。有两种方法保护你的URLs:一种是动态,通过RequestmapController来实现;另一种是静态的,直接编辑AcegiConfig.groovy文件。动态配置是被推荐的选项,下面我们继续进行动态配置工作。

在我们保护应用之前,需要考虑一下应用需要给予怎样的访问规则。一个manager被允许读/写访问应用中的任何页面,即:

  • /race/*
  • /registration/*

一个用户被允许只读访问某些页面,包括:

  • /race/list/*
  • /race/show/*
  • /registration/list/*
  • /registration/show/*

这些规则需要使用RequestmapController翻译成Acegi请求映射(Acegi request map)中的条目。从RaceTrack首页上点击RequestmapController,转到“create a new requestmap”页面。在URL域内填写上“/race/**”,在Role域填写为“manager”(图12)——这将创建一条规则,允许任何拥有manager角色的用户访问/race下的所有URLs。同样的方法可以配置好registration(URL:/registration/**)。

图 12 —— Manager访问规则

图 12 —— Manager访问规则

注意,一个好的习惯是给manager角色也授予所有用户权限。下一步将给用户角色创建访问规则——在URL域输入“/race/list/**”,在Role域输入“user, manager”(图13——注意角色之间是用逗号分隔的)。这一步骤将创建这样一个访问规则——允许user和manager角色都能访问race列表页面。注意这两个角色你都需要指定——如果你只将该URL指派给user角色,它将覆盖前面给manager指派的规则,这样只有user角色才能访问该页面。为前面定义的其他规则重复这一步骤——这将为race和registration页创建所有的访问规则。

图 13 —— 为/race/list/**页面创建规则——准许user和manager角色访问

图 13 —— 为/race/list/**页面创建规则——准许user和manager角色访问

测试

在RaceTrack首页上点击RaceController或RegistrationController(我们已经保护了这些controller)。你将注意到页面自动重定向到了Login页面。如果你先以manager角色的用户登录,你就能够浏览、创建、更新和删除race和registration页面的任何东西。

图 14 —— 以一个用户身份登录

图 14 —— 以一个user身份登录

回到RaceTrack首页并点击LogoutController——这将使你的用户session失效并登出。再次点击LoginController,但是这次以user角色的用户登录。如果你转向/race/list的子页面(直接访问http://localhost:8080/racetrack/race/list或通过controller转过去),你将看到race/list视图(图15)。

记得么,访问规则只允许manager创建新记录,user角色只允许从List和Show页面读取数据——这意味着如果你以user角色的用户登录并点击了New Race(http://localhost:8080/racetrack/race/create),Acegi将阻止你浏览该页面,它阻止了一个新记录的创建。

它是怎么工作的呢?回想一下,我们给manager角色授权可以访问/race/*,但是只给user角色授权访问/race/list/*和/race/show/*。当拥有“user”角色的用户试图访问/race/create页面时,Acegi察看该用户所拥有的所有角色,发现其只有“user”角色——因为我们的Request map说了,必须是“manager”角色才被授权访问这一页面,于是访问这一页面的许可被禁止了。

顺便讲一下,在一个真正的应用中,你可能想要显示一个比默认错误页(图16)更好看的错误页。

图 15 —— Race List视图

图 15 —— Race List视图

Figure 16 —— 访问禁止错误页

Figure 16 —— 访问禁止错误页

恭喜你——现在你已经有了RaceTrack应用的一个完整的安全实例了!

查看英文原文:Securing a Grails Application with Acegi Security

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

简直就是在堆积木嘛! by .oO tipfoo

这样实现权限控制真是太爽了,简直就是在堆积木嘛!

请问如果想增加一个权限,该权限除删除外其他和manager权限一样时如何处理 by Lau Andy

请问如果想增加一个权限,该权限除删除外其他和manager权限一样时如何处理?

有个大问题 by 吴 建涛

run-app挺正常,一单做成war,发布到tomcat,acegi就彻底完蛋了。所有页面都可以访问,登陆,注册,全都报错。不知道是我配置的问题还是bug~bd,gg搜了一大圈儿也没解决成,郁闷ing

非常感谢 by shen li

利用您讲的acegi配置,我很快的搭建起了一个基于grails对全县管理系统,并通过测试和部署。非常顺利。支持一下!

manager要每个限制里, 不爽. by linbin chen

/race/*
是manager

/race/list/*
是user

/race/list/*
还要定义user,manager
觉得什么不方便

Grails 中有没专用于Domain建模的工具 by tang zhejiang

Grails应用
中有没专用于Domain建模的工具,有的话麻烦各位大哥大姐知照一声!

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

6 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT