如何在 Spring Security OAuth2 中生成没有 client_secret 的令牌 [重复]

Posted

技术标签:

【中文标题】如何在 Spring Security OAuth2 中生成没有 client_secret 的令牌 [重复]【英文标题】:How to generate token without client_secret in Spring Security OAuth2 [duplicate] 【发布时间】:2017-01-05 07:43:27 【问题描述】:

我有一个基于 Spring Security OAuth 2.0 的应用程序,配置了 JDBC 和 LDAP。根据 OAuth 2.0 规范,客户端密码必须。

当我使用以下 URL 生成令牌时,它会生成令牌并且工作正常:

/oauth/token?grant_type=password&client_secret=test&client_id=test&username=test&password=test

当我尝试在没有client_secret 的情况下生成令牌时,它给出:

401:未经授权

error_description:“错误的用户凭据”

但我想生成没有client_secret 的令牌,例如:

/oauth/token?grant_type=password&username=test&password=test

securityConfig.java

 @Configuration
 @EnableWebSecurity
 @EnableGlobalMethodSecurity( prePostEnabled = true )
 public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter                               

    private static final int EMBEDDED_LDAP_SERVER_PORT = 33388;

    @Autowired
    private UserAuthenticationProvider userAuthenticationProvider;    

    @Autowired
    private LdapAuthenticationProvider ldapAuthenticationProvider;

    @Autowired
    private AuthTokenStore oAuthTokenStore;     

    @Autowired
    private AuthDelegatingAuthenticationEntryPoint  delegatingAuthenticationEntryPoint;

    @Override
    @Qualifier("authenticationManagerBean")
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception 
        return new ProviderManager(Arrays.asList((AuthenticationProvider) ldapAuthenticationProvider,userAuthenticationProvider));
    
    @Override
    protected void configure(HttpSecurity http) throws Exception       
         http
             .csrf().disable()
             .sessionManagement()
                  .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .and()
             .authorizeRequests()
                  .anyRequest().authenticated()
                  .and()
             .exceptionHandling().authenticationEntryPoint(delegatingAuthenticationEntryPoint);
    

    @Bean
    public ResourceServerTokenServices tokenService() 

        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setTokenStore(oAuthTokenStore);
        tokenServices.setReuseRefreshToken(true);
        return tokenServices;
    

【问题讨论】:

如果授权类型是密码,你可以只传递 client_id 不需要客户端密码..like /oauth/token?grant_type=password&username=test&password=test&client_id=CLIENT_ID 我该如何处理这个网址? /oauth/token?grant_type=password&username=test&password=test‌​&client_id=CLIENT_ID @PrasannaKumar 在安全配置中提及客户端 ID 并传递该客户端 ID...它将返回令牌 我应该在哪里通过 securityConfig 中的 client_id 并且我正在使用 ClientCredentialsTokenEndpointFilter 但它不起作用@PrasannaKumar 见***.com/a/57081799/3090180 【参考方案1】:

不幸的是,没有简单的方法可以解决您的问题。 Spring Security 对标准的解释非常严格:

这是来自 OAuth2 规范的引用,RFC 6749, section 4.3.2 (Resource Owner Password Credentials Grant - Access Token Request):

如果客户类型是保密的或者客户是发给客户的 凭据(或分配的其他身份验证要求), 客户端必须按照所述向授权服务器进行身份验证 在第 3.2.1 节中。

对于 Spring Security,密码授予始终属于此类别。第 3.2.1 节需要客户端 ID 和客户端密码。

Spring 安全文档也是这样写的: 28.1.1 Authorization Server

除非你想改变 spring security 的 OAuth2 的认证逻辑(不推荐)你被卡住了。

在我看来没有问题。客户端 ID 和密码不会花费您任何费用,并为您的应用程序带来更多的安全性。

【讨论】:

我不明白。如果我使用 Web 客户端与我的 API 交谈 - 我应该在某处硬编码 client_idclient_secret 还是只是将其发送给客户端?我不明白这有什么意义。 ^^ 我对此投了反对票,因为我相信拥有一个不使用资源所有者/密码授权来保护自己的客户机密的非机密(公共)客户端是合法的,这是真正的答案.如果我被证明是错误的,很高兴再次投票,但以目前的形式,我认为这个答案具有误导性,同时通过引用规范听起来很权威。

以上是关于如何在 Spring Security OAuth2 中生成没有 client_secret 的令牌 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 spring-security-oauth 中获取经过身份验证的用户

您如何在代理后面使用 spring-security OAuth2,但仅将 ForwardedHeaderTransformer 用于 OAuth 组件

如何使用spring-security,oauth2调整实体的正确登录?

Spring Security OAuth 2:如何在 oauth/token 请求后获取访问令牌和附加数据

如何使用 redis 使用 spring-security-oauth2 持久化令牌

如何使用 XML 使用 Spring Security Oauth2 启用 /oauth/check_token