Spring security 有没有更简单的方法来加载SpringOAuth客户端配置

Spring security 有没有更简单的方法来加载SpringOAuth客户端配置,spring-security,spring-boot,spring-security-oauth2,spring-oauth2,Spring Security,Spring Boot,Spring Security Oauth2,Spring Oauth2,我正在研究一组端点的概念证明,这些端点需要能够通过通过OAuth 2客户端凭据流获得的令牌相互调用。我正在使用Spring Boot和相关项目来构建这些端点,我不明白为什么框架似乎对以下代码非常固执己见: package com.example.client; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Val

我正在研究一组端点的概念证明,这些端点需要能够通过通过OAuth 2客户端凭据流获得的令牌相互调用。我正在使用Spring Boot和相关项目来构建这些端点,我不明白为什么框架似乎对以下代码非常固执己见:

package com.example.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.OAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@Configuration
@EnableAutoConfiguration
@EnableOAuth2Client
@RestController
public class StuffClient {

    @Value("${security.oauth2.client.access-token-uri}")
    private String tokenUrl;

    @Value("${security.oauth2.client.id}")
    private String clientId;

    @Value("${security.oauth2.client.client-secret}")
    private String clientSecret;

    @Value("${security.oauth2.client.grant-type}")
    private String grantType;

    @Autowired
    private OAuth2RestOperations restTemplate;

    private String uri = "http://localhost:8082/stuff/";

    @RequestMapping(value = "/client/{stuffName}", method = RequestMethod.GET)
    public String client(@PathVariable("stuffName") String stuffName) {
        String request = uri + stuffName;
        return restTemplate.getForObject(request, String.class);
    }

    @Bean
    public OAuth2RestOperations restTemplate(OAuth2ClientContext clientContext) {
        return new OAuth2RestTemplate(resource(), clientContext);
    }

    @Bean
    protected OAuth2ProtectedResourceDetails resource() {
        ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
        resource.setAccessTokenUri(tokenUrl);
        resource.setClientId(clientId);
        resource.setClientSecret(clientSecret);
        resource.setGrantType(grantType);
        return resource;
    }
}
以及附带的配置文件:

server:
  port: 8081

security:
  basic:
    enabled: false
  oauth2:
    client:
      id: test-client
      client-secret: test-secret
      access-token-uri: http://localhost:8080/uaa/oauth/token
      grant-type: client_credentials
上述工作完全符合预期。如果我将
security.oauth2.client.id
更改为
security.oauth2.client.client id
(在Java代码和YAML中),我会得到一个500错误,第一行是:

org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException: Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it. 
如果我为所有实例变量硬编码值,代码也可以正常工作。事实上,它似乎在填充这些实例变量的每一种排列中都很好,除了我使用
@Value
security.oauth2.client.client id
的值填充
clientId
之外


所以我的主要问题是:框架是否真的以这种非常具体的方式固执己见?如果是,为什么?而且,我可以利用这种自以为是的态度来简化我的代码吗?

我不确定您使用的是哪个spring boot版本。我使用的是spring boot版本
1.5.4。已发布
,为了简化您的代码

你可以像这样注射

并创建为

样品yaml

### OAuth2 settings ### 
security:
  user:
    password: none
  oauth2:
    client:
      accessTokenUri: ${auth-server}/oauth/token
      userAuthorizationUri: ${auth-server}/oauth/authorize
      clientId: myclient
      clientSecret: secret
    resource:
      user-info-uri: ${auth-server}/sso/user
      jwt:
        keyValue: |
          -----BEGIN PUBLIC KEY-----
          your public key
          -----END PUBLIC KEY-----
然后,在控制器中使用
restemplate
实例作为

@Autowired
private OAuth2RestOperations restTemplate;

我希望能对您有所帮助。

我面临的问题与您解决的问题相同
### OAuth2 settings ### 
security:
  user:
    password: none
  oauth2:
    client:
      accessTokenUri: ${auth-server}/oauth/token
      userAuthorizationUri: ${auth-server}/oauth/authorize
      clientId: myclient
      clientSecret: secret
    resource:
      user-info-uri: ${auth-server}/sso/user
      jwt:
        keyValue: |
          -----BEGIN PUBLIC KEY-----
          your public key
          -----END PUBLIC KEY-----
@Autowired
private OAuth2RestOperations restTemplate;