使用Grails实现OAuth2提供程序

时间:2015-03-05 17:04:05

标签: grails oauth spring-security

我正在尝试使用Spring Security OAuth2 Provider插件实现提供OAuth2的Grails应用。我用它来测试它的The provider appclient app都可以在GitHub上找到。

我遵循instructions in the plugin's docs,解释了如何实现提供程序。为了测试它,我在Bootstrap.groovy

中保存了以下oauth客户端和用户
def init = { servletContext ->

    def saveArgs = [flush: true, failOnError: true]

    def userRole = new Role(authority: 'ROLE_USER').save(saveArgs)
    def clientRole = new Role(authority: 'ROLE_CLIENT').save(saveArgs)

    // create an OAuth client
    new Client(
            clientId: 'my-client',
            authorizedGrantTypes: ['authorization_code', 'refresh_token', 'implicit', 'password', 'client_credentials'],
            authorities: ['ROLE_CLIENT'],
            scopes: ['read', 'write'],
            redirectUris: ['http://localhost:9090/oauth-client/auth/callback']
    ).save(saveArgs)

    // create a regular user
    def user = new User(username: 'me', password: 'password').save(saveArgs)
    UserRole.create user, userRole, true
}

在客户端应用程序中,我单击以下链接以启动授权代码授予流程

<g:set var="redirectUrl" value="${g.createLink(controller: 'auth', action: 'callback', absolute: true)}"/>
<h2>
    <a href="http://localhost:8080/oauth2-provider/oauth/authorize?response_type=code&client_id=my-client&scope=read&redirect_uri=${redirectUrl}">OAuth Login</a>
</h2>

我在登录表单中输入上述用户的用户名和密码,然后单击确认对话框中显示的“授权”按钮。授权代码成功返回到客户端应用程序,但是当它尝试将此交换为访问令牌时,会发生以下错误

  

invalid_scope:空范围(客户端或用户不允许请求的范围)

用于交换访问令牌的授权码的代码如下所示。

String getAccessToken(String authCode) {

    def url = 'http://localhost:8080/oauth2-provider/oauth/token'

    def params = [
            grant_type: 'authorization_code',
            code: authCode,
            client_id: 'my-client'
    ]

    new HTTPBuilder(url).request(POST, JSON) {
        uri.query = params

        response.success = { resp, json ->
            json.access_token
        }

        response.failure = { resp, json ->
            log.error "HTTP error code: $resp.status, status line: $resp.statusLine, "

            json.each { key, value ->
                log.error "$key: $value"
            }
        }
    }
}

启动OAuth流程的链接请求访问read范围。 包含在scopes对象的Client属性中,因此没有明显的理由说明为什么禁止访问此范围。

您可以按照以下说明重现错误:

  • 使用grails run-app
  • 启动提供商应用
  • 使用grails run-app -Dserver.port=9090
  • 在端口9090上启动客户端应用
  • 在客户端应用的主页上,点击“OAuth登录”链接。这会重定向到提供程序应用程序并提示您登录。输入用户名“me”,密码“password”,然后单击下面确认对话框中的“授权”按钮。

1 个答案:

答案 0 :(得分:1)

对于未来偶然遇到这种情况的任何人:

这是插件中的一个小错误的结果。临时解决方法是在令牌端点请求中包含scope参数,其值与发送到授权端点的scope参数相同。

有关此问题的详细信息,请参阅插件的GitHub存储库中的issue #64