Permissions Spring Security

Asked

Viewed 738 times

2

I’m having trouble with the user permissions using Spring Security. I registered the user assigns to him the permission due to him, but when accessing the system the option in the menu that the user would have access does not appear.

Follow how Spring Security is configured on my system:

@Configuration
@EnableWebSecurity

public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    @Autowired
    IUsuarioDAO usuarioDAO; 

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(usuarioDAO)
            .passwordEncoder(new BCryptPasswordEncoder());
    }   

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
        .antMatchers("/vendas/cadastro-vendas").hasAnyRole("VENDAS_MERCADO")
        .anyRequest().authenticated()
        .and().formLogin().loginPage("/index").permitAll()
        .failureUrl("/index?error=true").defaultSuccessUrl("/home", true).permitAll()
        .and().rememberMe().userDetailsService(usuarioDAO)
        .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
    }   
}

My User Entity:

package br.com.mercadinhojt.mercado.models;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class UsuarioDetails implements UserDetails{

    private static final long serialVersionUID = 1L;

    private String nome;
    private String login;
    private String senha;
    private boolean ativo;
    private Collection<GrantedAuthority> permissoes = new ArrayList<>();

    public UsuarioDetails(String nome, String login, String senha, boolean ativo) {
        this.nome = nome;
        this.login = login;
        this.senha = senha;
        this.ativo = ativo;
    }

    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;
    }

    @Override
    public Collection<GrantedAuthority> getAuthorities() {
        // TODO Auto-generated method stub
        return permissoes;
    }

    @Override
    public String getPassword() {
        // TODO Auto-generated method stub
        return this.senha;
    }

    @Override
    public String getUsername() {
        // TODO Auto-generated method stub
        return this.login;
    }

    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public boolean isEnabled() {
        // TODO Auto-generated method stub
        return this.ativo;
    }

}

My Class DAO

public class UsuarioDAOImpl implements IUsuarioDAO, UserDetailsService{

    private static final Logger logger = Logger.getLogger(UsuarioDetails.class.getSimpleName());


    private JdbcTemplate jdbcTemplate;  
    private Connection connection;
    private CallableStatement cs;
    private ResultSet rs;

    @Autowired
    public UsuarioDAOImpl(DataSource dataSource) {
        jdbcTemplate = new JdbcTemplate(dataSource);
    }   


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UsuarioDetails userDetails = null;
        try {           
            connection = jdbcTemplate.getDataSource().getConnection();

            userDetails = buscarUsuario(connection, username);

            Collection<GrantedAuthority> permissoesPorUsuario = buscarPermissoes(connection,username);

            userDetails.getAuthorities().addAll(permissoesPorUsuario);          

            return userDetails;

        } catch (UsernameNotFoundException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }finally{
            try {
                connection.close();
                cs.close();
                rs.close();     
            } catch (SQLException e) {
                e.printStackTrace();
            }               
        }       
        return userDetails;
    }

    public UsuarioDetails buscarUsuario(Connection connection, String login) throws SQLException {
        cs = this.connection.prepareCall("{call MEJT_SP_SEL_USUARIOS(?,?)}");
        cs.setString("MODO", "BUSCAR_USUARIO");
        cs.setString("LOGIN_USER", login);

        rs = cs.executeQuery();

        String nome = null;
        String senha = null;
        boolean ativo = false;

        while(rs.next()){               
            nome = rs.getString("NOME");
            senha  = rs.getString("SENHA");
            ativo = rs.getBoolean("ATIVO");             
        }

        rs.close();
        cs.close();

        return new UsuarioDetails(nome, login, senha, ativo);
    }

    public Collection<GrantedAuthority> buscarPermissoes(Connection connection, String login) throws SQLException {
        List<GrantedAuthority> permissoes = new ArrayList<>();

        cs = this.connection.prepareCall("{call MEJT_SP_SEL_USUARIOS(?,?)}");
        cs.setString("MODO", "ACESSAR_APLICACAO");
        cs.setString("LOGIN_USER", login);

        rs = cs.executeQuery();     

        while (rs.next()) {
            permissoes.add(new SimpleGrantedAuthority(rs.getString("NMFORMULARIO")));
        }

        rs.close();
        cs.close();

        return permissoes;
    }
}

In the case NUMBER would be the name of my ROLE. When the user logs into the system I take the User data and then I take all the permissions that this user has access to.

Debugging the system the method search for refugees() is correctly picking up the permission the user has.

inserir a descrição da imagem aqui

In my JSP Header I am leaving the menu this way (Specifically the access that this scroll allows):

<sec:authorize access="hasAnyRole('VENDAS_MERCADO')">
    <li class="nav-item">
      <a class="nav-link" href="${s:mvcUrl('VC#vendasCaixa').build()}">Caixa</a>
    </li>
</sec:authorize>

To set up this rule I used as a basis a Algaworks class, but they used spring bot. But the way I rode it is very similar to what they were teaching, but it’s not working. When accessing my application this menu item is not available to the user. This application I’m creating is my TCC project and this question of assignments of each user would be one of the foundations of my application and I’m not able to make this access rule work. And also did not want all registered users in the system have access to everything from the application.

I wonder if there is something wrong in the time to recognize the permission that the user has.

If you can contribute I would appreciate it very much, only this is missing to complete my project

1 answer

1


I’ve spent a lot of time trying to solve this problem. I hope it’s the same as what I’ve been through.

Next, you have two options:

1° - Tell Spring to ignore ROLE prefix_.

@Override
public void configure(WebSecurity web) throws Exception {
    web.expressionHandler(new DefaultWebSecurityExpressionHandler() {
        @Override
        protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, FilterInvocation fi) {
            WebSecurityExpressionRoot root = (WebSecurityExpressionRoot) super.createSecurityExpressionRoot(authentication, fi);
            root.setDefaultRolePrefix(""); //remove the prefix ROLE_
            return root;
        }
    });
}

Credits: https://stackoverflow.com/questions/38134121/how-do-i-remove-the-role-prefix-from-spring-security-with-javaconfig

2° - AddROLE_ as prefix in your permissions.

public static final String ROLE_PREFIX = "ROLE_";

public String getRole() {
    return ROLE_PREFIX + this.nomePermissao;
}
  • 1

    Thank you very much!! That was the problem because of the "ROLE_" that did not have. I added this part in the name of the permission that is in the database and it worked. Sensational guy, it was worth even helped a lot.!!!!

  • Oops, ball show! Then marks the question as correct. Thanks, hug!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.