Springboot
JWT3x
Json Web Token com Spring Boot 3x
Neste tutorial iremos ilustrar as mudanças em configurar e habilitar segurança utilizando Spring Boot 3x com JWT.
🔔 Atenção
Grande parte das configurações e ilustrações já foram abordadas no tutoria JWT2x onde agora iremos pontuar as modificações necessárias para a migração do Spring Boot 2x para o Spring Boot 3x.
Grande parte das configurações e ilustrações já foram abordadas no tutoria JWT2x onde agora iremos pontuar as modificações necessárias para a migração do Spring Boot 2x para o Spring Boot 3x.
pom.xml
Revisa abaixo as versões das dependências já existentes no projeto ou adiciona conforme código abaixo:
<!-- Spring Boot 3x -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<!-- JWT compatível -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.1</version>
<scope>runtime</scope>
</dependency>
<!-- API do Swagger -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
<!-- Interface Gráfica -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version>
</dependency>
chave token
Para garantir a segurança do JWT gerado é recomendado gerar uma chave privada conforme novas orientações abaixo:
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.util.Base64;
public class JwtSecretKey {
public static void main(String[] args) {
System.out.println(new String(Base64.getEncoder().encode(Keys.secretKeyFor(SignatureAlgorithm.HS512).getEncoded())));
//saida ilustrativa
//25L+x4ic5gLDyYtOsVsLf40sX54Y8SoJ4/oCXqG9p2uzlKsPRiuu8+NRnzsoOEuALfZBT7Xe3pu/d/YQ5ZEdCw==
}
}
O resultado deverá ser inserido no application.propeties
security.config.key=25L+x4ic5gLDyYtOsVsLf40sX54Y8SoJ4/oCXqG9p2uzlKsPRiuu8+NRnzsoOEuALfZBT7Xe3pu/d/YQ5ZEdCw==
web security config
Com a mudança da versão do Spring Boot 2x para 3x o algoritimo de configuração das rotas livres ou permissionadas teve alterações pontuais de classes e sintaxe conforme abaixo.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
private static final String[] SWAGGER_WHITELIST = {
"/v2/api-docs/**",
"/v3/api-docs/**",
"/swagger-resources",
"/swagger-resources/**",
"/configuration/ui",
"/configuration/security",
"/swagger-ui/**",
"/webjars/**"
};
@Bean
public SecurityFilterChain securityFilterChan(HttpSecurity httpSecurity) throws Exception {
return httpSecurity.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests( authorize -> authorize
.requestMatchers(HttpMethod.POST,"/users").permitAll()
.requestMatchers( SWAGGER_WHITELIST).permitAll()
.requestMatchers(HttpMethod.POST,"/login").permitAll()
.requestMatchers(HttpMethod.GET,"/users").hasAnyRole("USERS","MANAGERS")
.requestMatchers("/managers").hasAnyRole("MANAGERS")
.anyRequest().authenticated()
).addFilterAfter(new JWTFilter(), UsernamePasswordAuthenticationFilter.class)
.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception{
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}