从本系列的第一篇文章开始,我的目标就是向您展示核心 Grails 与生俱来的强大功能,以及 Groovy 语言的简洁的表达能力。例如,一旦理解了 Grails 的编解码器,就可能打乱数据库中存储的密码,而不是以简洁的形式显示出来(有关 HashCodec 的更多信息,参见 参考资料)。创建 grails-app/utils/HashCodec.groovy 并添加清单 13 中的代码:
清单 13. 创建一个简单的 HashCodec
import java.security.MessageDigest import sun.misc.BASE64Encoder import sun.misc.CharacterEncoder class HashCodec { static encode = { str -> MessageDigest md = MessageDigest.getInstance('SHA') md.update(str.getBytes('UTF-8')) return (new BASE64Encoder()).encode(md.digest()) } } |
有了 HashCodec 之后,只需要在 UserController 的 login、save 和 update 闭包中将对 User.password 的引用修改为 User.password.encodeAsHash()。令人惊讶的是,只需要 10 行代码,您让应用程序变得更高级。
但是,有时并不是增加代码就能获得回报。对于 Grails 中,典型的 “构建还是购买” 问题变成了 “构建还是下载插件”。http://grails.org/plugin/list#security+tags 中的一些插件试图解决身份验证和授权挑战,使用了与 grails install-plugin 不同的方法。
比如,Authentication 插件提供了一些非常不错的特性,例如允许 User 注册一个帐户,而不是要求 admin 为他们创建帐户。随后可以配置此插件,向 User 发送一条确认消息,表示 “使用这个电子邮件地址创建了一个新的用户帐户。单击此链接将验证您的新帐户”。
OpenID 插件则采取不同的方法。您的最终用户不需要创建另一个用户名和密码组合(他们肯定会遗忘),身份验证被委托给他们选择的 OpenID 提供商。Lightweight Directory Access Protocol (LDAP) 插件采用了类似地方法,允许您的 Grails 应用程序利用现有的 LDAP 基础设施。
Authentication 和 OpenID 插件只提供身份验证功能。其他插件还提供了授权解决方案。JSecurity 插件提供了一个完整的安全框架,为 User、Role 和 Permission 提供了模板(boilerplate)域类。Spring Security 插件利用了 Spring Security (formerly Acegi Security) 库,允许您重用现有的 Spring Security 知识和源代码。
可以看到,Grails 中可以应用多种身份验证和授权策略,因为应用程序之间的需求是不一样的。通过在功能中设置这些策略,应用程序不可避免地将增加相应的复杂性。在生产应用程序中,我曾使用了这里列出的一些插件,但前提是,必须确保使用插件带来的优点超过了我最早给出的简单的 hand-rolled 策略的好处。
结束语
您现在拥有了一个安全的 Blogito。User 拥有了一种登录和退出方法,以及一个可用于执行这些操作的方便的链接集合,这全部归功于所创建的 LoginTagLib。在某些情况下,只需要登录到应用程序就足够保证安全性了,正如检验身份验证的 EntryController 中的 beforeInterceptor 所展示的那样。对于其他情况,角色让授权更加高级。向 User 添加简单的角色允许将用户管理访问限制为只能由管理员执行。
现在 Blogito 已经具备了安全性,在下一期精通 Grails 文章中,我们将关注目前最主要的任务 — 为通过身份验证的用户提供一种方法来上传文件,以及为最终用户提供一种方法来订阅 Atom 提要。具备了这些功能后,Blogito 将真正成为一个博客应用程序。到那时,请尽情享受精通 Grails 的乐趣吧!(责任编辑:A6)