显示导航

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 如何完成指南

要开始,请执行以下操作

Grails 指南仓库包含两个文件夹

  • initial 初始项目。通常是一个简单的 Grails 应用,其中有一些额外的代码可以让你先睹为快。

  • complete 一个完成的示例。它是根据指南介绍的步骤操作并在 initial 文件夹中应用这些更改的过程。

要完成指南,请转到 initial 文件夹

  • cdgrails-guides/grails-basicauth/initial

并按照下一节中的说明进行操作。

如果你cdgrails-guides/grails-basicauth/complete,则可以直接转到已完成示例

如果你想从头开始,请使用Grails 应用程序 Forge创建一个新的 Grails 3 应用程序。

forgeDefault

2 编写应用

使用 rest-api 配置文件创建应用

grails create-app example --profile=rest-api

2.1 添加安全依赖项

首先我们需要向 build.gradle 中添加 spring-security-core Grails 插件。

build.gradle
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-app/conf/application.groovy
grails.plugin.springsecurity.useBasicAuth = true

2.2 控制器

创建 HomeController,该控制器返回已验证用户的用户名。

grails-app/controllers/example/grails/HomeController.groovy
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 负载。

grails-app/views/home/index.gson
model {
    String name
}

json {
    username name
}

2.4 GORM 数据服务

通过添加使用 GORM 逻辑自动实现抽象类或接口的能力,GORM 数据服务可减轻实施服务层逻辑的工作量。

创建一个 GORM 数据服务以简化 User 领域类 CRUD 操作。

grails-app/services/example/grails/UserDataService.groovy
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 测试

创建一个通过基本认证验证用户身份验证流程的测试。

src/integration-test/groovy/example/grails/HomeControllerSpec.groovy
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 部分,以了解基本认证的各种配置选项。

3 您是否需要有关 Grails 的帮助?

Object Computing, Inc. (OCI) 赞助了本指南的创建。有多种咨询和支持服务。OCI 是 Grails 的所在地。

OCI 是 Grails 的所在地

认识团队成员