InfoQ

InfoQ

文章

我的书签

登录注册 以永久保存书签。

该内容已经被标记书签!

标记书签错误,请重试!

用Acegi Security来保护Grails应用

作者 Fadi Shami 译者 宋玮 发布于 2008年3月14日

领域
架构 & 设计,
语言 & 开发
主题
Java ,
安全
标签
Groovy ,
Grails

目录

简介
建立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

简直就是在堆积木嘛! 发表人 .oO tipfoo 发表于
请问如果想增加一个权限,该权限除删除外其他和manager权限一样时如何处理 发表人 Lau Andy 发表于
有个大问题 发表人 吴 建涛 发表于
非常感谢 发表人 shen li 发表于
manager要每个限制里, 不爽. 发表人 linbin chen 发表于
Grails 中有没专用于Domain建模的工具 发表人 tang zhejiang 发表于
  1. 返回顶部

    简直就是在堆积木嘛!

    发表人 .oO tipfoo

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

  2. 返回顶部

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

    发表人 Lau Andy

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

  3. 返回顶部

    有个大问题

    发表人 吴 建涛

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

  4. 返回顶部

    非常感谢

    发表人 shen li

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

  5. 返回顶部

    manager要每个限制里, 不爽.

    发表人 linbin chen

    /race/*
    是manager

    /race/list/*
    是user

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

  6. 返回顶部

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

    发表人 tang zhejiang

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

深度内容

大规模视频网站的计费与流量管理

本次分享将会就大规模视频网站的计费与流量管理这个话题,从操作层面细细进行讲解和分析,为系统工程师们揭示平日里我们没有关心的另一些内容。同时也希望本次分享能揭示行业中的一些“潜规则”,让互联网行业的流量与带宽管理更为开放与简洁。
本次演讲视频录制于QCon杭州2011

专访Jeffrey Richter:Windows 8是微软的重中之重

Jeffrey Richter以其多本Windows核心技术的经典著作而闻名,同时,他深入掌握微软的.NET等一系列核心技术,2012年1月,Jeffrey Richter在北京接受了InfoQ中文站的专访,谈到Windows 8和WinRT编程,并就异步编程、Windows编程中的可扩展性、性能和安全性方面给出自己的建议。

应用云平台的可用性——从新浪SAE看云平台设计

云计算平台的可用性,相比传统互联网服务而言,更加复杂和困难,也更具有挑战性。本文借助新浪SAE云平台为读者讲述了云平台可用性的定义、如何打造高可用的平台,以及对云计算的用户提出了建议。

JVM定制改进 @ 淘宝

淘宝高度重视Java平台的健康发展,组建了一个团队专注于Java平台的底层部分的性能、功能与稳定性改进;工作主要基于OpenJDK中的HotSpot VM开展,其中一些通用的功能随后也会逐渐反馈给OpenJDK社区。希望能与使用Java平台开发应用的大家交流经验。
本次演讲视频录制于QCon杭州2011

"伤得起"的云计算应用——对云端应用之架构的思考

2011年4月21日至22日是值得云计算从业者纪念的日子。Amazon的IaaS服务出现故障,导致许多商业网站的服务中断,影响非常严重。作为云计算用户,我们需要思考的是,如何保证即便在云服务不可用的情况,我们的应用架构仍然能够屹立不倒?本文正是站在云计算用户的角度试图探讨这一问题。

让交付的速度跟上思考的速度

12人的技术团队,4组刀片服务器,每月20亿的访问量,每日1次准时部署,99.9%的可用性。这可能吗?当然。想知道如何做的吗?百姓网将与您分享他们在DevOps实践过程中的经验和技巧。
本次演讲视频录制于QCon杭州2011

架构之路——穿行在产品和业务之间

篱笆作为一家起源于社区的电子商务公司,反映到技术层面就是同时要面对产品和业务,以及经营战略的变化调整。如何在产品和业务的夹缝之间完成技术架构的抽象与平衡,寻找更有效的价值定位,这当中有些经验教训和个人感悟愿与众人分享。
本次演讲视频录制于QCon杭州2011

特性注入:成功三部曲

本文将对特性注入以及相关方法做一个扫盲性的介绍。我们会解释这个框架的关键要素,并附上实例来证实它们。为了让文章保持相对较短,我们不会深入到某个工具或方法中,而是会给出一些参考资料,以便大家做进一步的研究。