Como proteger seu aplicativo Spring com Spring Security
O Spring Security é um meio eficaz para proteger os aplicativos por meio dos processos de autenticação e autorização. Por padrão, essa estrutura exige que cada URL individual ou página da Web dentro de um aplicativo seja acessado com as credenciais de um usuário final solitário e globalmente reconhecido.
A abordagem proposta exibe uma adaptabilidade excepcional. Ele permite a formulação de regulamentos de segurança personalizados para cada rota de solicitação HTTP individual em seu programa, juntamente com os usuários finais distintos. Consequentemente, torna-se possível eliminar as limitações de segurança impostas às páginas da Web que não necessitam de autenticação do usuário, como a homepage. Além disso, esse método permite a especificação de atribuições de funções e níveis de autoridade para determinadas categorias de usuários.
Adicionando Spring Security ao seu aplicativo
Ao incorporar o Spring Security em um aplicativo Spring Boot existente ou recém-criado, existem dois métodos principais de implementação. A primeira envolve selecionar a integração durante o processo de geração de um novo projeto Spring Boot utilizando a plataforma Spring Initializr. Como alternativa, pode-se optar por incluí-lo nas especificações de construção do projeto, adicionando-o à lista de dependências no referido documento após a criação do projeto.
Os arquivos de configuração para projetos Gradle são identificados como build.gradle quando selecionados por meio da primeira opção, enquanto aqueles em projetos Maven são indicados como pom.xml.
Seu arquivo build.gradle deve incluir uma dependência específica, conforme descrito abaixo:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
}
Espera-se que o arquivo XML de portfólio mencionado acima inclua uma confiança específica, descrita a seguir:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
O aplicativo de amostra fornecido pode ser acessado por meio de um repositório GitHub, que o oferece gratuitamente sob os termos da licença MIT, permitindo que os usuários o utilizem de acordo com suas condições especificadas.
Usando o Spring Security
Ao incorporar o módulo Spring Security em seu projeto, você já está equipado para implantar suas funcionalidades sem demora. Para demonstrar isso, basta iniciar seu programa e direcionar seu navegador para o site oficial do Spring Boot ou qualquer página designada em seu próprio aplicativo. O exemplo fornecido emprega um controlador primário que controla o tratamento padrão de solicitações de entrada direcionadas à URL pré-configurada http://localhost:8080.
package com.springSecurityDemo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebController {
@GetMapping("/")
public String home() {
return "Welcome!";
}
}
A referida aplicação, ao incorporar a referida classe de controlador solitário, produz uma perspectiva inicial da seguinte forma:
Ao acessar o aplicativo pela primeira vez, será direcionado para a página localhost:8080/login. Antes de obter acesso a qualquer outra parte do programa, o usuário deve inserir o nome de usuário predefinido, que é “usuário”, junto com a senha criada aleatoriamente, que pode ser encontrada no prompt de comando. O prompt de comando gera uma mensagem semelhante ao exemplo a seguir:
Using generated security password: c4070465-4c65-4e72-8c3f-3800e631ba81
Nas reinicializações subsequentes do aplicativo, a senha gerada automaticamente sofrerá alteração; no entanto, o nome de usuário permanecerá inalterado. Ao inserir o nome de usuário e a senha predefinidos, o usuário será redirecionado para a interface relevante dentro do aplicativo.
Personalizando o Spring Security
Para adequar a segurança do seu aplicativo de acordo com seus requisitos específicos, é necessário modificar a configuração padrão fornecida pelo Spring Security. No entanto, antes de fazer isso, supondo que você já tenha configurado um aplicativo da Web básico usando o Spring, há vários pré-requisitos adicionais que devem ser atendidos para utilizar este exemplo específico:
⭐Spring Data JPA
⭐Driver MySQL JDBC
⭐Folha de tomilho
⭐Lombok
A utilização do framework Thymeleaf permite a geração de múltiplas perspectivas, enquanto o Lombok agiliza o processo de codificação dentro de estruturas de classes baseadas em objetos. Além disso, a integração com a biblioteca JPA e o driver MySQL facilita a interação com um banco de dados MySQL, embora bancos de dados alternativos também possam ser empregados a critério do usuário. Para configurar tais interações, é necessário ajustar as definições de configuração presentes no arquivo applications.properties, que reside no diretório 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
Para estabelecer uma conexão com uma instância local do MySQL, denotada como “spring\_security”, utilizando o nome de usuário “root” e a senha “(1234)”, é imperativo que o código de configuração fornecido seja configurado corretamente atualizando as informações relevantes de acordo para garantir a compatibilidade com a configuração específica do banco de dados.
Depois de adicionar todas as dependências necessárias e estabelecer seu banco de dados, você pode começar a determinar o número de perspectivas que seu aplicativo abrangerá. Além disso, é importante considerar as medidas de segurança em vigor para cada ponto de vista. Em nosso exemplo ilustrativo, há seis pontos de vista distintos incorporados ao aplicativo.
⭐Página inicial
⭐Página de registro
⭐Página de login
⭐Sair da página
⭐Página do usuário
⭐Página de erro
Para que um usuário acesse suas informações pessoais na “página do usuário”, ele deve primeiro se registrar e fazer login no aplicativo. Somente aqueles que se registraram têm permissão para visualizar esta página. Além disso, é necessário estabelecer quatro pacotes adicionais dentro do aplicativo além do que é fornecido pelas ofertas padrão do Spring Boot.
A Classe do Controlador de Registro
O pacote Controller compreende classes responsáveis pelo processamento de requisições HTTP. Normalmente, uma única classe de controlador lida com solicitações correspondentes à funcionalidade de uma página da Web específica, como na instância da classe WebController. Por outro lado, o RegistrationView requer o gerenciamento de funcionalidades distintas, necessitando, portanto, de uma classe de controlador privada dedicada.
@Controller
@RequestMapping("/register")
public class RegistrationController {
private UserRepository userRepo;
private PasswordEncoder passwordEncoder;
public RegistrationController( 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 RegistrationController
serve como um ponto de entrada para a funcionalidade de segurança em nosso aplicativo, com sua manipulação de solicitações direcionadas para localhost:8080/register
. Isso é indicado pela anotação @RequestMapping
, que especifica o tipo específico de solicitação que esse controlador foi projetado para atender.
A anotação @GetMapping
significa que quando o aplicativo encontra uma solicitação para /register
, o método registrationForm()
é responsável por processar essa solicitação e renderizar a exibição de registro correspondente.
Depois que um visitante clica no botão de registro, a anotação @PostMapping entra em ação. O método processRegistration() permite que você envie os dados do usuário obtidos da classe RegistrationForm para o banco de dados, usando a classe UserRepository. Mas antes de armazenar esses dados, o método processRegistration() criptografa a senha do usuário usando Spring’s Interface do PasswordEncoder.
Criando Novas Configurações de Segurança
Utilizando a introdução do Spring 3.1, os desenvolvedores agora são capazes de empregar uma abordagem baseada em Java para configurar o Spring Security por meio da utilização de classes, em vez de depender de configurações baseadas em XML. Essencial para este processo é a inclusão do
@Configuration
public class SecurityConfiguration {
}
A anotação @Configuration
significa que a classe subsequente constitui uma classe de configuração, que é instrumental em fornecer constituintes para o contexto do aplicativo Spring. Esse contêiner serve como um meio para o Spring construir e administrar os vários elementos (ou constituintes) de um aplicativo. Na classe SecurityConfiguration
, o constituinte inicial fornecido é indicado pela designação passwordEncoder
.
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
O RegistrationController
depende do bean passwordEncoder
para codificar senhas recém-geradas antes de seu armazenamento no banco de dados. Além disso, o SecurityConfiguration
requer a incorporação de um bean userDetailsService
para seu funcionamento adequado.
@Bean
public UserDetailsService userDetailsService(UserRepository userRepo) {
return username -> {
Customer customer = userRepo.findByUsername(username);
if (customer != null)
return customer;
throw new UsernameNotFoundException("Customer '" \+ username \+ "' not found");
};
}
O bean userDetailsService emprega a interface UserDetailsService do Spring Security UserDetailsService 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 clica no botão de login na visualização de login, o bean userDetailsService entra em ação.
Por meio da utilização da interface UserRepository
, o bean userDetailsService
recebe acesso à coleção abrangente de usuários armazenados no banco de dados. A interface subseqüentemente emprega o UserRepository
para identificar um usuário cujas credenciais correspondem ao nome de usuário e senha fornecidos, após o que recupera e retorna todas as informações relevantes pertencentes a esse cliente específico como uma entidade agregada.
Após a autenticação bem-sucedida das credenciais fornecidas, se a entidade recuperada corresponder a um cliente registrado, eles recebem permissão para utilizar os recursos da plataforma. Caso a validação falhe e uma combinação de nome de usuário ou senha inválida seja inserida, a interface é recarregada continuamente, convidando o usuário final a inserir informações de login legítimas para outra tentativa.
A Cadeia do Filtro
Spring Security’s A interface SecurityFilterChain é uma interface de programação de aplicativo (API) útil que desempenha um papel essencial na configuração do Spring Security. Esta interface funciona com Spring Security’s HttpSecurity 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 código fornecido utiliza a classe HttpSecurity
dentro do bean filterChain
para impor medidas de segurança restringindo o acesso a terminais específicos com base nas funções do usuário. Especificamente, a configuração HttpSecurity
concede acesso ao terminal /user
apenas para aqueles usuários que possuem a função “USER”, que é determinada pela implementação do método getAuthorities()
encontrado em cada objeto cliente recém-criado.
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Arrays.asList(new SimpleGrantedAuthority("USER"));
}
A cadeia de filtro permite acesso irrestrito a cada URL dentro do aplicativo para usuários que não foram autenticados, pois aproveita os procedimentos de login e logout do formulário fornecidos pela classe HttpSecurity.
A implementação dessas técnicas permite uma navegação perfeita para usuários que concluíram uma ação com êxito. Por exemplo, ao inserir credenciais válidas e clicar no botão “Login” na página “/login”, o usuário é redirecionado sem esforço para a página “/user” sem qualquer intervenção adicional necessária de sua parte.
Em conclusão, o bean filterChain constrói e gera uma cadeia de filtros, permitindo que usuários finais autenticados tenham acesso à plataforma de software. A função coletiva de todos os três componentes dentro da classe de configuração SecurityConfiguration é proteger seu aplicativo contra acesso não autorizado.
O bean filterChain ocupa uma posição central na determinação da camada de autorização para cada solicitação HTTP recebida. Sua influência aumenta à medida que páginas da Web adicionais são adicionadas ao aplicativo, permitindo que o bean filterChain estabeleça seu nível de segurança.
O principal benefício do Spring Security
O Spring Security fornece uma ampla gama de recursos para regular os indivíduos admitidos e o escopo das permissões concedidas àqueles dentro do domínio de seu aplicativo (utilizando sua lista robusta de funções de usuário). A implementação de mecanismos eficientes de controle de acesso está entre as considerações primordiais no desenvolvimento de soluções de software. Fornecer entrada irrestrita a uma ampla gama de usuários devido a medidas de restrição de acesso insuficientes pode resultar inadvertidamente em despesas substanciais e possíveis violações de segurança.