用 Acegi Security 来保护 Grails 应用

阅读数:3504 2008 年 3 月 14 日 03:49

建立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 }

class RegistrationController { def scaffold = Registration }

这足以让程序跑起来了。在你开始运行 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 应用的一个完整的安全实例了!

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

评论

发布