当前位置: 首页 > 知识库问答 >
问题:

没有client_secret的Spring Security OAuth 2.0

马峻
2023-03-14

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

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

OAuth2客户端:

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

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

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环境中真的毫无价值,我不能保证它的“私密性”。

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

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

见https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-31#section-2.1:

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

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

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错误。

共有1个答案

翟光赫
2023-03-14

这就是我的工作:

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”元素在2.3.1节定义: client-secret = *VSCHAR

  • 我们正在使用OAuth2。0表示安全性。我在网上浏览了很多资源,每个人都在使用客户id、客户机密以及用户名和密码。但是我只想要client_id和client_secret,并且获得不带用户名和密码的访问令牌。 任何帮助将高度赞赏。

  • 在GlassFish Server开源版本3.1中部署。1(构建12): 引起原因:java.security.PrivilegedActionExcema:com.sun.xml.bind.v2.runtime.IllegalAnnotationsExceptions: 1个IllegalAnnotationExceptions的计数没有ObjectFactory与@XmlElementDecl

  • 问题内容: 在进行了整个“企业”编程一段时间之后,我对语言本身感到非常失望,如果不得不回到它上面,总是会感到很受阻。您平均的Android应用程序的项目规模并不太令人生畏,并且库的编码风格实际上非常不错,但是如果我可以避免使用Java,我肯定会这样做。 这就是问题:我可以避免吗?尽管有很多JVM语言可以在台式机和服务器上选择,但是Dalvik VM和设备本身存在一些限制。使用JIT在2.2中似乎更

  • 问题内容: 由于用户可以在浏览器中禁用JavaScript,所以我想知道是否有任何开发使用Ajax但不使用Javascript的应用程序的方法,因此即使禁用了Javascript仍可以正常工作。有什么限制吗? 问题答案: 没有Javascript,AJAX是不可能的,因为它以客户端上运行的JS代码为前提。如果禁用了JS,则浏览器中无法执行任何操作并无法与服务器联系- 只有“死”的HTML和CSS。

  • 问题内容: 有什么方法可以在不创建容器的情况下使用LXC通过进程组进行资源管理?我正在研究一种在沙箱中运行任意代码的服务,对此我只对硬件资源管理感兴趣。我不要生根发芽;我只希望这些进程组可以访问主文件系统。 有人告诉我lxc重量轻,但是我看到的所有示例都为每个lxc进程创建了一个新容器(即具有完整OS的目录)。我真的没有看到它比其他任何VM解决方案轻得多。 那么,有什么方法可以将LXC用于控制和管