Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

[ERRO] Token não enviado no cabeçalho Authorization

Eu criei o projeto do vollmed tranquilo, e resolvi me desafiar criando um projeto inspirado na aula, só que como se fosse uma escola, pois bem Insira aqui a descrição dessa imagem para ajudar na acessibilidadena requisão de login após a implementação do getSubject ele fica dando erro

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeseguem as classes

TokenService

package br.com.projeto.escola.api.Infra;

import br.com.projeto.escola.api.Model.Usuarios;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

@Service
public class TokenService {

    @Value("{api.security.token.secret}")
    private String secret;

    private static final String ISSUER = "API Projeto.Escola";

    public String tokenGenerator(Usuarios usuarios){
        try {
            var algorithm = Algorithm.HMAC256(secret);
            return  JWT.create()
                    .withIssuer(ISSUER)
                    .withSubject(usuarios.getUsername())
                    .withClaim("id", usuarios.getId())
                    .withClaim("username", usuarios.getUsername())
                    .withClaim("rolesUsuarios", String.valueOf(usuarios.getRolesUsuarios()))
                    .withExpiresAt(dataExpiracao())
                    //.withExpiresAt(expirationData())
                    .sign(algorithm);
        } catch (JWTCreationException exception){
            // Invalid Signing configuration / Couldn't convert Claims.
            throw new RuntimeException("Erro ao gerar o token", exception);
        }
    }
    public String getSubject(String tokenJWT){
        try {
            var algorithm = Algorithm.HMAC256(secret);
            return JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build()
                    .verify(tokenJWT)
                    .getSubject();
        } catch (JWTVerificationException exception) {
            throw new RuntimeException("Token JWT inválido ou expirado!");
        }
    }

    private Instant dataExpiracao() {
        return LocalDateTime.now().plusHours(2).toInstant(ZoneOffset.of("-03:00"));
    }


}
SecurityFilter

package br.com.projeto.escola.api.Infra;

import br.com.projeto.escola.api.Repository.RepositorioUsuarios;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Component
public class SecurityFilter extends OncePerRequestFilter {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private RepositorioUsuarios repositorioUsuario;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        var tokenJWT = retrieveToken(request);

        if(tokenJWT != null){
            var subject = tokenService.getSubject(tokenJWT);
            var usuario = repositorioUsuario.findByUsername(subject);
            SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken
                    (usuario, null, usuario.getAuthorities()));
        }
        filterChain.doFilter(request, response);
    }

    private String retrieveToken(HttpServletRequest request) {
        var authorizationHeader = request.getHeader("Authorization");
        if(authorizationHeader != null){
            return authorizationHeader.replace("Bearer ", "").trim();
        }
        throw new ErrorHandling.ErrorInvalidStatement("Token JWT não enviado no cabeçalho Authorization");
    }

}
3 respostas
SecurityConfiguration

package br.com.projeto.escola.api.Infra;

import org.springframework.beans.factory.annotation.Autowired;
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.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration implements WebMvcConfigurer {


    @Autowired
    private SecurityFilter securityFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
        return http.csrf(csrf -> csrf.disable())
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(ahttpr -> ahttpr.requestMatchers(HttpMethod.POST, "login").permitAll())
                .authorizeHttpRequests(ahttpr -> ahttpr.requestMatchers(HttpMethod.POST, "login/criar/usuarios").permitAll())
                .authorizeHttpRequests(ahttpr -> ahttpr.requestMatchers(HttpMethod.GET, "login/listagem/usuarios").permitAll())
                .authorizeHttpRequests(ahttpr -> ahttpr.requestMatchers(HttpMethod.POST, "estudante/criado").permitAll())
                .authorizeHttpRequests(ahttpr -> ahttpr.requestMatchers(HttpMethod.GET, "estudante/listar").permitAll())
                .authorizeHttpRequests(ahttpr -> ahttpr.anyRequest().authenticated())
                .authorizeHttpRequests(ahttpr -> ahttpr.and().addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class))
                .build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception{
        return configuration.getAuthenticationManager();
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
solução!

Oi!

Na sua classe Filter:

private String retrieveToken(HttpServletRequest request) {
    var authorizationHeader = request.getHeader("Authorization");
    if(authorizationHeader != null){
        return authorizationHeader.replace("Bearer ", "").trim();
    }
    throw new ErrorHandling.ErrorInvalidStatement("Token JWT não enviado no cabeçalho Authorization");
}

Você não deve lançar exception, pois o token não deve ser sempre obrigatório. Exemplo, na requisição de login não se envia o token, pois é justamente a requisição para se obter um token ;)

Bons estudos!

Opa verdade professor, as linhas estão trocadas

return authorizationHeader.replace("Bearer ", "").trim(); } throw new ErrorHandling.ErrorInvalidStatement("Token JWT não enviado no cabeçalho Authorization"); }

corrigido obrigado !