在grails集成测试中创建的安全用户是未经授权的,但是自举的用户是

时间:2017-07-28 21:32:30

标签: spring grails spring-security grails-rest-api

我正在使用Grails Spring Security CoreGrails Spring Security REST plugin,我刚刚开始设置。我使用User类和Authority类(默认值)初始化了插件,然后按照guide I found on the Grails website编写了集成测试。

它说要将以下内容放入集成测试中:

def "test a user with the role ROLE_BOSS is able to access /api/announcements url"() {
    when: 'login with the sherlock'
    RestBuilder rest = new RestBuilder()
    def resp = rest.post("http://localhost:${serverPort}/api/login") { 
        accept('application/json')
        contentType('application/json')
        json {
            username = 'sherlock'
            password = 'elementary'
        }
    }

    then:
    resp.status == 200
    resp.json.roles.find { it == 'ROLE_BOSS' }
}

我继续做了类似的事情并且使用了引导程序User,但是当我尝试使用在测试方法本身中创建的User进行完全相同的测试时,它会失败并且一个401 HTTP响应代码。

我正在尝试运行的代码:

void "check get access token"() {
    given:
    RestBuilder rest = new RestBuilder()
    new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
    assert User.count == 2

    when:
    def resp = rest.post("http://localhost:${serverPort}/api/login") {
        accept('application/json')
        contentType('application/json')
        json {
            username = "securitySpecTestUserName"
            password = "securitySpecTestPassword"
        }
    }

    then:
    resp.status == 200
}

请注意,User.count == 2断言通过,因为User中有一个Bootstrap.groovy,而且在测试方法中创建了一个User

为什么这样做并且通过引导的/api/login而没有任何问题,而不是在方法中创建的问题?有没有办法可以编写此集成测试,以便以这种方式测试grails-spring-security-rest插件中包含的<Page x:Class="ClockCpp.MainPage" Loaded="Page_Loaded" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ClockCpp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="black" SizeChanged="Page_SizeChanged"> 端点?

1 个答案:

答案 0 :(得分:0)

您在给定部分中创建的用户位于尚未提交的事务中。当你进行REST调用时,api / login控制器将在一个无法看到未提交用户的新事务中运行。

一些选项(还有其他选项)......

  1. 在BootStrap.groovy中创建用户

    def init = { servletContext ->
      environments {
        test {
          new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
        }
      }
    }
    
  2. 进行REST调用以创建用户 - 假设您具有此类功能

  3. 在设置中创建用户

    @Integration
    @Rollback
    class UserIntSpec extends Specification {
    
      def setup() {
        new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
      }
    
      void "check get access token"() {
        given:
        RestBuilder rest = new RestBuilder()
    
        when:
        def response = rest.post("http://localhost:${serverPort}/api/login") {
          accept('application/json')
          contentType('application/json')
          json {
            username = "securitySpecTestUserName"
            password = "securitySpecTestPassword"
          }
        }
    
       then:
       response.status == HttpServletResponse.SC_OK
    
       when:
       def token = response.json.access_token
    
       then:
       token
      }
    }
    
  4. 注意:在Grails&gt; = 3.0中,setup()在一个单独的事务中运行并保持不变(为什么它解决了您的问题),这些事务未回滚。任何数据都需要手动清理。

    我建议您阅读有关测试的grails文档:Integration Testing