5

Sto lavorando a un piccolo proof of concept per un set di endpoint che devono essere in grado di chiamarsi reciprocamente passando token che sono ottenuti tramite un flusso di credenziali client OAuth 2 . Sto usando primavera Boot e progetti correlati a costruire questi endpoint, e io sono confusa sul motivo per cui il quadro sembra essere molto supponente circa il seguente codice:C'è un modo più semplice per caricare la configurazione del client OAuth di Spring

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; 
    } 
} 

E il file di configurazione di accompagnamento:

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 

Quanto sopra funziona esattamente come previsto. Se cambio security.oauth2.client.id a security.oauth2.client.client-id (sia nel codice Java e il YAML), ottengo un errore 500, la prima linea di che è:

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. 

Il codice funziona anche bene se I valori di codice duri per tutti le variabili di istanza. Sembra funzionare bene, infatti, in ogni permutazione di popolare quelle variabili di istanza, tranne quella in cui io uso @Value per popolare clientId con il valore di security.oauth2.client.client-id

Quindi la mia domanda principale è: è il quadro in realtà supponente in questa modo specifico? E se sì, perché? E posso sfruttare questa opinione per semplificare il mio codice?

risposta

0

Non sono sicuro di quale versione di avvio a molla si sta utilizzando. Sto usando la primavera-boot versione 1.5.4.RELEASED e di facilità codici,

è possibile iniettare OAuth2ProtectedResourceDetails come

@Autowired 
private OAuth2ProtectedResourceDetails resource; 

e creare OAuth2RestTemplate come

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

yaml campione ..

### 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----- 

E quindi, utilizzare l'istanza restTemplate in controller come

@Autowired 
private OAuth2RestOperations restTemplate; 

Spero che un po 'di aiuto per voi.

Problemi correlati