Oi! estou tentando lançar uma exceção para quando o usuário tenta acessar uma rota que não é permitida para o tipo de ROLE dele.
Exemplo: /cursos (POST, PUT e DELETE) só podem ser executados pelos usuários que tenham um ROLE_PROFESSOR
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception{
return http.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> {
auth.requestMatchers(HttpMethod.POST, "/usuarios/**").permitAll();
auth.requestMatchers("/usuarios/**").authenticated();
auth.requestMatchers(HttpMethod.POST, "/cursos").hasRole("PROFESSOR");
auth.requestMatchers(HttpMethod.PUT, "/cursos").hasRole("PROFESSOR");
auth.requestMatchers(HttpMethod.DELETE, "/cursos").hasRole("PROFESSOR");
auth.anyRequest().authenticated();
})
.addFilterBefore(this.securityFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
@Service
public class CursoService {
@Autowired
private CursoRepository cursoRepository;
@Autowired
private ValidadorRegistroCurso validadorRegistroCurso;
@Autowired
private ValidadorRegistroFeitoPorProfessor registroFeitoPorProfessor;
public CursoDadosDetalhados registrar(CursoRegistro cursoRegistro, Usuario usuario){
this.registroFeitoPorProfessor.validar(usuario);
this.validadorRegistroCurso.validar(cursoRegistro);
Curso curso = new Curso(cursoRegistro);
var cursoSalvo = this.cursoRepository.save(curso);
return new CursoDadosDetalhados(cursoSalvo);
}
public CursoDadosDetalhados buscar(Long id){
var curso = this.cursoRepository.getReferenceById(id);
return new CursoDadosDetalhados(curso);
}
}
@Component
public class ValidadorRegistroFeitoPorProfessor {
public void validar(Usuario usuario){
boolean possuiPerfilProfessor = usuario.getAuthorities()
.stream()
.map(GrantedAuthority::getAuthority)
.anyMatch(auth -> auth.equals("ROLE_" + Perfil.PROFESSOR.name()));
if (!possuiPerfilProfessor){
throw new AccessDeniedException("Somente usuários com perfil PROFESSOR podem realizar ações para curso.");
}
}
}
quando tento fazer uma requisição com um token de aluno, ele não permite, mas somente lança um body vazio e o http status 403.
@PostMapping
public ResponseEntity registrar(@RequestBody @Valid CursoRegistro cursoRegistro, UriComponentsBuilder uriBuilder, Authentication auth){
var usuario = (Usuario) auth.getPrincipal();
var curso = this.cursoService.registrar(cursoRegistro, usuario);
var uri = uriBuilder
.path("/cursos/{id}")
.buildAndExpand(curso.id())
.toUri();
return ResponseEntity.created(uri).body(curso);
}