Configuração Automática de Segurança de Inicialização Spring

Configuração Automática de Segurança de Inicialização Spring

1. Introdução

Neste artigo, daremos uma olhada na abordagem opinativa do Spring Boot para a segurança.

Simplificando, vamos nos concentrar na configuração de segurança padrão e como podemos desabilitá-la ou personalizá-la se necessário.

Leitura adicional:

Spring Security - segurança nenhuma, filtros nenhum, permissão de acesso

As diferenças entre access = "allowAll", filtros = "none", security = "none" no Spring Security.

Read more

Login do Formulário de Segurança da Primavera

Um exemplo de login do Spring - Como configurar um formulário de login simples, uma configuração XML de segurança básica e algumas técnicas de configuração mais avançadas.

Read more

2. Configuração de segurança padrão

Para adicionar segurança ao nosso aplicativo Spring Boot, precisamos adicionar osecurity starter dependency:


    org.springframework.boot
    spring-boot-starter-security

Isso incluirá a classeSecurityAutoConfiguration - contendo a configuração de segurança inicial / padrão.

Observe como não especificamos a versão aqui, com a suposição de que o projeto já está usando Boot como pai.

Simplificando,by default, the Authentication gets enabled for the Application. Also, content negotiation is used to determine if basic or formLogin should be used.

Existem algumas propriedades predefinidas, como:

spring.security.user.name
spring.security.user.password

Se não configurarmos a senha usando a propriedade predefinidaspring.security.user.password e iniciarmos o aplicativo, notaremos que uma senha padrão é gerada aleatoriamente e impressa no log do console:

Using default security password: c8be15de-4488-4490-9dc6-fab3f91435c6

Para obter mais padrões, consulte a seção de propriedades de segurança da página de referênciaSpring Boot Common Application Properties.

3. Desativando a configuração automática

Para descartar a configuração automática de segurança e adicionar nossa própria configuração, precisamos excluir a classeSecurityAutoConfiguration.

Isso pode ser feito através de uma simples exclusão:

@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class SpringBootSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootSecurityApplication.class, args);
    }
}

Ou adicionando alguma configuração ao arquivoapplication.properties:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration

Existem também alguns casos particulares em que esta configuração não é suficiente.

Por exemplo, quase todos os aplicativos Spring Boot são iniciados com o Actuator no caminho de classe. This causes problems because another auto-configuration class needs the one we’ve just excluded, portanto, o aplicativo falhará ao iniciar.

Para corrigir esse problema, precisamos excluir essa classe; e, específico para a situação do Atuador, precisamos excluirManagementWebSecurityAutoConfiguration.

3.1. Desativando vs. Ultrapassando a configuração automática de segurança

Há uma diferença significativa entre desativar a configuração automática e superá-la.

Ao desabilitá-lo, é como adicionar a dependência do Spring Security e toda a configuração do zero. Isso pode ser útil em vários casos:

  1. Integrando a segurança do aplicativo a um provedor de segurança personalizado

  2. Migrando um aplicativo Spring legado com a configuração de segurança já existente - para o Spring Boot

Mas, na maioria das vezes, não precisamos desabilitar totalmente a configuração automática de segurança.

A maneira como o Spring Boot é configurado permite superar a segurança configurada automaticamente adicionando em nossas novas classes de configuração personalizadas. Normalmente, isso é mais fácil, pois estamos apenas personalizando uma configuração de segurança existente para atender às nossas necessidades.

4. Configurando Spring Boot Security

Se escolhemos o caminho para desabilitar a configuração automática de segurança, naturalmente precisamos fornecer nossa própria configuração.

Como discutimos antes, esta é a configuração de segurança padrão; podemos personalizá-lo modificando o arquivo de propriedades.

Por exemplo, podemos substituir a senha padrão adicionando a nossa:

security.user.password=password

Se quisermos uma configuração mais flexível, com vários usuários e funções, por exemplo - agora você precisa fazer uso de uma classe@Configuration completa:

@Configuration
@EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
      throws Exception {
        auth
          .inMemoryAuthentication()
          .withUser("user")
            .password("password")
            .roles("USER")
            .and()
          .withUser("admin")
            .password("admin")
            .roles("USER", "ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .anyRequest()
          .authenticated()
          .and()
          .httpBasic();
    }
}

A anotação@EnableWebSecurity é crucial se desabilitarmos a configuração de segurança padrão.

Se ausente, o aplicativo falhará ao iniciar. A anotação só é opcional se estivermos apenas substituindo o comportamento padrão usando umWebSecurityConfigurerAdapter.

