建立RaceTrack 例子应用安装Grails Acegi plugin 创建Acegi Security 组件配制Acegi Security 来保护应用测试
简介
本文论述了grails-acegi plugin 与一个简单Grails 应用的集成。集成使用了三个主要组件—— Groovy , Grails 和 Acegi 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.0 、 grails-acegi-0.2 plugin 以及 Java SE JDK 5.0 或更新版。
这里,我们假定你已经实现了 Grails 入门指南中所描述的 RaceTrack 应用的大部分功能。但是,为了测试 grails-acegi plugin,你不必完成整个指南。测试 grails-acegi plugin 所需的全部东西包括:领域类(domain classes)和 controller,controller 的脚手架对于测试来说已经足够了。
图 1 —— 创建 racetrack 应用后的目录结构
你的 RaceTrack 应用目录看起来应该和图 1 显示的类似。现在,打开\grails-app\domain 目录:
图 2 —— 领域类目录
正如你从图 2 中看到的,“domain”目录只包含了两个 domain 类:Race 和 Registration。现在,打开\grails-app\controllers 目录,确认一下每个 domain 类都有一个对应的 controller,如图 3 所示:
图 3 —— Controllers 目录
这些 controller 可以是空的、脚手架(scaffold)controller,例如:
class RaceController { def scaffold = Race }<p> class RegistrationController { def scaffold = Registration }</p>
这足以让程序跑起来了。在你开始运行 RaceTrack 应用之后,你将能够在如图 4 所示的 contoller list 中看到两个你所创建的 controller:
图 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 目录
创建 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 中使用)
图 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 被创建的时候创建的)
图 9 —— 安装 grails-acegi-plugin 之后可用的 Controller
访问 RaceTrack 首页——它看上去类似于图 9 所示内容。
配制 Acegi Security 来保护应用
我们现在创建一个用户角色和管理者角色——首先点击 RoleController,输入角色名“user”以及角色描述(图 10)。注意 RoleController 将会把“user”转换成“ROLE_USER”,数据库中和 Acegi 的配置中将使用“ROLE_USER”。重复同样的步骤创建一个管理者角色。
图 10 —— 创建一个用户角色
回到首页,点击 UserController。现在创建一个拥有“user”角色的用户和另一个拥有“manager”角色的用户,如图 11 所示:
图 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 访问规则
注意,一个好的习惯是给 manager 角色也授予所有用户权限。下一步将给用户角色创建访问规则——在 URL 域输入“/race/list/**”,在 Role 域输入“user, manager”(图 13——注意角色之间是用逗号分隔的)。这一步骤将创建这样一个访问规则——允许 user 和 manager 角色都能访问 race 列表页面。注意这两个角色你都需要指定——如果你只将该 URL 指派给 user 角色,它将覆盖前面给 manager 指派的规则,这样只有 user 角色才能访问该页面。为前面定义的其他规则重复这一步骤——这将为 race 和 registration 页创建所有的访问规则。
图 13 —— 为 /race/list/** 页面创建规则——准许 user 和 manager 角色访问
测试
在 RaceTrack 首页上点击 RaceController 或 RegistrationController(我们已经保护了这些 controller)。你将注意到页面自动重定向到了 Login 页面。如果你先以 manager 角色的用户登录,你就能够浏览、创建、更新和删除 race 和 registration 页面的任何东西。
图 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 视图
Figure 16 —— 访问禁止错误页
恭喜你——现在你已经有了 RaceTrack 应用的一个完整的安全实例了!
评论