Introdução à Spring Cloud Security
1. Visão geral
O módulo Spring Cloud Security fornece recursos relacionados à segurança baseada em token nos aplicativos Spring Boot.
Especificamente, facilita o SSO baseado em OAuth2 - com suporte para retransmitir tokens entre servidores de recursos, além de configurar a autenticação downstream usando um proxy Zuul incorporado.
Neste artigo rápido, daremos uma olhada em como podemos configurar esses recursos usando um aplicativo cliente Spring Boot, um Authorization Server e uma API REST funcionando como um Resource Server.
Observe que, neste exemplo, só temos um aplicativo Cliente que usa SSO para demonstrar os recursos de segurança da nuvem - mas em um cenário típico, teríamos pelo menos dois aplicativos clientes para justificar a necessidade de Logon Único.
2. Quick Start a Cloud Security App
Vamos começar porconfiguring SSO in a Spring Boot application.
Primeiro, precisamos adicionar a dependênciaspring-cloud-starter-oauth2:
org.springframework.cloud
spring-cloud-starter-oauth2
2.2.2.RELEASE
Isso também trará a dependência despring-cloud-starter-security.
We can configure any social site as an Auth Server for our site or we can use our own server. In our case, we’ve chosen the latter option and configured an application that acts as an Authorization Server – which is implantado localmente emhttp://localhost:7070/authserver.
Nosso servidor de autorização usa tokens JWT.
Além disso, para que qualquer Cliente possa recuperar as credenciais de um usuário, precisamos configurar nosso Servidor de Recursos, executando na porta 9000, com um terminal que pode servir essas credenciais.
Aqui, configuramos um endpoint /user que está disponível emhttp://localhost:9000/user.
Para obter mais detalhes sobre como configurar um servidor de autorização e um servidor de recursos, verifique nossoprevious article here.
Agora podemos adicionar a anotação em uma classe de configuração em nosso aplicativo cliente:
@Configuration
@EnableOAuth2Sso
public class SiteSecurityConfigurer
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// ...
}
}
Any requests that require authentication will be redirected to the Authorization Server. Para que isso funcione, também temos que definir as propriedades do servidor:
security:
oauth2:
client:
accessTokenUri: http://localhost:7070/authserver/oauth/token
userAuthorizationUri: http://localhost:7070/authserver/oauth/authorize
clientId: authserver
clientSecret: passwordforauthserver
resource:
userInfoUri: http://localhost:9000/user
Observe que precisamos terspring-boot-starter-security em nosso caminho de classe para encontrar a configuração acima funcionando.
3. Relaying Access Tokens
Ao retransmitir um token, um cliente OAuth2 encaminha o token OAuth2 recebido por ele para uma solicitação de recurso de saída.
Como declaramos a anotação@EnableOauth2Sso, Spring Boot adiciona um beanOAuth2ClientContext no escopo da solicitação. Com base nisso, podemos criar nosso próprioOAuth2RestTemplate em nosso aplicativo cliente:
@Bean
public OAuth2RestOperations restOperations(
OAuth2ProtectedResourceDetails resource, OAuth2ClientContext context) {
return new OAuth2RestTemplate(resource, context);
}
Depois de configurar o bean,, o contexto encaminhará o token de acesso aos serviços solicitados e também atualizará o token se ele expirar.
4. Retransmitindo um token OAuth usandoRestTemplate
Definimos anteriormente um beanrestOperations do tipoOAuth2RestTemplate em nosso aplicativo Client. Como resultado,we can use the getForObject() method of OAuth2RestTemplate to send a request with the necessary tokens to a protected Resource server do nosso cliente.
Primeiro, vamos definir um endpoint que requer autenticação em nosso servidor de recursos:
@GetMapping("/person")
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
public @ResponseBody Person personInfo(){
return new Person("abir", "Dhaka", "Bangladesh", 29, "Male");
}
Este é um terminal REST simples que retorna uma representação JSON de um objetoPerson.
Agora,we can send a request from the Client application using the getForObject() method which will relay the token to the Resource Server:
@Autowired
private RestOperations restOperations;
@GetMapping("/personInfo")
public ModelAndView person() {
ModelAndView mav = new ModelAndView("personinfo");
String personResourceUrl = "http://localhost:9000/person";
mav.addObject("person",
restOperations.getForObject(personResourceUrl, String.class));
return mav;
}
5. Configurando Zuul para Token Relay
Se quisermos retransmitir um token downstream para os serviços de proxy, podemos usar o proxy reverso integrado Spring Cloud Zuul.
Primeiro, precisamos adicionar a dependência do Maven para trabalhar com o Zuul:
org.springframework.cloud
spring-cloud-starter-netflix-zuul
Em seguida, precisamos adicionar a anotação @EnableZuulProxy em nossa classe de configuração no aplicativo cliente:
@Configuration
@EnableOAuth2Sso
@EnableZuulProxy
public class SiteSecurityConfigurer
extends WebSecurityConfigurerAdapter {
//...
}
Tudo o que resta a fazer é adicionar as propriedades de configuração Zuul ao nosso arquivoapplication.yml:
zuul:
sensitiveHeaders: Cookie,Set-Cookie
routes:
resource:
path: /api/**
url: http://localhost:9000
user:
path: /user/**
url: http://localhost:9000/user
Qualquer solicitação que chegue ao endpoint /api do aplicativo cliente será redirecionada para a URL do servidor de recursos. Também precisamos fornecer o URL do terminal de credenciais do usuário.
6. Conclusão
Neste artigo rápido, exploramos como usar Spring Cloud Security com OAuth2 e Zuul para configurar autorização segura e servidores de recursos, bem como como retransmitir tokens OAuth2 entre servidores usandoOauth2RestTemplatee Proxy Zuul Embutido.
Como sempre, o código está disponívelover on GitHub.