Permissions Spring Security

1

I'm having problems with user permissions using Spring Security. Signing the user assigns him the permission that is due to him, however when accessing the system the option in the menu that the user would have access does not appear.

Here's 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 DAO Class

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

NMFORMULARIO would be the name of my ROLE . When the user logs in to the system I get the user's data and then I get all the permissions that this user has access to.

By debugging the system the SearchPermissions () method is correctly picking up the permission that the user has.

InmyJSPHeaderIamleavingthemenu(specificallytheaccessthatthisroleallows):

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

To build this rule I used an AlgaWorks class as a base, but they used spring bot. But the way I rode it is very much like what they were teaching, but it is not working. When I access my application this menu item is not available to the user. This application I'm creating is my CBT project and this question of attributions of each user would be one of the fundamentals of my application and I can not make that access rule work. And I also did not want all registered users on the system to have access to everything in the application.

I would like to know if there is anything wrong with recognizing the user's permission.

If you can contribute, I would appreciate it a lot, this is just missing to complete my project

    
asked by anonymous 07.11.2018 / 18:30

1 answer

0

I've wasted so much time trying to solve this problem. I hope it's the same as I did.

Next, you have two options:

1st - Tell Spring to ignore the prefix ROLE _.

@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: link

2 ° - Add ROLE_ as a prefix to your permissions.

public static final String ROLE_PREFIX = "ROLE_";

public String getRole() {
    return ROLE_PREFIX + this.nomePermissao;
}
    
08.11.2018 / 11:04