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

"/login" Erro 403 após o curso

Olá, mesmo após a finalização do curso, ainda não consigo logar no endpoint "/login", para efetuar o login, e captar os token. Conferi com o código do curso, mas parece estar igual, alguém poderia me ajudar? abaixo os códigos:

**AUTENTICACAOCONTROLLER

@Controller @RequestMapping("/login") public class AutenticacaoController {

@Autowired
private AuthenticationManager manager;

@Autowired
private TokenService tokenService;

@PostMapping
public ResponseEntity efetuarLogin(@RequestBody @Valid DadosAutenticacao dados){
    var authenticationToken = new UsernamePasswordAuthenticationToken(dados.login(), dados.senha());
    var authentication = manager.authenticate(authenticationToken);
    var tokenJWT = tokenService.gerarToken((Usuario) authentication.getPrincipal());

    return ResponseEntity.ok(new DadosTokenJWT(tokenJWT));
}

}

**SECURITYCONFIGURATIONS

@Configuration @EnableWebSecurity public class SecurityConfigurations {

@Autowired
private SecurityFilter securityFilter;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
     return http.csrf().disable()
             .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
             .and().authorizeHttpRequests()
             .requestMatchers(HttpMethod.POST, "/login").permitAll()
             .requestMatchers(HttpMethod.GET,"/h2-console/**").permitAll()
             .anyRequest().authenticated()
             .and().addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
             .build();
}

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

@Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

}

5 respostas

**SECURITYFILTER

@Component public class SecurityFilter extends OncePerRequestFilter {

@Autowired
private TokenService tokenService;

@Autowired
private UsuarioRepository usuarioRepository;

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    var tokenJWT = recuperarToken(request);
    if(tokenJWT != null){
        var subject = tokenService.getSubject(tokenJWT);
        var usuario = usuarioRepository.findByLogin(subject);
        var authentication = new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    filterChain.doFilter(request, response);
}

private String recuperarToken(HttpServletRequest request) {
    var authorizatonHeader = request.getHeader("Authorization");
    if (authorizatonHeader != null){
        return authorizatonHeader.replace("Bearer", "").trim();
    }
    return null;
}

}

**USUARIO

@Table(name = "usuarios") @Entity (name = "Usuario") @Getter @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(of = "id") public class Usuario implements UserDetails {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String senha;

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return List.of(new SimpleGrantedAuthority("ROLE_USER"));
}

@Override
public String getPassword() {
    return senha;
}

@Override
public String getUsername() {
    return login;
}

@Override
public boolean isAccountNonExpired() {
    return true;
}

@Override
public boolean isAccountNonLocked() {
    return true;
}

@Override
public boolean isCredentialsNonExpired() {
    return true;
}

@Override
public boolean isEnabled() {
    return true;
}

}

**USUARIOREPOSITORY

public interface UsuarioRepository extends JpaRepository<Usuario, Long> { UserDetails findByLogin(String login); }

**AUTENTICACAOSERVICE

@Service public class AutenticacaoService implements UserDetailsService {

@Autowired
private UsuarioRepository repository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    return repository.findByLogin(username);
}

}

**TOKENSERVICE

@Service public class TokenService {

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

public String gerarToken(Usuario usuario){
    try {
        var algoritmo = Algorithm.HMAC256(secret);
        return JWT.create()
                .withIssuer("API Apiapplication Itau")
                .withSubject(usuario.getLogin())
                .withExpiresAt(dataExpiracao())
                .sign(algoritmo);
    } catch (JWTCreationException exception){
        throw new RuntimeException("Erro ao gerar o Token jwt", exception);
    }
}

public String getSubject(String tokenJWT){
    try {
        var algoritmo = Algorithm.HMAC256(secret);
        return JWT.require(algoritmo)
                .withIssuer("API Apiapplication Itau")
                .build()
                .verify(tokenJWT)
                .getSubject();
    } catch (JWTVerificationException exception){
        throw new RuntimeException("Token JWT inválido ou expirado");
    }
}

// // public String getSubject(String tokenJWT){ // try{ // var algoritmo = Algorithm.HMAC256(secret); // return JWT.require(algoritmo) // .withIssuer("API Apiapplication Itau") // .build() // .verify(tokenJWT) // .getSubject(); // } catch (TokenExpiredException e) { // throw new RuntimeException("Token JWT expirado"); // } catch (SignatureVerificationException e) { // throw new RuntimeException("Assinatura do token JWT inválida"); // } catch (JWTVerificationException e){ // throw new RuntimeException("Token JWT inválido"); // } // }

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

}

solução!

Oi Lúcio tudo bem? Na classe controller utiliza a anotação @RestController no lugar no @Controller. Na classe SecurityFilter tem que ajusar return authorizationHeader.replace("Bearer", ""); para return authorizationHeader.replace("Bearer ", ""); tem um espaço ali no Bearer, isso é quando tu recupera o token. Seria bom baixar o código do git e verificar certinho se tem mais alguma coisa para arrumar.

Maravilha, agora deu certo! Muito obrigado! Agora estou lutando para fazer abrir o html do login e depois acessar a página com os cruds. Se puder ajudar - https://cursos.alura.com.br/forum/topico-pagina-de-login-e-produtos-crud-customizada-nao-acessada-274885