Olá pessoal, tudo bem?
Eu fiquei com algumas dúvidas referente a bloqueio de acesso por URL, acredito ser algo de extrema importância, então para agregar aos conhecimentos fui atrás de tutoriais e cheguei em uma conclusão.
Caso tenham dúvidas, vou deixar abaixo os trechos de códigos alterados.
Obs.: Eu fiz os testes e funcionou, porém não sei se é a melhor solução.
Criei uma classe Enum chamada UsuarioRole, criei apenas dois perfis, sendo eles, administrador e o usuário padrão:
public enum UsuarioRole {
ADMIN,
USER;
}
Na classe Usuario adicionei o atributo role com a anotação @Enumerated(EnumType.STRING) para mapear o Enum como String no banco de dados:
public class Usuario implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String login;
private String senha;
@Enumerated(EnumType.STRING)
private UsuarioRole role;
Criei uma nova versão do banco de dados para adicionar uma nova coluna na tabela usuarios, como só tínhamos um cadastro na tabela usuarios, fiz o SET para alterar todos para ADMIN:
ALTER TABLE usuarios ADD role varchar(20);
UPDATE usuarios SET role = "ADMIN";
No método getAuthorities() na classe Usuario, foi verificado se o Enum é igual a ADMIN, então terá que retornar a lista de autoridades do Spring Security contendo o ROLE_ADMIN e ROLE_USER, caso contrário, somente o ROLE_USER:
@Override
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
if(this.role == UsuarioRole.ADMIN) {
return List.of(new SimpleGrantedAuthority("ROLE_ADMIN"), new SimpleGrantedAuthority("ROLE_USER"));
}
else return List.of(new SimpleGrantedAuthority("ROLE_USER"));
}
E por fim, alterado o método securityFilterChain adicionando as permissões conforme nossa regra de negócio. Eu apenas adicionei as permissões para que todas as requisições do tipo DELETE tanto para medicos/* e pacientes/* fossem processadas por um admin:
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http.csrf(csrf -> csrf.disable())
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(req -> req
.requestMatchers(HttpMethod.POST, "/login").permitAll()
.requestMatchers(HttpMethod.DELETE, "/medicos/*").hasRole("ADMIN")
.requestMatchers(HttpMethod.DELETE, "/pacientes/*").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(securityFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
Espero ter ajudado de alguma forma,
Até breve,