没有 client_secret 的 Spring Security OAuth 2.0 [英] Spring Security OAuth 2.0 with no client_secret

查看:81
本文介绍了没有 client_secret 的 Spring Security OAuth 2.0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Spring Boot 和 Spring Security OAuth 2.0 为我的 Android 应用程序开发登录系统.

I am developing a login system for my Android application using Spring Boot and Spring Security OAuth 2.0.

我的出发点是以下演示存储库:https://github.com/royclarkson/spring-rest-service-oauth.在演示中,您可以找到以下设置:

My starting point is the following demo repository: https://github.com/royclarkson/spring-rest-service-oauth. In the demo you can find the following setup:

OAuth2 客户端:

OAuth2 client:

clients
    .inMemory()
        .withClient("clientapp")
            .authorizedGrantTypes("password", "refresh_token")
            .authorities("USER")
            .scopes("read", "write")
            .resourceIds(RESOURCE_ID)
            .secret("123456");

在测试中获取访问令牌的方法:

Method to fetch the access token in its tests:

private String getAccessToken(String username, String password) throws Exception {
    String authorization = "Basic " + new String(Base64Utils.encode("clientapp:123456".getBytes()));

    String content = mvc
        .perform(
                post("/oauth/token")
                        .header("Authorization", authorization)
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("username", username)
                        .param("password", password)
                        .param("grant_type", "password")
                        .param("scope", "read write")
                        .param("client_id", "clientapp")
                        .param("client_secret", "123456"))
        .andExpect(status().isOk())
        .andReturn().getResponse().getContentAsString();

    return content.substring(17, 53);
}

项目中的每个测试都提供了完美的工作,但我想以不同的方式做事,但我在这样做时遇到了麻烦.正如您所看到的,演示客户端定义了一个 client_secret(也在测试中使用)但是 client_secret 在 Android 环境中确实毫无价值,我不能保证它的隐私".

Every test in the project provides works perfectly but I want do things differently and I am having trouble doing so. As you can see the demo client defines a client_secret (which is also used in the tests) but a client_secret is really worthless in an Android environment, I can not guarantee its 'privateness'.

参见 https://apigility.org/documentation/auth/authentication-oauth2:

如果我们使用的是公共客户端(默认情况下,当没有与客户端关联的秘密时,这是真的),您可以省略 client_secret 值;

If we are using a public client (by default, this is true when no secret is associated with the client) you can omit the client_secret value;

并查看 http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-2.1:

公开:客户无法维护其机密性凭据(例如,在用户使用的设备上执行的客户端)资源所有者,例如已安装的本机应用程序或 Web基于浏览器的应用程序),并且无法安全客户端通过任何其他方式进行身份验证.

Public: Clients incapable of maintaining the confidentiality of their credentials (e.g. clients executing on the device used by the resource owner such as an installed native application or a web browser-based application), and incapable of secure client authentication via any other means.

所以我所做的是删除客户端配置中的秘密:

So what I have done is removing the secret in the client configuration:

clients
    .inMemory()
        .withClient("books_password_client")
        .authorizedGrantTypes("password", "refresh_token")
        .authorities("USER")
        .scopes("read", "write")
        .resourceIds(RESOURCE_ID);

还修改了 getAccessToken(...) 方法:

private String getAccessToken(String username, String password) throws Exception {
    String authorization = "Basic " + new String(Base64Utils.encode("books_password_client:123456".getBytes()));

    String content = mvc
        .perform(
                post("/oauth/token")
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                        .param("username", username)
                        .param("password", password)
                        .param("grant_type", "password")
                        .param("client_id", "books_password_client"))
        .andExpect(status().isOk())
        .andReturn().getResponse().getContentAsString();

    return content.substring(17, 53);}
}

但是当我使用这个新设置时,我的测试失败了,我无法获得访问令牌,我不断收到 HTTP 错误 401 Unauthorized.

But when I use this new setup my tests fail, I can't get an access token, I keep getting an HTTP error 401 Unauthorized.

推荐答案

这就是我的工作:

Response response =
    given().
        auth()
            .preemptive().basic("clientapp", "")
            .formParam("username", username)
            .formParam("password", password)
            .formParam("grant_type", "password")
            .formParam("scope", "read%20write")
    when()
        .post("/oauth/token").
    then()
        .extract().response();

这篇关于没有 client_secret 的 Spring Security OAuth 2.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