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

Login e cadastro de usuario sem usar Roles

Boa tarde.

Gostaria de saber como posso implementar o Login do Spring, sem a necessidade de usar as roles, pois no meu sistema nao existe nenhum funcionalidade, que seja restrita por permissões, a única coisa é que ao finalizar a compra é verificado se o usuario está logado, então acredito que não preciso de uma role, até porque meu usuário vai se cadastra através de um form nesse caso eu teria que ter um roleDao ? para persistir no banco quando for persistir o usuário, então nesse caso não vejo utilidade de usar isso, mas acho q não posso simplesmente tirar pois, pois o usuarioque implementa UserDetails espera receber um objeto do tipo getAuthorities que são as roles.

como poderia usar essa parte de login se usar as roles?

obrigado.

13 respostas

Olá Gabriel,

Caso voce ainda esteja apenas estudando, sugiro continuar utilizando as roles. Assuma que ao cadastrar um usuário ele recaba a role 'USUARIO' e na configuração de rotas sempre permita para 'USUARIO', assim voce não vai ter problemas.

Caso voce realmente queira retirar a role, coloque aqui os códigos relacionados para que possamos te auxiliar nas alterações.

Sobre o RoleDAO:

Não, a Role e um atributo de usuario, então voce vai cadastrar ele atravez do proprio UsuarioDAO.

Voce voce altera o metodo de cadastrar o Usuário para: - Recebe o usuário que veio do Form - Seta a role 'USUARIO' nele - Salva o usuário

Ola rafael.

ok vou continuar com a Role, alterei o meu metodo de inserção de usuario, para setar a role. mas agora estou com erro

meu metodo:

@RequestMapping(method = RequestMethod.POST)
    public ModelAndView add(Usuario usuario, Endereco endereco){

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(usuario.getSenha());
        usuario.setSenha(encode);

        ArrayList<Role> list = new ArrayList<Role>();
        Role role = new Role();
        role.setNome("ROLE_USUARIO");
        list.add(role);

        usuario.setRoles(list);
        Usuario usuarioCadastrado = dao.addUsuario(usuario);

        endereco.setUsuario(usuarioCadastrado);
        eDao.addEndereco(endereco);

        return new ModelAndView("rprvidros");

    }

segue o erro:

Cannot add or update a child row: a foreign key constraint fails (`rprvidros`.`usuario_role`, CONSTRAINT `FK_jnmoadyberbn5oyaybe8dxskj` FOREIGN KEY (`roles_nome`) REFERENCES `role` (`nome`))

pelo jeito ele nao esta inserindo pela chave estrangeira.

Como o cardinalidade é @OneToMany ele cria outra tabela, usuario_role, aparentemente ele nao esta inserindo nada nessa tabela, ele fala da role_nome, mas eu estou passando isso no metodo:

    role.setNome("ROLE_USUARIO");

obrigado.

Desculpe, eu não lembrava como era o modelo dessa entidade.

Voce pode como é o mapeamento das entidade aqui? Ele esta reclamando que esta faltando cadastrar o relacionamento.

Voce poderia chamar o DAO dela e cadastrar esse relacionamento.

Eu tenho no meu GitHub um projeto que utiliza uma forma simples de role: https://github.com/rafaelvicio/eNoticias/tree/master/src/br/com/esportsclub

Vale a pena voce dar uma olhada.

Rafael, eu mudei o relacionamento das minhas entidades para não criar outra tabela fiz da seguinte forma,

classe Usuario:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "nome", targetEntity = Role.class)
    private List<Role> roles = new ArrayList<Role>();

classe Role:

@ManyToOne
    @JoinColumn(name="usuario_id")
    private Usuario usuario;

acabei fazendo o RoleDao, ele até insere mas acredito que minha logica esta errada, quando eu persisto o Usuario, logo em seguida utilizo o metodo setUsuario da classe role ele inseri normal, mas ai vem o erro, como a role vai ser fixa com o valor: "ROLE_USUARIO" ele não vai inserir duas vezes a coluna com duas chaves primarias iguais causando o erro:

Duplicate entry 'ROLE_USUARIO' for key 'PRIMARY'

meu metodo AddUsuario:

@RequestMapping(method = RequestMethod.POST)
    public ModelAndView add(Usuario usuario, Endereco endereco){

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String encode = passwordEncoder.encode(usuario.getSenha());
        usuario.setSenha(encode);

        Role role = new Role();
        role.setNome("ROLE_USUARIO");


        Usuario usuarioCadastrado = dao.addUsuario(usuario);

        role.setUsuario(usuarioCadastrado);
        endereco.setUsuario(usuarioCadastrado);
        eDao.addEndereco(endereco);
        rDao.addRole(role);
        return new ModelAndView("rprvidros");

    }

acho q vou ter q desfazer isso.

Acho que não precisa de um relacionamento para isso. Olha meu exemplote mandei agora a pouco.

Eu crio um atributo role no modelo de ususario.

Claro que isso e pra deixar da forma mais simples possível, que tambem seria o seu caso. Se fosse varais roles, ai faria sentido ter uma associativa.

Rafael voltei para o que estava antes, desculpe não vi sua mensagem com seu código,eu dei uma olhada no seu código, realmente esta simples, gostaria de usar desse mesmo jeito, mas no seu caso vc usa uma String de role, e seu usuario pelo o que vi não implementa UserDetails e não tem o método :

@Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.roles;
    }

esse método espera receber uma Collection e não umaString, como poderia fazer ?

Outra coisa que voce disse: Voce poderia chamar o DAO dela e cadastrar esse relacionamento.

mas no curso não é feito esse Dao, o instrutor cadastra o usario na mão no BD, então teria que criar esse dao correto?

Uma Collection pode ser uma String.

Eu estava me referindo ao DAO de Roles, mas como você não vai user o relacionalmente, não e preciso.

Sim, voce teria que fazer uma DAO pra Usuário, se voce quiser fazer um formulario para cadastro de usuario no caso.

Ok Rafael acredito que entendi o que vc disse, a role é apenas mais uma coluna na minha tabela usuario seria isso?

quanto ao DAO do usuario eu ja tenho ele tanto que esse metodo que lhe mandei varias vezes alterado ele recebe de um FORM um objeto usuario e outro endereco e insere no banco de dados, eu desfiz o relacionamento coloquei apenas como uma String, cadastrei o Usuario, mas como ja acontecia antes ele nao loga, me vem o erro:

Reason: Bad credentials

tem alguma informação que nao bate.

solução!

Isso, correto.

Agora acho que voce vai ter que ir la nas configurações do spring security e mudar algumas coisas para ele procurar na coluna da tabela usuário, e não mais no relacionamento como era antes.

Acho que deve ter isso la no meu projeto do GitHub.

Vou dar uma procurado Rafael mas acredito que do jeito que eu configurei ele não verifica isso,

.antMatchers("/rprvidros**").permitAll()

eu não uso o hasRole() acredito que ele não deveria verificar isso, mas vou dar uma olhada no seu código.