技术开发 频道

精通 Grails: 身份验证和授权

  使用插件实现更高级功能

  这个 “微型” 博客应用程序的 “微型” 身份验证和授权系统现在已经初具雏形。您可以轻松地对它进行扩展。也许您希望 User 能够管理他们各自的帐户,而不是其他人的。也许 admin 应当具备编辑所有 Entries 的能力,而不仅仅是编辑他们自己的。在这些情况下,只需要策略性地放置几行代码就可以添加新的功能。

  人们常常将简洁性误解为缺乏功能。Blogito 仍然不足 200 行代码 — 并且这还包含了单元和集成测试。在命令行输入 grails stats 以确认这点。结果如清单 12 所示。但是 Blogito 不复杂并不表示它的功能不完备。

  清单 12. “微型” 应用程序的大小

$ grails stats

    
+----------------------+-------+-------+
    | Name                 | Files |  LOC  |
    
+----------------------+-------+-------+
    | Controllers          |    
2 |    95 |
    | Domain Classes       |    
2 |    32 |
    | Tag Libraries        |    
2 |    21 |
    | Unit Tests           |    
5 |    20 |
    | Integration Tests    |    
1 |    10 |
    
+----------------------+-------+-------+
    | Totals               |    
12 |   178 |
    
+----------------------+-------+-------+

  从本系列的第一篇文章开始,我的目标就是向您展示核心 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 策略的好处。

0
相关文章