Grails 基本认证
了解如何使用“基本”HTTP 认证计划保护 Grails 应用。
作者:Sergio del Amo
Grails 版本 3.3.5
1 开始使用
RFC7617定义了“基本”超文本传输协议 (HTTP) 认证计划,它使用 Base64 编码将凭证传输为 user_ID/密码对。
在本指南中,你将创建 Grails 应用并通过 HTTP Basic Auth 保护它。
1.1 你需要什么
要完成本指南,你需要以下内容
-
一些时间
-
一个好的文本编辑器或 IDE
-
安装了 JDK 1.7 或更高版本,并相应地配置了
JAVA_HOME
1.2 如何完成指南
要开始,请执行以下操作
-
下载并解压源
或
-
克隆Git 仓库
git clone https://github.com/grails-guides/grails-basicauth.git
Grails 指南仓库包含两个文件夹
-
initial
初始项目。通常是一个简单的 Grails 应用,其中有一些额外的代码可以让你先睹为快。 -
complete
一个完成的示例。它是根据指南介绍的步骤操作并在initial
文件夹中应用这些更改的过程。
要完成指南,请转到 initial
文件夹
-
cd
到grails-guides/grails-basicauth/initial
并按照下一节中的说明进行操作。
如果你cd 到 grails-guides/grails-basicauth/complete ,则可以直接转到已完成示例 |
如果你想从头开始,请使用Grails 应用程序 Forge创建一个新的 Grails 3 应用程序。
2 编写应用
使用 rest-api
配置文件创建应用
grails create-app example --profile=rest-api
2.1 添加安全依赖项
首先我们需要向 build.gradle
中添加 spring-security-core
Grails 插件。
compile 'org.grails.plugins:spring-security-core:3.2.1'
然后运行以下命令
grails s2-quickstart example.grails User Role
该命令将生成下列领域类
-
grails-app/domain/example.grails.User
-
grails-app/domain/example.grails.Role
-
grails-app/domain/example.grails.UserRole
密码编码器侦听器
src/main/groovy/example.grails.UserPasswordEncoderListener
以及
-
grails-app/conf/application.groovy
中默认的安全配置。修改生成的 application.groovy
以启用基本认证。
grails.plugin.springsecurity.useBasicAuth = true
2.2 控制器
创建 HomeController
,该控制器返回已验证用户的用户名。
package example.grails
import groovy.transform.CompileStatic
import grails.plugin.springsecurity.SpringSecurityService
import grails.plugin.springsecurity.annotation.Secured
import grails.plugin.springsecurity.userdetails.GrailsUser
@CompileStatic
@Secured('isAuthenticated()')
class HomeController {
static responseFormats = ['json']
SpringSecurityService springSecurityService
def index() {
[name: loggedUsername()]
}
String loggedUsername() {
if ( springSecurityService.principal == null ) {
return null
}
if ( springSecurityService.principal instanceof String ) {
return springSecurityService.principal
}
if ( springSecurityService.principal instanceof GrailsUser ) {
return ((GrailsUser) springSecurityService.principal).username
}
null
}
}
2.3 视图
借助 JSON 视图 将控制器输出呈现为 JSON 负载。
model {
String name
}
json {
username name
}
2.4 GORM 数据服务
通过添加使用 GORM 逻辑自动实现抽象类或接口的能力,GORM 数据服务可减轻实施服务层逻辑的工作量。
创建一个 GORM 数据服务以简化 User
领域类 CRUD 操作。
package example.grails
import grails.gorm.services.Service
@Service(User)
interface UserDataService {
User save(String username, String password, boolean enabled, boolean accountExpired, boolean accountLocked, boolean passwordExpired)
void delete(Serializable id)
int count()
}
2.5 测试
创建一个通过基本认证验证用户身份验证流程的测试。
package example.grails
import grails.plugins.rest.client.RestBuilder
import grails.plugins.rest.client.RestResponse
import grails.testing.mixin.integration.Integration
import spock.lang.Specification
@Integration
class HomeControllerSpec extends Specification {
UserDataService userDataService
def "verify basic auth is possible"() {
given:
RestBuilder rest = new RestBuilder()
final String username = 'sherlock'
final String password = 'elementary'
when:
User user = userDataService.save(username, password, true, false, false, false, )
then:
userDataService.count() == old(userDataService.count()) + 1
when:
String token = "${username}:${password}".encodeAsBase64()
RestResponse rsp = rest.get("http://localhost:${serverPort}/home") {
auth("Basic $token")
}
then:
rsp.status == 200
and:
rsp.json.username == username
cleanup:
userDataService?.delete(user?.id)
}
}
2.6 后续步骤
阅读 Grails Springs 安全核心插件文档的 Basic and Digest Authentication 部分,以了解基本认证的各种配置选项。