写点什么

用 Acegi Security 来保护 Grails 应用

2008 年 3 月 14 日

建立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 应用的一个完整的安全实例了!

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

2008 年 3 月 14 日 03:493569
用户头像

发布了 150 篇内容, 共 35.6 次阅读, 收获喜欢 2 次。

关注

评论

发布
暂无评论
发现更多内容

程序员的晚餐 | 5 月 17 日 当西红柿遇上鱼

清远

美食

Collaboration on SaaS

zhenglei

SaaS Collaboration Cisco Webex

键入网址后,其间发生了什么?

小林coding

TCP 计算机网络 网络协议 IP HTTP

如何用一套引擎搞定机器学习全流程?

Apache Flink

大数据 flink 流计算 实时计算 大数据处理

回“疫”录(19):都什么时候了,还在搞“填表抗疫”

小天同学

疫情 回忆录 现实纪录 纪实 形式主义

都前后端分离了,咱就别做页面跳转了!统统 JSON 交互

江南一点雨

spring Spring Boot spring security

机会,是不会让你准备好的

Winann

学习 生活 知识管理 机会

写作对我的意义

Neco.W

总结 思考 写作 感悟

2020第一篇技术博客

java劝退师首席大弟子

生活

【高级进阶】写给大忙人看的JDK14新特性

知春秋

Java java 14 java 14 新特性

Docker 镜像制作教程:针对不同语言的精简策略

米开朗基杨

Docker Dockerfile

《零基础学 Java》 FAQ 之 8-Java方法调用是传值还是传引用

臧萌

Java

如何搞定Kafka重复消费?

奈学教育

kafka kafka配置

微服务为什么要有服务发现与注册?

攀岩飞鱼

微服务 微服务冶理 微服务发现

Java如何处理异常情况

Rayjun

Java 异常

EasyExcel最权威教程

知春秋

Java Excel EasyExcel

2020年比以往任何时候更想做成的使命感

乐少

从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(一)

图雀社区

node.js vue.js Vue

从连续两届图灵奖(2018-2019)看GPU发展史

GPU

人工智能 gpu 计算机基础 计算机图形学 计算机体系结构

笔记:《如何系统思考》之如何应用系统思考

wiflish

思维方式

Design Sprint 教你五天完成产品迭代

Yanel 说敏捷产品

产品 敏捷 设计 产品设计 团队

少说废话,先干起来

白鸽

学习 个人成长 自律

Kotlin协程实践之进程、线程、协程

陈吉米

Java kotlin 协程 Coroutine

发布Maven包的正确姿势

廖雪峰

maven 开源

DevOps生命周期,你想知道的全都在这里了!

陈琦

DevOps 测试 持续集成

游戏夜读 | Scikit-learn迎来0.21版本

game1night

比AtomicLong更优秀的LongAdder确定不来了解一下吗?

一枝花算不算浪漫

并发编程 jdk源码

JAVA内存模型与线程

颇风

Java 内存模型 JVM

一种练好英语口语的方法

七镜花园-董一凡

学习

有问必答(2020-05-09):如何督促自己做好一件事情?

冯夷

生活

11 万字的字节码编程系列合集放送(ASM、Javassist、Byte-buddy、Javaagent)

小傅哥

Java asm bytebuddy 《字节码编程》

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

用Acegi Security来保护Grails应用-InfoQ