Garanta a segurança de seu aplicativo Spring aproveitando os recursos robustos oferecidos pela estrutura Spring Security.
A estrutura Spring Security protege seu aplicativo por meio de autenticação e autorização. Em seu estado padrão, o Spring Security garante que cada caminho de solicitação HTTP (ou página) em seu aplicativo exija a autenticação de um único usuário global.
Essa estrutura também é extremamente flexível. Ele permite que você crie regras de segurança personalizadas para cada caminho de solicitação HTTP em seu aplicativo, bem como para os diferentes usuários. Assim, você pode remover a restrição de segurança em páginas que não requerem autorização do usuário (como uma página inicial). E defina as funções e autoridades de tipos de usuários específicos.
Adicionando Spring Security ao seu aplicativo
Existem duas maneiras de adicionar Spring Security ao seu aplicativo. Você pode selecioná-lo como uma dependência ao gerar um novo aplicativo Spring Boot usando Spring initializr, ou adicione-o ao seu arquivo de especificação de construção na seção de dependência após gerar seu projeto.
Se você selecionou uma das opções de projeto do Gradle, o arquivo de dependências é build.gradle. No entanto, se você escolher Maven, esse arquivo será pom.xml.
Seu build.gradle arquivo deve conter a seguinte dependência:
dependencies {
implementation 'org.springframework.boot: spring-boot-starter-security'
}
Enquanto seu pom.xml arquivo deve conter a seguinte dependência:
org.springframework.boot
spring-boot-starter-security
O aplicativo de exemplo usado no artigo está disponível neste Repositório GitHub e é gratuito para você usar sob a licença do MIT.
Usando o Spring Security
Depois de adicionar a dependência do Spring Security ao seu aplicativo, você pode começar a usar a estrutura imediatamente. Simplesmente execute seu aplicativo e navegue até a página inicial do Spring Boot (ou qualquer página do seu aplicativo). O aplicativo de exemplo usa o seguinte controlador inicial para controlar o padrão do Spring Boot host local: 8080 solicitar:
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
publicclassWebController{
@GetMapping("/")
public String home(){
return"Welcome!";
}
}
Executar seu aplicativo após adicionar a classe de controlador único acima gera a seguinte visualização inicial:
Você notará que ele o direciona automaticamente para o host local: 8080/login página, e faz isso antes de permitir que você acesse qualquer outra página do aplicativo. Nesta fase, você precisará fornecer o nome de usuário padrão (que é o usuário) e a senha gerada automaticamente (que você encontrará no console). O console irá gerar uma linha como a seguinte:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
Cada vez que você reiniciar seu aplicativo, a senha gerada automaticamente mudará, mas o nome de usuário permanecerá o mesmo. Inserir o nome de usuário e a senha padrão o direcionará para a exibição apropriada em seu aplicativo.
Personalizando o Spring Security
Para personalizar a segurança do seu aplicativo, você precisará substituir a configuração padrão do Spring Security. Mas antes disso (supondo que você já tenha o Spring Web), você precisará de várias outras dependências para este aplicativo de amostra:
- Spring Data JPA
- Driver MySQL JDBC
- folha de tomilho
- Lombok
A estrutura Thymeleaf gerará visualizações diferentes. O Lombok ajudará a reduzir o código em suas classes de objeto. A biblioteca JPA e o driver MySQL permitirão que você use um banco de dados MySQL com o aplicativo, mas você tem a opção de usar qualquer banco de dados com o qual se sinta confortável. Usar um banco de dados significa configurar o aplicações.propriedades arquivo sob o arquivo de recursos.
spring.datasource.url=jdbc: mysql://${MYSQL_HOST: localhost}:3306/spring_security
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
O código de configuração acima permite que você se conecte a um banco de dados MySQL local chamado spring_security, com um nome de usuário de raiz, e senha (1234). Você precisará atualizar esses dados para corresponder ao nome e às credenciais do seu banco de dados.
Depois de adicionar suas dependências adicionais e criar seu banco de dados, você pode começar a decidir quantas visualizações seu aplicativo terá. Você também precisará saber como é a segurança de cada página. Nosso aplicativo de exemplo tem 6 visualizações:
- Pagina inicial
- Página de registro
- Página de login
- Página de saída
- Página do usuário
- página de erro
A única exibição que exigirá autorização do usuário é a página do usuário. Esta página só pode ser acessada por usuários que primeiro se registram e, em seguida, fazem login no aplicativo. Além do pacote padrão do Spring Boot, você precisará criar outros quatro pacotes em seu aplicativo.
A classe do controlador de registro
O pacote do controlador conterá as classes que lidam com solicitações HTTP. Dependendo da função de uma página, você geralmente pode agrupar cada solicitação HTTP em uma classe controladora, como é o caso do WebController aula. No entanto, a visualização de registro tem mais funções exclusivas, portanto, pode ter uma classe de controlador privado:
@Controller
@RequestMapping("/register")
publicclassRegistrationController{
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
publicRegistrationController( UserRepository userRepo, PasswordEncoder passwordEncoder){
this.userRepo = userRepo;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(){
return"registration";
}
@PostMapping
public String processRegistration(RegistrationForm form){
userRepo.save(form.toUser(passwordEncoder));
return"redirect:/login";
}
}
O Controlador de registro class é um gateway para o aspecto de segurança do seu aplicativo. O @RequestMapping A anotação especifica o tipo de solicitação que este controlador irá manipular (solicitações para host local: 8080/registro).
O @GetMapping A anotação simplesmente indica que, se o aplicativo receber uma solicitação de /register, o formulário de registro() O método deve lidar com essa solicitação retornando a exibição de registro.
Depois que um visitante clica no botão de registro, o @PostMapping anotação entra em jogo. O processRegistration() método permite que você publique os dados do usuário que obtém do Formulário de registro classe para o banco de dados, usando o UserRepository aula. Mas antes de armazenar esses dados, o processRegistration() método criptografa a senha do usuário usando primaveraCodificador de Senha interface.
Criando Novas Configurações de Segurança
Desde o Spring 3.1, os desenvolvedores agora podem criar configurações para Spring Security usando Java, o que significa classes em vez de XML. A principal coisa que essas classes de configuração exigem é o @Configuração anotação.
@Configuration
publicclassSecurityConfiguration{
}
O @Configuração A anotação indica que a classe acima é uma classe de configuração. Essas classes fornecem beans para o Contexto do aplicativo Spring, que é um contêiner que o Spring usa para criar e gerenciar os diferentes componentes (ou beans) de um aplicativo. O primeiro feijão da Configuração de segurança classe é o passwordEncoder feijão.
@Bean
public PasswordEncoder passwordEncoder(){
returnnew BCryptPasswordEncoder();
}
O Controlador de registro classe usa o passwordEncoder bean para codificar novas senhas antes de salvá-las no banco de dados. Outro bean importante que você precisará adicionar ao Configuração de segurança classe é o userDetailsService feijão.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo){
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
thrownew UsernameNotFoundException("Customer '" + username + "' not found");
};
}
O userDetailsService feijão emprega Spring Security'sUserDetailsServiço interface para recuperar o nome de usuário e a senha de um usuário para autenticação, durante a sessão de login de um cliente. Portanto, assim que um cliente clicar no botão de login na visualização de login, o userDetailsService feijão entra em movimento.
Através de UserRepository, o userDetailsService bean obtém acesso a todos os clientes existentes no banco de dados. Essa interface então usa o UserRepository para localizar um usuário com um nome de usuário e senha correspondentes e, em seguida, retorna todos os atributos desse cliente como um objeto.
Se o objeto retornado for um cliente, esse cliente obterá acesso ao aplicativo. Caso contrário, a página será atualizada automaticamente, permitindo que o usuário insira credenciais válidas.
A Cadeia do Filtro
Spring Security'sSecurityFilterChain interface é útil interface de programação de aplicativos (API) que desempenha um papel essencial na configuração do Spring Security. Esta interface funciona com Spring Security'sHttpSecurity class para criar uma cadeia de filtros para solicitações HTTP específicas.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.requestMatchers("/user").hasAuthority("USER").anyRequest().permitAll())
.formLogin(formLogin -> formLogin
.loginPage("/login").defaultSuccessUrl("/user", true))
.logout(logout -> logout.logoutSuccessUrl("/logout"));
return http.build();
}
O cadeia de filtros feijão acima usa o SecurityFilterChain API para realizar várias tarefas. Primeiro, ele usa o HttpSecurity class para ditar que apenas os usuários que têm a função de um USER podem acessar host local: 8080/usuário. E um usuário obtém essa função após o registro, graças ao getAutoridades() método que cada novo objeto cliente implementa.
@Override
public Collection extends="extends" grantedauthority="grantedauthority"?> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
A cadeia de filtro permite acesso não autenticado a todos os outros URLs no aplicativo. O cadeia de filtros feijão também utiliza o formLogin() e sair() métodos do HttpSecurity objeto de classe.
Esses métodos permitem direcionar automaticamente um usuário para páginas específicas após a execução de uma tarefa. Portanto, um usuário que insere as credenciais corretas e clica no botão de login no /login página será automaticamente direcionada para o /user página.
finalmente, o cadeia de filtros bean constrói e retorna a cadeia de filtro, que permite que usuários autorizados acessem o aplicativo. Todos os três feijões no Configuração de segurança classe trabalham juntos para proteger seu aplicativo.
No entanto, o cadeia de filtros bean desempenha o papel mais significativo de ditar o nível de autorização para cada solicitação HTTP. Ao começar a adicionar mais páginas ao seu aplicativo, você pode usar o cadeia de filtros bean para definir seu nível de segurança.
O principal benefício do Spring Security
O Spring Security oferece controle total não apenas sobre quem tem acesso ao seu aplicativo, mas também sobre o tipo de acesso que um usuário pode ter (através de seu recurso de funções de usuário). O controle de acesso é um dos aspectos mais importantes de qualquer aplicativo. Dar aos usuários em geral acesso não filtrado ao seu aplicativo devido a barreiras limitadas de controle de acesso pode ser um erro caro.