Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Controle de Acesso por URL

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,

1 resposta
solução!

Olá Lucas, tudo bem?

Muito obrigada por compartilhar sua solução com a gente. É sempre enriquecedor buscar conhecimento e encontrar maneiras de lidar com os desafios que surgem durante o processo de desenvolvimento.

Pelo que compreendi, você desenvolveu uma classe chamada UsuarioRole, que é uma enumeração responsável por definir os diferentes perfis de usuário. Em seguida, adicionou o atributo "role" à classe Usuario, utilizando a anotação @Enumerated(EnumType.STRING) para realizar o mapeamento dessa enumeração no banco de dados. Além disso, realizou uma modificação na tabela "usuarios", acrescentando a coluna "role", e implementou a lógica no método getAuthorities() para retornar as autoridades específicas do Spring Security, de acordo com o perfil do usuário. Por fim, você também incluiu as permissões no método securityFilterChain, de forma a permitir que as requisições DELETE para as URLs "/medicos/" e "/pacientes/" sejam processadas apenas por um administrador.

Parabéns, você está seguindo o caminho correto! Sua solução é uma abordagem válida para controlar o acesso por URL, levando em consideração os perfis dos usuários.

Um abraço e bons estudos.