Un'introduzione a Spring Cloud Security

1. Panoramica

Il modulo Spring Cloud Security fornisce funzionalità relative alla sicurezza basata su token nelle applicazioni Spring Boot.

In particolare, semplifica l'SSO basato su OAuth2, con il supporto per l'inoltro dei token tra i server risorse, nonché la configurazione dell'autenticazione a valle utilizzando un proxy Zuul incorporato.

In questo rapido articolo, daremo uno sguardo a come possiamo configurare queste funzionalità utilizzando un'applicazione client Spring Boot, un server di autorizzazione e un'API REST che funziona come server di risorse.

Si noti che per questo esempio, abbiamo solo un'applicazione client che utilizza SSO per dimostrare le funzionalità di sicurezza cloud, ma in uno scenario tipico avremmo almeno due applicazioni client per giustificare la necessità di Single Sign-On.

2. Avvio rapido di un'app di sicurezza cloud

Cominciamo configurando SSO in un'applicazione Spring Boot.

Innanzitutto, dobbiamo aggiungere la dipendenza spring-cloud-starter-oauth2 :

 org.springframework.cloud spring-cloud-starter-oauth2 2.2.2.RELEASE 

Ciò porterà anche alla dipendenza dalla sicurezza primaverile del cloud .

Possiamo configurare qualsiasi sito social come server di autenticazione per il nostro sito oppure possiamo utilizzare il nostro server. Nel nostro caso, abbiamo scelto la seconda opzione e configurato un'applicazione che funge da server di autorizzazione, che viene distribuito localmente su // localhost: 7070 / authserver.

Il nostro server di autorizzazione utilizza token JWT.

Inoltre, affinché qualsiasi client sia in grado di recuperare le credenziali di un utente, dobbiamo configurare il nostro Resource Server, in esecuzione sulla porta 9000, con un endpoint che possa servire queste credenziali.

Qui, abbiamo configurato un endpoint / user disponibile in // localhost: 9000 / user.

Per maggiori dettagli su come impostare un server di autorizzazione e un server risorse, consulta il nostro articolo precedente qui.

Ora possiamo aggiungere l'annotazione in una classe di configurazione nella nostra applicazione client:

@Configuration @EnableOAuth2Sso public class SiteSecurityConfigurer extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // ... } }

Tutte le richieste che richiedono l'autenticazione verranno reindirizzate al server di autorizzazione. Perché funzioni dobbiamo anche definire le proprietà del server:

security: oauth2: client: accessTokenUri: //localhost:7070/authserver/oauth/token userAuthorizationUri: //localhost:7070/authserver/oauth/authorize clientId: authserver clientSecret: passwordforauthserver resource: userInfoUri: //localhost:9000/user

Nota che abbiamo bisogno di avere spring-boot-starter-security nel nostro classpath per trovare la configurazione di cui sopra funzionante.

3. Inoltro dei token di accesso

Durante l'inoltro di un token, un client OAuth2 inoltra il token OAuth2 ricevuto da esso a una richiesta di risorsa in uscita.

Poiché abbiamo dichiarato l' annotazione @ EnableOauth2Sso , Spring Boot aggiunge un bean OAuth2ClientContext nell'ambito della richiesta. Sulla base di ciò, possiamo creare il nostro OAuth2RestTemplate nella nostra applicazione client:

@Bean public OAuth2RestOperations restOperations( OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) { return new OAuth2RestTemplate(resource, context); }

Una volta configurato il bean , il contesto inoltrerà il token di accesso ai servizi richiesti e aggiornerà anche il token se scade.

4. Inoltro di un token OAuth utilizzando RestTemplate

Abbiamo precedentemente definito un bean restOperations di tipo OAuth2RestTemplate nella nostra applicazione client. Di conseguenza, possiamo utilizzare il metodo getForObject () di OAuth2RestTemplate per inviare una richiesta con i token necessari a un server di risorse protetto dal nostro client.

Per prima cosa, definiamo un endpoint che richiede l'autenticazione nel nostro Resource Server:

@GetMapping("/person") @PreAuthorize("hasAnyRole('ADMIN', 'USER')") public @ResponseBody Person personInfo(){ return new Person("abir", "Dhaka", "Bangladesh", 29, "Male"); } 

Si tratta di un semplice endpoint REST che restituisce una rappresentazione JSON di un oggetto Person .

Ora possiamo inviare una richiesta dall'applicazione client utilizzando il metodo getForObject () che inoltrerà il token al Resource Server :

@Autowired private RestOperations restOperations; @GetMapping("/personInfo") public ModelAndView person() { ModelAndView mav = new ModelAndView("personinfo"); String personResourceUrl = "//localhost:9000/person"; mav.addObject("person", restOperations.getForObject(personResourceUrl, String.class)); return mav; }

5. Configurazione di Zuul per Token Relay

Se desideriamo inoltrare un token a valle ai servizi proxy, possiamo utilizzare Spring Cloud Zuul Embedded Reverse Proxy.

Innanzitutto, dobbiamo aggiungere la dipendenza Maven per lavorare con Zuul:

 org.springframework.cloud spring-cloud-starter-netflix-zuul 

Successivamente, dobbiamo aggiungere l' annotazione @ EnableZuulProxy alla nostra classe di configurazione nell'applicazione client:

@Configuration @EnableOAuth2Sso @EnableZuulProxy public class SiteSecurityConfigurer extends WebSecurityConfigurerAdapter { //... }

Tutto ciò che resta da fare è aggiungere le proprietà di configurazione Zuul al nostro file application.yml :

zuul: sensitiveHeaders: Cookie,Set-Cookie routes: resource: path: /api/** url: //localhost:9000 user: path: /user/** url: //localhost:9000/user

Qualsiasi richiesta in arrivo all'endpoint / api dell'applicazione client verrà reindirizzata all'URL del server delle risorse. È inoltre necessario fornire l'URL dell'endpoint delle credenziali utente.

6. Conclusione

In questo breve articolo, abbiamo esplorato come utilizzare Spring Cloud Security con OAuth2 e Zuul per configurare l'autorizzazione protetta e i server di risorse, nonché come inoltrare i token OAuth2 tra i server utilizzando Oauth2RestTemplate e Embedded Zuul Proxy.

Come sempre, il codice è disponibile su GitHub.