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

用戶類處理密碼加密,對生成的控制器要求沒有發生變化。

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