Spring-Security-core插件使用教程

作者: 伯特·贝克威思,贝弗利塔尔博特

版本: 1.2.7.3

1. 创建Grails应用程序

$ grails create-app bookstore

$ cd bookstore

2. 安装该插件

$ grails install-plugin spring-security-core

3. 创建User和 Role 领域类。

$ grails s2-quickstart com.testapp User Role

You can choose your names for your domain classes and package; these arejust examples.

依据你的数据库,有些领域类的命名可能会受到限制, 尤其是那些与安全相关的。在创建诸如 "User"或者 "Group"为名的领域类之前, 请确认它们在你的数据库中不是被保护的关键字。

脚本自动创建了User类:

package com.testapp

package test

class User {

   transient springSecurityService

   String username

   String password

   boolean enabled

   boolean accountExpired

   boolean accountLocked

   boolean passwordExpired

   static constraints = {

      username blank: false, unique: true

      password blank: false

   }

   static mapping = {

      password column: '`password`'

   }

   Set<Role> getAuthorities(){

      UserRole.findAllByUser(this).collect {it.role } as Set

   }

   def beforeInsert() {

      encodePassword()

   }

   def beforeUpdate() {

      if (isDirty('password')) {

         encodePassword()

      }

   }

   protected void encodePassword() {

      password =springSecurityService.encodePassword(password)

   }

}

早期版本的插件没有包括密码加密逻辑的域类,但代码很干净。

Role类也是脚本自动创建:

package com.testapp

class Role {

   String authority

   static mapping = {

      cache true

   }

   static constraints = {

      authority blank: false, unique: true

   }

}

还创建了一个UserRole领域类来映射 many-to-many 连接类:

package com.testapp

import org.apache.commons.lang.builder.HashCodeBuilder

class UserRole implements Serializable {

   User user

   Role role

   boolean equals(other) {

      if (!(other instanceof UserRole)) {

         returnfalse

      }

      other.user?.id == user?.id&&

         other.role?.id == role?.id

   }

   int hashCode() {

     def builder = new HashCodeBuilder()

      if (user) builder.append(user.id)

      if (role) builder.append(role.id)

      builder.toHashCode()

   }

   static UserRole get(long userId, long roleId) {

      find 'from UserRole whereuser.id=:userId and role.id=:roleId',

         [userId: userId, roleId:roleId]

   }

   static UserRole create(User user, Role role, boolean flush = false) {

      new UserRole(user: user, role:role).save(flush: flush, insert: true)

   }

   staticboolean remove(User user, Role role, boolean flush = false) {

      UserRole instance =UserRole.findByUserAndRole(user, role)

      if (!instance) {

         returnfalse

      }

      instance.delete(flush: flush)

      true

   }

   static void removeAll(User user) {

      executeUpdate 'DELETE FROMUserRole WHERE user=:user', [user: user]

   }

   static mapping = {

      id composite: ['role', 'user']

      version false

   }

}

还自动创建了几个 UI 控制器和 GSP页面:

·        grails-app/controllers/LoginController.groovy

·        grails-app/controllers/LogoutController.groovy

·        grails-app/views/auth.gsp

·        grails-app/views/denied.gsp

脚本还编辑了grails-app/conf/Config.groovy ,为生成的领域类添加了一些配置,请确认这些修改是正确的。

这些自动生成的文件并不是插件的一部分 它们都是你的应用程序文件。它们帮助你开始,所以你可以按照自己的喜好去修改。它们包含了插件的最低需求。

插件不支持对所生成领域类的 CRUD 动作和 GSP页面;spring-security-ui插件 会为这些提供一个UI。现在你需要在grails-app/conf/BootStrap.groovy中预置一些用户和角色 (参看第7步)。

4. 创建一个被role限制使用的控制器

$ grails create-controller com.testapp.Secure

这行命令在创建一个控制器类:grails-app/controllers/com/testapp/SecureController.groovy。添加一些输出内容可以验证控制器工作是否正常。

package com.testapp

class SecureController {

   def index = {

      render 'Secure access only'

   }

}

5. 启动服务

$ grails run-app

6. 导航到http://localhost:8080/bookstore/secure 在进入secure页面之前 你看不到登陆页面。

7. 停止服务,编辑 grails-app/conf/BootStrap.groovy 文件,添加你需要的安全部件。

import com.testapp.Role

import com.testapp.User

import com.testapp.UserRole

class BootStrap {

   def init = { servletContext ->

      def adminRole = new Role(authority:'ROLE_ADMIN').save(flush: true)

      def userRole = new Role(authority:'ROLE_USER').save(flush: true)

      def testUser = new User(username:'me', enabled: true, password: 'password')

      testUser.save(flush: true)

      UserRole.create testUser,adminRole, true

      assert User.count() == 1

      assert Role.count() == 2

      assert UserRole.count() == 1

   }

}

在上述的BootStrap.groovy中需要注意一些事情

·        本例中没有使用传统的GORMmany-to-many 映射User<->Role 关系; 插入了一个映射连接表UserRole类。 当多个用户有一个或多个共同的角色时,这样做对性能的优化比较明显。

·        我们显式刷新创建,因为 BootStrap 没有在事务和OpenSessionInView中运行。

8.编辑grails-app/controllers/SecureController.groovy 倒入注解类并应用注解限制访问。

package com.testapp

import grails.plugins.springsecurity.Secured

class SecureController {

   @Secured(['ROLE_ADMIN'])

   def index = {

      render 'Secure access only'

   }

}

或者

package com.testapp

import grails.plugins.springsecurity.Secured

@Secured(['ROLE_ADMIN'])

class SecureController {

   def index = {

      render 'Secure access only'

   }

}

你可以对控制器标注,也可以对其中的方法进行标注。在这里你只有一个方法,所以标注在哪里都可以。

9. 再次运行 grails run-app again 并导航到http://localhost:8080/bookstore/secure

这一次,你可能会提前看到登录页面,用测试用户的用户名和密码登录,你随后可能会重新看到secure页面。

10. 测试Remember Me 功能

选中Remember Me 复选框,进入你测试的secure页面,关闭浏览器再重新打开它。再次导航到secure 页面。因为有一个cookie 被保存,你可能不需要再次登录。在任何时候要退出请导航到http://localhost:8080/bookstore/logout

11.可选,为user和role创建一个创建CRUD UI 。

运行grailsgenerate-all 生成控制器和视图:

$ grails generate-all com.testapp.User

$ grails generate-all com.testapp.Role

用户类处理密码加密,对生成的控制器要求没有发生变化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章