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

Autorização usando perfis de acesso

Como seria limitar o acesso a recursos por perfil (exemplo: "administrador" só acessa o método DELETE de tópicos)?

Obrigado.

4 respostas
solução!

Oi Bruno,

É possível filtrar uma URL e/ou o método HTTP:

.antMatchers(HttpMethod.DELETE, "/topicos/*").hasRole("MODERADOR")

Isso será apresentado no 3º curso de Spring Boot aqui da Alura.

Bons estudos!

Obrigado, Rodrigo!

Fiz o exemplo acima, mas não funcionou o hasRole(), apesar da autenticação estar funcionando corretamente.

Porém, eu mapeei minhas entities JPA de uma forma um pouco diferente do curso: não inclui diretamente, nas entities, as classes do Spring (UserDetails e GrantedAuthority), mas criei outras classes que estendem das classes Spring decorando as entidades JPA, conforme abaixo:

public class UserDecorator implements UserDetails {
    private User user; //Entidade JPA

    public UserDecorator(User user) {
        this.user = user;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.user.getRoles().stream()
                .map(UserRoleDecorator::new)
                .collect(Collectors.toSet());
    }

    @Override
    public String getPassword() {
        return user.getPassword();
    }
    (...)

E, abaixo, a classe que decora as roles ...

public class UserRoleDecorator implements GrantedAuthority {
    //Classe associativa JPA (n x n) com as PKs de User e de Role
    private UserRole userRole; 

    public UserRoleDecorator(UserRole userRole) {
        this.userRole = userRole;
    }

    @Override
    public String getAuthority() {
        return userRole.getRole().getRole();
    }
    (...)

Na classe SecurityConfigurations, fiz o mapeamento:

@Configuration
@EnableWebSecurity
public class SecurityConfigurations extends WebSecurityConfigurerAdapter {
    (...)
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers(HttpMethod.GET, "/actuator/**").hasRole("Administrator")
            .anyRequest().authenticated()
            .and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and().addFilterBefore(...
    }
    (...)

Oi Bruno,

Verifique se seu banco de dados está com as tabelas de role e user_role(tabela de join) populadas corretamente.

Na tabela de role deve ter um registro com nome ROLE_ADMINISTRADOR, e na configuração de segurança deve estar em maiusculo:

.hasRole("ADMINISTRADOR")

Ahhh garoto! Funcionou! No banco eu havia cadastrado como "Adminsitrador".

Muito obrigado!