Agora, devemos verificar se nossa configuração de segurança se aplica corretamente com alguns testes rápidos ao vivo:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class BasicConfigurationIntegrationTest {

    TestRestTemplate restTemplate;
    URL base;
    @LocalServerPort int port;

    @Before
    public void setUp() throws MalformedURLException {
        restTemplate = new TestRestTemplate("user", "password");
        base = new URL("http://localhost:" + port);
    }

    @Test
    public void whenLoggedUserRequestsHomePage_ThenSuccess()
     throws IllegalStateException, IOException {
        ResponseEntity response
          = restTemplate.getForEntity(base.toString(), String.class);

        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertTrue(response
          .getBody()
          .contains("example"));
    }

    @Test
    public void whenUserWithWrongCredentials_thenUnauthorizedPage()
      throws Exception {

        restTemplate = new TestRestTemplate("user", "wrongpassword");
        ResponseEntity response
          = restTemplate.getForEntity(base.toString(), String.class);

        assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
        assertTrue(response
          .getBody()
          .contains("Unauthorized"));
    }
}

A idéia é que, por trás do Spring Boot Security, é de fato o Spring Security, portanto, qualquer configuração de segurança que possa ser feita com este, ou qualquer integração que este suporte também possa ser implementada no Spring Boot.

5. Configuração automática Spring Boot OAuth2

O Spring Boot possui um suporte de configuração automática dedicado para OAuth2.

Antes de chegarmos a isso, vamos adicionar a dependência Maven para começar a configurar nosso aplicativo:


   org.springframework.security.oauth
   spring-security-oauth2

Essa dependência inclui um conjunto de classes que são capazes de acionar o mecanismo de autoconfiguração definido na classeOAuth2AutoConfiguration.

Agora, temos várias opções para continuar, dependendo do escopo de nosso aplicativo.

5.1. Configuração automática do servidor de autorização OAuth2

Se quisermos que nosso aplicativo seja um provedor OAuth2, podemos usar@EnableAuthorizationServer.

Na inicialização, vamos notar nos logs que as classes de configuração automática irão gerar uma ID de cliente e um segredo de cliente para nosso servidor de autorização e, claro, uma senha aleatória para autenticação básica.

Using default security password: a81cb256-f243-40c0-a585-81ce1b952a98
security.oauth2.client.client-id = 39d2835b-1f87-4a77-9798-e2975f36972e
security.oauth2.client.client-secret = f1463f8b-0791-46fe-9269-521b86c55b71

Essas credenciais podem ser usadas para obter um token de acesso:

curl -X POST -u 39d2835b-1f87-4a77-9798-e2975f36972e:f1463f8b-0791-46fe-9269-521b86c55b71 \
 -d grant_type=client_credentials
 -d username=user
 -d password=a81cb256-f243-40c0-a585-81ce1b952a98 \
 -d scope=write  http://localhost:8080/oauth/token

5.2. Outras definições de configuração automática Spring Boot OAuth2

Existem outros casos de uso cobertos pelo Spring Boot OAuth2, como:

  1. Servidor de recursos -@EnableResourceServer

  2. Aplicativo cliente -@EnableOAuth2Sso ou@EnableOAuth2Client

Se precisarmos que nosso aplicativo seja um dos tipos acima, basta adicionar alguma configuração às propriedades do aplicativo.

Todas as propriedades específicas do OAuth2 podem ser encontradas emSpring Boot Common Application Properties.

6. Spring Boot 2 Security vs Spring Boot 1 Security

Em comparação com Spring Boot 1,Spring Boot 2 has greatly simplified the auto-configuration.

No Spring Boot 2, se quisermos nossa própria configuração de segurança, podemos simplesmente adicionar umWebSecurityConfigurerAdapter. personalizado. Isso desabilitará a configuração automática padrão e habilitará nossa configuração de segurança personalizada.

O Spring Boot 2 usa a maioria dos padrões do Spring Security. Por causa disso,some of the endpoints that were unsecured by default in Spring Boot 1 are now secured by default.

Esses terminais incluem recursos estáticos como / css /, /js/, / images /, /webjars/, /**/favicon.ico e o terminal de erro. Se precisarmos permitir acesso não autenticado a esses pontos de extremidade, podemos configurá-lo explicitamente.

Para simplificar a configuração relacionada à segurança,Spring Boot 2 has removed the following Spring Boot 1 properties:

security.basic.authorize-mode
security.basic.enabled
security.basic.path
security.basic.realm
security.enable-csrf
security.headers.cache
security.headers.content-security-policy
security.headers.content-security-policy-mode
security.headers.content-type
security.headers.frame
security.headers.hsts
security.headers.xss
security.ignored
security.require-ssl
security.sessions

7. Conclusão

Neste artigo, focamos na configuração de segurança padrão fornecida pelo Spring Boot. Vimos como o mecanismo de configuração automática de segurança pode ser desativado ou substituído e como uma nova configuração de segurança pode ser aplicada.

O código-fonte pode ser encontradoover on Github.