8
respostas

Aplicação Multi-Empresa

olá pessoal, bom dia.....

Gostaria de pedir uma dica de como fazer um Login Multi-Empresa. Algum material para consulta, pesquisa...

Eu já estou cadastrando as informações de Empresa e Filial no Usuario do Sistema.

Mas gostaria de já no Login o USUARIO escolher também a EMPRESA ou FILIAL a qual ele foi cadastrado, e não somente USERNAME E PASSWORD.

Por que isso? Por que quero vincular todos os movimentos que o USUARIO fizer no sistema a uma Local específico.

Exemplo: Ao cadastrar um cliente, a qual Empresa ou Filial ele pertence.

Favor, me ajude com isso....pelo menos com dicas de como fazer....

obrigado...

8 respostas

Oi Fagner, eu acho que entendi o problema. Só uma pergunta, se as informações já estão associadas com o usuário, pq vc não carrega elas quando ele fizer o login com o login e senha? Elas vão estar na sessão e aí, vc pode fazer esse registro de informações em função delas. Se isso não for suficiente, vc pode testar o seguinte: existe uma interface no SpringSecurity chamada de AuthenticationProvider, ela funciona como uma versão mais genérica do UserDetailsService. Agora, na classe de configuração de segurança, você teria algo assim:


    @Autowired
    private List<AuthenticationProvider> authenticationProviders;

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        for (AuthenticationProvider provider : authenticationProviders) {
            auth.authenticationProvider(provider);
        }
        // super.configure(auth);
    }

Acho que isso aí pode dar uma base para você.. Só que de novo, eu acho bem mais complicado e, pelo que vc descreveu, não parece ser necessário.

olá Alberto,

Vou te explicar o que estou pensando...

Se eu cadastrar acesso a um Usuario com a seguinte hierarquia: Empresa: Calçados SA Filiais: 1 - Calçados Jundiai 2 - Calçados Campinas

Dessa forma quando eu logar no sistema eu terei os dados das duas Filiais ao mesmo tempos na session do USUARIO.

Agora algo que eu não sei como fazer.....

Ao cadastrar um CLIENTE em qual dessas Filiais o cliente vai pertencer ?

Digo isso, por que, o usuario do sistema não vai escolher onde ele deve inserir(Filial 01 ou Filial 02) o cliente, essas informações devem vir da session do usuario....

Mas como eu vou conseguir isso se o Usuario está com as duas Filiais na session?

Uma alternativa seria ter dois logins para um mesmo usuario: Cadastrar usuario para a Filial 01. Outro Usuario para Filial 02

Ou o Usuaio escolher a Filial que ele vai cadastrar.

Alberto, o que acha?

obrigado,

Agora eu entendi, ele tem que dizer por qual filial está realizando o login. Vai com a solução do AuthenticationProvider mesmo. Você poderia até usar um UserDetailService também... Como elas são classes normais, você pode receber injetado o request e pegar o parâmetro escolhido pelo usuário no momento do login. O SpringSecurity não tem um jeito muito claro de realizar um login customizado, por isso que estou te dando este caminho.

Então, desculpe perguntar isso ...mais.....realmente não está muito claro pra mim....

vamos lá....os passos seriam assim?

No form do Login eu vou informa um input select com as Filiais cadastradas....

E depois onde, em qual método eu faço essas verificações?

A minha configuração está conforme o curso Spring MVC II...

seria no /login ?

olá Alberto,

Pesquisando achei a classe abaixo para um AuthenticationProvider, conforme sua sugestão...

Mas eu ainda falta comparar o parâmetro Filial 01 informado na tela de Login, com o user.getId_filial() cadastrado.

Eu vi aqui que o @AuthenticationPrincipal Usuario usuarioLogado tem todos os dados da session do Usuario....

Como eu faria algo parecido com: usuarioLogado.SetIdfilial(3);

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

        @Autowired
        private UsuarioDao userService;

        @SuppressWarnings("unused")
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {

            String username = authentication.getName();
            String password = (String) authentication.getCredentials();

            Usuario user = userService.loadUserByUsername(username);

            System.out.println(" user.getId_filial() é : " +  user.getId_filial());


            if (user == null) {
                throw new BadCredentialsException("Username not found.");
            }

            if (!password.equals(user.getPassword())) {
                throw new BadCredentialsException("Wrong password.");
            }

            Collection<? extends GrantedAuthority> authorities = user.getAuthorities();

            return new UsernamePasswordAuthenticationToken(username, password, authorities);
        }

        @Override
        public boolean supports(Class<?> arg0) {
            return true;
        }


}

Esse método loadUserByUsername(String email), ele não aceita mais parâmetros para eu comparar....

@Repository
@Service
@Transactional
public class UsuarioDao implements UserDetailsService {

    @PersistenceContext
    private EntityManager manager;

    public Usuario loadUserByUsername(String email){
    List<Usuario> usuarios = manager.createQuery("select u from Usuario u where lower(u.email) = :p_email ", Usuario.class)
                                    .setParameter("p_email", email.toLowerCase())
                                    .getResultList();
        if(usuarios.isEmpty()){
            throw new UsernameNotFoundException("Usuario " +  email + " não foi encontrado!");
        }

        System.out.println(" usuarios.get(0) " + usuarios.get(0).getEmail());

        return usuarios.get(0);
    }

No provider, vc pode receber injetado um HttpServletRequest e pegar o parâmetro a partir dele, por exemplo. O seu UsuarioDao não vai mais, necessariamente, precisar implementar a interface do Spring, então você pode ter um método que recebe quantos argumentos vc quiser.

Ele não aceita eu injetar, dá erro de Null pointer....

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

         @Autowired
         private HttpServletRequest request;