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

[Bug] Error 403 Forbidden

Boa noite a todos. Tudo bem? Pode me ajudar com uma situação? Ao tentar efetuar o login, o projeto está dando erro 403 Forbidden, mesmo estando com o usuário criado na tabela. Segue classes criadas e demais evidências:

Classe Usuario

package com.jh.car.model;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Table(name="usuarios")
@Entity(name="usuarios")
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
public class Usuario implements UserDetails{	  
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String login;
        private String senha;    		
        
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getLogin() {
            return login;
        }
        public void setLogin(String login) {
            this.login = login;
        }
        public String getSenha() {
            return senha;
        }
        public void setSenha(String senha) {
            this.senha = senha;
        }
        // configurações do UserDetails
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return List.of(new SimpleGrantedAuthority("ROLE_USER"));
        }
        @Override
        public String getPassword() {
            return senha.trim();
        }
        @Override
        public String getUsername() {
            return login.trim();
        }
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }
        @Override
        public boolean isEnabled() {
            return true;
        }
}

AutenticacaoService

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.jh.car.repository.UsuarioRepository;
@Service
public class AutenticacaoService implements UserDetailsService {

    @Autowired
    private UsuarioRepository repo;	
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        return repo.findByLogin(username);
    }	
    
}

DadosAutenticacao

package com.jh.car.dto;
public record DadosAutenticacao(String login, String senha) {
}

AutenticacaoController

package com.jh.car.controller;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.jh.car.config.TokenService;
import com.jh.car.dto.DadosAutenticacao;
import com.jh.car.model.Usuario;
import lombok.AllArgsConstructor;

@RestController
@AllArgsConstructor
public class AutenticacaoController {	
      @Autowired
        private AuthenticationManager manager;	  	  
      @Autowired
      private TokenService jwtService;  
      
        @PostMapping("/login")
        public ResponseEntity efetuarLogin(@RequestBody @Valid DadosAutenticacao dados) {
            var token = new UsernamePasswordAuthenticationToken(dados.login(),dados.senha());
            var authentication = manager.authenticate(token);

            return ResponseEntity.ok(jwtService.gerarToken((Usuario) authentication.getPrincipal()));
        }	
}

UsuarioRepository

package com.jh.car.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.security.core.userdetails.UserDetails;

import com.jh.car.model.Usuario;

public interface UsuarioRepository extends JpaRepository<Usuario, Long> {

    UserDetails findByLogin(String login);

}
4 respostas

Dá uma pesquisada. Mas isso está com cara de erro de CORS. Dá uma pesquisada sobre CORS.

solução!

Oi João!

Manda aqui as suas classes Securityconfigurations e SecurityFilter. Manda também um print da sua requisição no Insomnia.

Desculpe pela demora Professor Rodrigo.

Segue a classe SecurityConfiguration abaixo:

package com.jh.car.config;

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {

        CorsConfiguration configuration = new CorsConfiguration().applyPermitDefaultValues();
        configuration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "DELETE", "OPTIONS"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    // metodo para tratar as situações de segurança
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http.csrf(csrf -> csrf.disable())
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))// habilitando no
                                                                                                    // Security a
                                                                                                    // autenticação via
                                                                                                    // STATELESS
                .build();
    }

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

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

}

Obs: Ainda nao cheguei na criação da classe SecurityFilter, estou na aula Geração de Tokens JWT.

Oi!

Nesse método:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http.csrf(csrf -> csrf.disable())
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))// habilitando no
            .build();
}

Faltou você marcar a url /login com permitAll() para que a requisição não seja bloqueada.