Vários pontos de entrada no Spring Security
*1. Visão geral *
Neste tutorial rápido, veremos como* definir vários pontos de entrada em um aplicativo Spring Security *.
Isso implica principalmente na definição de vários blocos http em um arquivo de configuração XML ou em várias instâncias HttpSecurity, estendendo a classe WebSecurityConfigurerAdapter várias vezes.
*2. Dependências do Maven *
Para o desenvolvimento, precisaremos das seguintes dependências:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>5.0.4.RELEASE</version>
</dependency>
As versões mais recentes de spring-boot-starter-security, spring-boot-starter-web , Https://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22spring-boot-starter-thymeleaf%22[spring-boot-starter-thymeleaf], https://search. maven.org/classic/#search%7Cga%7C1%7Ca%3A%22spring-boot-starter-test%22[spring-boot-starter-test], https://search.maven.org/classic/#search % 7Cga% 7C1% 7Ca% 3A% 22spring-security-test% 22 [teste de segurança da primavera] pode ser baixado do Maven Central.
===* 3. Vários pontos de entrada *
====* 3.1 Vários pontos de entrada com vários elementos HTTP *
Vamos definir a principal classe de configuração que conterá uma fonte de usuário:
@Configuration
@EnableWebSecurity
public class MultipleEntryPointsSecurityConfig {
@Bean
public UserDetailsService userDetailsService() throws Exception {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User
.withUsername("user")
.password(encoder().encode("userPass"))
.roles("USER").build());
manager.createUser(User
.withUsername("admin")
.password(encoder().encode("adminPass"))
.roles("ADMIN").build());
return manager;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
Agora, vejamos* como podemos definir vários pontos de entrada *em nossa configuração de segurança.
Vamos usar um exemplo orientado pela autenticação básica aqui e faremos bom uso do fato de que o* Spring Security suporta a definição de vários elementos HTTP * em nossas configurações.
Ao usar a configuração Java, a maneira de definir várias regiões de segurança é ter várias classes _ @ Configuration_ que estendem a classe base WebSecurityConfigurerAdapter - cada uma com sua própria configuração de segurança. Essas classes podem ser estáticas e colocadas dentro da configuração principal.
A principal motivação para ter vários pontos de entrada em um aplicativo é se existem diferentes tipos de usuários que podem acessar partes diferentes do aplicativo.
Vamos definir uma configuração com três pontos de entrada, cada um com diferentes permissões e modos de autenticação:
-
um para usuários administrativos usando autenticação básica HTTP
-
um para usuários regulares que usam autenticação de formulário *e um para usuários convidados que não exigem autenticação
O ponto de entrada definido para usuários administrativos protege URLs do formulário /admin/* * _ para permitir apenas usuários com uma função de ADMIN e requer autenticação básica HTTP com um ponto de entrada do tipo _BasicAuthenticationEntryPoint que é definido usando o método _authenticationEntryPoint () _ :
@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin/**")
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and().httpBasic().authenticationEntryPoint(authenticationEntryPoint());
}
@Bean
public AuthenticationEntryPoint authenticationEntryPoint(){
BasicAuthenticationEntryPoint entryPoint =
new BasicAuthenticationEntryPoint();
entryPoint.setRealmName("admin realm");
return entryPoint;
}
}
A anotação _ @ Order_ em cada classe estática indica a ordem na qual as configurações serão consideradas para encontrar uma que corresponda à URL solicitada. *O valor order para cada classe deve ser exclusivo.
O bean do tipo BasicAuthenticationEntryPoint requer que a propriedade realName esteja configurada.
====* 3.2 Vários pontos de entrada, mesmo elemento HTTP *
Em seguida, vamos definir a configuração dos URLs do formulário _/user/* * _ que podem ser acessados por usuários regulares com uma função de USUÁRIO usando autenticação de formulário:
@Configuration
@Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/user/**")
.authorizeRequests().anyRequest().hasRole("USER")
.and()
//formLogin configuration
.and()
.exceptionHandling()
.defaultAuthenticationEntryPointFor(
loginUrlauthenticationEntryPointWithWarning(),
new AntPathRequestMatcher("/user/private/**"))
.defaultAuthenticationEntryPointFor(
loginUrlauthenticationEntryPoint(),
new AntPathRequestMatcher("/user/general/**"));
}
}
Como podemos ver, outra maneira de definir pontos de entrada, além do método authenticationEntryPoint (), é usar o método defaultAuthenticationEntryPointFor () _. Isso pode definir vários pontos de entrada que correspondem a diferentes condições com base em um objeto _RequestMatcher.
A interface RequestMatcher possui implementações baseadas em diferentes tipos de condições, como caminho correspondente, tipo de mídia ou regexp. Em nosso exemplo, usamos o AntPathRequestMatch para definir dois pontos de entrada diferentes para URLs dos formulários /user/private/* e /user/general/