安全是每個實際的應用所必需面對的問題。但是,安全是個技術活,沒有相當的功底是搞不定的。況且,DRY(don't repeat yourself)一直是我們的信條。所以,Spring Security 成了一個非常不錯的選項。
Grails 約定優先的策略能夠帶來很大的便利,於是,兩者的結合就是順理成章的事情。
網上相關的帖子很多,經測試,總結下來是這樣幾個步驟。創建Grailsig程序不多贅述。以下的步驟是在程序創建完成後。
- 引入相應的插件。編輯build.gradle文件,dependencies中引入下列插件。
compile 'org.grails.plugins:spring-security-core:3.2.3'
compile 'org.grails.plugins:spring-security-ui:4.0.0.M1' // 針對Grails 3.3
compile 'org.grails.plugins:spring-security-rest:2.0.0.RC1'
- spring-security-core是核心插件,注意與Grails版本的匹配。如果Grails是3.3X就採用3.1以上的core。具體的匹配關係可以參考spring-security-core的說明。
- spring-security-ui是界面相關的插件,可以提供幾個可用的查詢,配置界面。也存在版本匹配的問題。
- 如果是些普通的web程序,只引入核心插件就夠了。
- spring-security-rest插件是爲了相應rest方式訪問而設計的。引入這個插件就可以相應後端ajax或者axios發來的請求。不過,也存在版本匹配的問題。對於Grails 3.X,要用2.X的rest插件。
- 更需要注意的是,2.0.0.M2,2.0.0.RC1也有關鍵的變化:
- M2之前,用戶的令牌採用JWT方式,有缺省的祕鑰。RC1中沒有了,所以,版本用錯了,無法啓動。會出錯:java.lang.IllegalArgumentException: The specified token domain class 'null' is not a domain class
- 解決方案有兩種:
- 或者引入相應的其他插件,用於存儲用戶令牌。比如spring-security-rest-gorm,將令牌存儲到數據庫中。
- 或者,自己給祕鑰賦值(後面具體列出)。
- 執行插件的腳本文件,生成關鍵代碼。最簡單的命令就是“s2-quickstart cn.edu.cup.system User Role”。生成用戶、角色兩個關鍵的域類。同時生成application.groovy,放在conf目錄下。
-
// Added by the Spring Security Core plugin: grails.plugin.springsecurity.userLookup.userDomainClassName = 'cn.edu.cup.system.User' grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'cn.edu.cup.system.UserRole' grails.plugin.springsecurity.authority.className = 'cn.edu.cup.system.Role' grails.plugin.springsecurity.controllerAnnotations.staticRules = [ [pattern: '/', access: ['permitAll']], [pattern: '/error', access: ['permitAll']], [pattern: '/index', access: ['permitAll']], [pattern: '/index.gsp', access: ['permitAll']], [pattern: '/shutdown', access: ['permitAll']], [pattern: '/assets/**', access: ['permitAll']], [pattern: '/**/js/**', access: ['permitAll']], [pattern: '/**/css/**', access: ['permitAll']], [pattern: '/**/images/**', access: ['permitAll']], [pattern: '/**/favicon.ico', access: ['permitAll']] ] grails.plugin.springsecurity.filterChain.chainMap = [ [pattern: '/assets/**', filters: 'none'], [pattern: '/**/js/**', filters: 'none'], [pattern: '/**/css/**', filters: 'none'], [pattern: '/**/images/**', filters: 'none'], [pattern: '/**/favicon.ico', filters: 'none'], [pattern: '/**', filters: 'JOINED_FILTERS'] ]
自動生成的代碼包括三個部分。第一部分是配置用戶名域類的名字,角色域類的名字,以及用戶授權域類的名字。
-
- 根據自己的需要,對安全插件進行必要的配置。如果rest採用M2版本,現在就可以用了。
- 如果採用RC1版本,就需要在application.groovy中增加一句,給JWT祕鑰賦值。注意,如果不加這一句,系統會給出一個提示,結果提示中所列出來的對象的包名是錯的,多了一個conf。具體的賦值語句如下:
grails.plugin.springsecurity.rest.token.storage.jwt.secret = '01234567890123456789012345678901'
祕鑰的長度是有要求的,至少32個字符。
經過上述步驟,安全組件就基本正常可用了。接下來,就需要按照自己的選擇,設置用戶功能的安全性即可。