Skip to content

Commit

Permalink
feat: configuração JWT e Filtros
Browse files Browse the repository at this point in the history
  • Loading branch information
wallanpsantos committed Dec 7, 2023
1 parent 7352bf0 commit 0874909
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
52 changes: 52 additions & 0 deletions src/main/java/com/jwtauthcruddemo/configs/JWTAuthFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.jwtauthcruddemo.configs;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Objects;

/***
* Classe de configuração HTTP para interceptar
* as solicitações recebidas e validar o JWT
*/
public class JWTAuthFilter extends OncePerRequestFilter {

private final LoginAuthProvider loginAuthProvider;

public JWTAuthFilter(LoginAuthProvider loginAuthProvider) {
this.loginAuthProvider = loginAuthProvider;
}

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {

// Verificar se existe um cabeçalho de autorização
String header = request.getHeader(HttpHeaders.AUTHORIZATION);

// Portador
if (Objects.nonNull(header)) validateAndSetAuthentication(header);

// Continue a cadeia de filtros
filterChain.doFilter(request, response);
}

private void validateAndSetAuthentication(String header) {
String[] authElements = header.split(" ");
if (authElements.length == 2 && "Bearer".equals(authElements[0])) {
try {
SecurityContextHolder.getContext().setAuthentication(loginAuthProvider.validateToken(authElements[1]));
} catch (RuntimeException ex) {
SecurityContextHolder.clearContext();
throw ex;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class LoginAuthProvider {

private static final int TIME_TO_EXPIRED_TOKEN = 1; // 1 Hour

@Value("{security.jwt.token.secret-key:secret-key}")
@Value("${security.jwt.token.secret-key:secret-key}")
private String secretKey;

@PostConstruct
Expand All @@ -33,15 +33,13 @@ protected void init() {
public String createToken(UserDto userDto) {
var validity = Date.from(Instant.now().plus(TIME_TO_EXPIRED_TOKEN, ChronoUnit.HOURS));


return JWT.create()
.withIssuer(userDto.getLogin())
.withIssuedAt(new Date())
.withExpiresAt(validity)
.withClaim("firstName", userDto.getFirstName())
.withClaim("lastName", userDto.getLastName())
.sign(Algorithm.HMAC256(secretKey));

}

public Authentication validateToken(String token) {
Expand All @@ -56,11 +54,13 @@ public Authentication validateToken(String token) {
return new UsernamePasswordAuthenticationToken(userDto, null, Collections.emptyList());
}

/* Usando as informações do JWT para criar um usuario DTO */
private static UserDto getUserDtoFromDecodedJWT(DecodedJWT decodedJWT) {
var userDto = new UserDto();
userDto.setLogin(decodedJWT.getIssuer());
userDto.setFirstName(decodedJWT.getClaim("firstName").asString());
userDto.setLastName(decodedJWT.getClaim("lastName").asString());
return userDto;
}

}
9 changes: 9 additions & 0 deletions src/main/java/com/jwtauthcruddemo/configs/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@
import org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

private final LoginAuthProvider loginAuthProvider;

public SecurityConfig(LoginAuthProvider loginAuthProvider) {
this.loginAuthProvider = loginAuthProvider;
}

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf(AbstractHttpConfigurer::disable)
// Filtro antes do filtro de autenticação básico, porque o JWTAuthFilter desejo que seja primeiro filtro.
.addFilterBefore(new JWTAuthFilter(loginAuthProvider), BasicAuthenticationFilter.class)
.sessionManagement(SecurityConfig::configSessionManagement)
.authorizeHttpRequests(SecurityConfig::configAuthorizeHttpRequests);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.jwtauthcruddemo.controllers;

import com.jwtauthcruddemo.configs.LoginAuthProvider;
import com.jwtauthcruddemo.dtos.input.CredentialsDto;
import com.jwtauthcruddemo.dtos.input.SignUpDto;
import com.jwtauthcruddemo.dtos.output.UserDto;
Expand All @@ -17,20 +18,24 @@
public class AuthController {

private final UserService userService;
private final LoginAuthProvider loginAuthProvider;

public AuthController(UserService userService) {
public AuthController(UserService userService, LoginAuthProvider loginAuthProvider) {
this.userService = userService;
this.loginAuthProvider = loginAuthProvider;
}

@PostMapping("/login")
public ResponseEntity<UserDto> login(@RequestBody CredentialsDto credentialsDto) {
UserDto userDto = userService.login(credentialsDto);
userDto.setToken(loginAuthProvider.createToken(userDto));
return ResponseEntity.ok(userDto);
}

@PostMapping("/register")
public ResponseEntity<UserDto> register(@RequestBody SignUpDto signUpDto) {
UserDto userDto = userService.register(signUpDto);
userDto.setToken(loginAuthProvider.createToken(userDto));
return ResponseEntity.created(URI.create("/users/" + userDto.getId())).body(userDto);
}
}

0 comments on commit 0874909

Please sign in to comment.