2016-05-30 26 views
13

Sto cercando di proteggere i miei microservizi su Spring Boot utilizzando Oath2 con flusso di credenziali client.Avvio a molla + credenziali client Oauth2

A proposito, questi microservizi si parleranno solo a metà del livello middleware, quindi non sono necessarie credenziali utente per consentire l'autorizzazione (processo di accesso utente come Facebook).

Ho cercato campioni su Internet che mostra come creare un server di autorizzazione e risorse per gestire questa comunicazione. Tuttavia ho appena trovato esempi che spiegano come farlo usando le credenziali dell'utente (tre gambe).

Qualcuno ha qualche esempio su come farlo in Spring Boot e Oauth2? Se è possibile fornire ulteriori dettagli sugli ambiti utilizzati, lo scambio di token sarebbe grato.

risposta

14

Abbiamo i servizi REST protetti con lo schema di credenziali Oauth2 Client. Il servizio Risorsa e autorizzazione sono in esecuzione nella stessa app, ma possono essere suddivisi in diverse app.

@Configuration 
public class SecurityConfig { 

@Configuration 
@EnableResourceServer 
protected static class ResourceServer extends ResourceServerConfigurerAdapter { 

    // Identifies this resource server. Usefull if the AuthorisationServer authorises multiple Resource servers 
    private static final String RESOURCE_ID = "*****"; 

    @Resource(name = "OAuth") 
    @Autowired 
    DataSource dataSource; 

    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     // @formatter:off 
     http  
       .authorizeRequests().anyRequest().authenticated(); 
     // @formatter:on 
    } 

    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 
     resources.resourceId(RESOURCE_ID); 
     resources.tokenStore(tokenStore()); 
    } 

    @Bean 
    public TokenStore tokenStore() { 
     return new JdbcTokenStore(dataSource); 
    } 
} 

@Configuration 
@EnableAuthorizationServer 
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { 

    @Resource(name = "OAuth") 
    @Autowired 
    DataSource dataSource; 

    @Bean 
    public TokenStore tokenStore() { 
     return new JdbcTokenStore(dataSource); 
    } 

    @Override 
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
     endpoints.tokenStore(tokenStore()); 
    } 

    @Override 
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.jdbc(dataSource); 
    } 
} 
} 

origine dati di configurazione per le tabelle OAuth2:

@Bean(name = "OAuth") 
@ConfigurationProperties(prefix="datasource.oauth") 
public DataSource secondaryDataSource() { 
    return DataSourceBuilder.create().build(); 
} 

Comunicazione con server di autenticazione & risorsa va come segue

curl -H "Accept: application/json" user:[email protected]:8080/oauth/token -d grant_type=client_credentials 
curl -H "Authorization: Bearer token" localhost:8080/... 

Il seguente record è presente nel database OAuth2:

client_id resource_ids client_secret scope authorized_grant_types web_server_redirect_uri authorities access_token_validity refresh_token_validity additional_information autoapprove 
user **** password NULL client_credentials NULL X NULL NULL NULL NULL 

configurazione Resttemplate in un'applicazione client

@Configuration 
@EnableOAuth2Client 
public class OAuthConfig { 

@Value("${OAuth2ClientId}") 
private String oAuth2ClientId; 

@Value("${OAuth2ClientSecret}") 
private String oAuth2ClientSecret; 

@Value("${Oauth2AccesTokenUri}") 
private String accessTokenUri; 

@Bean 
public RestTemplate oAuthRestTemplate() { 
    ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails(); 
    resourceDetails.setId("1"); 
    resourceDetails.setClientId(oAuth2ClientId); 
    resourceDetails.setClientSecret(oAuth2ClientSecret); 
    resourceDetails.setAccessTokenUri(accessTokenUri); 

    /* 

    When using @EnableOAuth2Client spring creates a OAuth2ClientContext for us: 

    "The OAuth2ClientContext is placed (for you) in session scope to keep the state for different users separate. 
    Without that you would have to manage the equivalent data structure yourself on the server, 
    mapping incoming requests to users, and associating each user with a separate instance of the OAuth2ClientContext." 
    (http://projects.spring.io/spring-security-oauth/docs/oauth2.html#client-configuration) 

    Internally the SessionScope works with a threadlocal to store variables, hence a new thread cannot access those. 
    Therefore we can not use @Async 

    Solution: create a new OAuth2ClientContext that has no scope. 
    *Note: this is only safe when using client_credentials as OAuth grant type! 

    */ 

//  OAuth2RestTemplate restTemplate = new  OAuth2RestTemplate(resourceDetails, oauth2ClientContext); 
    OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(resourceDetails, new DefaultOAuth2ClientContext()); 

    return restTemplate; 
} 
} 

È possibile iniettare il restTemplate a parlare (in modo asincrono) per il servizio garantito OAuth2. Al momento non utilizziamo l'ambito.

+1

Davvero un bel codice, ci proverò. –

+0

Esiste un altro modo invece di estrarre i dati usando @value e impostando oauthRestTemplate? – Jesse

+0

@CarlosAlberto Ciao, hai tutto il progetto per questo. Ho anche bisogno dello stesso. – noobdeveloper

Problemi correlati