JAAS Custom Login Module

Olá senhores, estou em um projeto onde já existe o JAAS configurado e funcionando na sua implementação padrão. Está implementado autenticação e autorização.

Porem como a vida não é fácil para todos, alem de um usuário e senha, a autenticação precisaria ter mais um atributo.

Hoje, eu tenho a entidade Usuario e Grupo(Roles). Nas “Roles” estou usando para perfils… tipo Administrador, Usuário, Gerente…etc…

Esse sistema, faz a gestão de varias empresas, e agora preciso colocar o nome da empresa na autenticação.

Relacionei Usuario e empresas como muitos para muitos e ok, já criei as telas, já está tudo cadastro no banco.

Até hoje, se o usuário passou na autenticação de usuário e senha, ele consegue logar no sistema e tambem consegue visualizar todos os dados de todas as empresas cadastradas no sistema.

O processo de mudança no sistema para que ele possa somente visualizar/salvar/alterar dados só das empresas que ele está cadastrado para trabalhar é lento, pois o sistema é grande.
Embora consigamos fazer essa mudança sem alterar o login, demanda muito tempo, e se eu conseguir implementar isso no login, eu já ganho tempo.

Minha tela de login deverá ter um select onde a pessoa escolhe a empresa e o digite seu usuário e senha, e tudo precisa ser conferido, se o cara ta cadastrado na empresa, se o usuario e senha conferem.

Eu vi um post aqui de 2006 ensinando a implementar um LoginModule com o JAAS, mas fiquei na duvida se seria esse o caminho.

Para que as minhas pesquisar continuem sobre o custom LoginModule para o JAAS…antes eu gostaria só de saber do amigos se esse meu problema eu consigo contornar criando um modulo personalizado mesmo, e esse modulo tratar de ir no banco e através dele autenticar todos os dados que eu gostaria alem de usuario e senha ?

Pelo que eu li até o momento na documentação da oracle e algums posts… me parece que sim… mas isso ta me levando um tempo danado.

Alguém ja passou por isso ?? é possível mesmo ?

Sim…ja passei por isso varias vezes…
O JAAS do JEE Container prove somente 2 campos para credenciais… SENHA /LOGIN…sendo assim não tem como passar + campos.
Vc tem 2 caminhos

  1. Gambiarra - enviar os campos que precisa a mais dentro do mesmo campo de LOGIN usando algum protocolo como CAMPO=VALOR;CAMPO=VALOR; via javascript. Na implementação do seu custom jaas vc lee o protocolo e faz a autenticação.

  2. Abandonar o JAAS e fazer a autenticação e autorização manual usando servlet filters.

[quote=FernandoFranzini]Sim…ja passei por isso varias vezes…
O JAAS do JEE Container prove somente 2 campos para credenciais… SENHA /LOGIN…sendo assim não tem como passar + campos.
Vc tem 2 caminhos

  1. Gambiarra - enviar os campos que precisa a mais dentro do mesmo campo de LOGIN usando algum protocolo como CAMPO=VALOR;CAMPO=VALOR; via javascript. Na implementação do seu custom jaas vc lee o protocolo e faz a autenticação.

  2. Abandonar o JAAS e fazer a autenticação e autorização manual usando servlet filters.[/quote]

Poiseh… não sei o que será mais doloroso se é abandonar o JAAS ou alterar todo o sistema pra liberar funcionalidades so para determinadas empresas que o usuário tenha cadastrado como permissão. Fiquei sem saída… todas as opções darão muito trabalho…

Se vc ja tem jaas custom fica facil…é só fazer um campo HIDE no html e um javascrip para enviar varios campos no mesmo input…

Eu abandonei JAAS…hoje temos um framework proprietário bem parecido com SpringSecurity fazendo esse serviço para nos…

Entendi… ja trabalhei com SpringSecurity, uso ele em outros sistema que desenvolvi… porem como primeira experiência passei a utilizar o JAAS… e ate o momento estava atendendo até surgirem esse desafios hehe…

mas me tira uma dúvida… o que vc fez seria extenção do SpringSecurity ? ou criou completamente independente ?

Ainda estou pesquisando se tem como eu criar um callback especifico… e um handler para ele… e não utilizar só o NamedCallback e o PasswordCallback… posso estar viajando aqui… mas a esperança é a ultima que morre hehe… mas tambem não vou correr muito com isso não… vou só fazer mais umas pesquisada em cima disso… se complicar muito… vou apela pro javascript…

uma coisa que tem o SpringScecuryt é só permitir login dos usuarios que extiverem com o campo boolean enabled como true… até o momento não consegui implementar isso no JAAS… se existir um usuário… ele ja pode logar… não consigo desabilita-lo no momento sem exclui-lo

achei esse trecho TextInputCallback can be used to access the data users enter into any additional fields on a login form nesse link http://docs.oracle.com/cd/E24329_01/web.1211/e24484/concepts.htm… porem a documentação é para o WebLogic… até onde vai funciona no Glassfish… resta saber…

abraço.

completamente independente…

Eu acredito que seja uma extensão proprietária do weblogic…vc precisa ler ai para ver…as vezes é um recurso do JAAS mesmo…

Pare e respire ! Já achou o cabelo no ovo que está procurando ?

Não invente problemas, apresente soluções.

Entendi que o cenário atual é 1 usuario para n perfis e n empresas.

A solução 1 e mais fácil e aproveita TUDO já implementado que é criar perfis (ROLE) de cada empresa. Ex.: ROLE_EMPRESA_1, ROLE_EMPRESA_2.
Atribuir os usuários com os respectivos perfis de empresas que poderão acessar. O problema que essa atribuição não é dinâmica.

A solução 2 também precisa de criar perfis (ROLE) de cada empresa e depende de mais uma implementação.
Após a autenticação, direcionar a uma tela para que possa selecionar a empresa (COMBO BOX, MENU DROP DOWN, COMBO LIST), sendo estes os perfis de empresa. Alterar a lista de ROLES do UserPrincipal adicionando a ROLE da empresa e direcionar para a tela inicial do sistema.

O sistema é web ta pessoal… falo só por causa que as roles estão diretamente ligadas as urls … paths do sistema que cada role permite… hoje as minhas roles sao assim… Vendedor… só consegue acessa o que condiz com vendas… Gerente tem mais direitos… mais paths que pode acessar… e assim por diante…

Seguinte… hoje o meu cenário que necessito seria, eu vou informar para qual empresas o usuário pode ter controle… e preciso informar o grupo dele… tipo na empresaX ele é administrador… e na empresaY ele só é Vendedor.

Desculpem a minha ignorancia mas eu fiquei curioso agora com uma coisa… se eu usar uma role para cada empresa… eu precisar ir la no xml onde declaro as roles e criar uma nova e fazer a configuração dela na mão ?? e fazer deploy da aplicaçào denovo ? será que tem como jogar essas roles pro banco ?

A solução 2 é um cenário legal… após o login eu mandar o cara pra uma telinha onde que só tem as empresas onde ele está cadastrado…

PessoALL segue a evolução até o momento…

Consegui fazer um custom login module rodar numa java aplication para teste que criei. ele vai no banco… checa usuario e senha… tudo funcionando blz…

A minha aplicação é web… ou seja está configurado as roles e grupos no glassfish-web.xml e web.xml…

O meu form login está configurado para ir no managedbean para chamar o login do logincontext e consequentemente acionar o modulo custom que eu criei… até ai tudo bem… funcionando…


@Named
@SessionScoped
public class LoginBean implements Serializable {

    private String username;
    private String password;
    private String texto = "Valor que veio do ManagedBean";
    
    HttpSession session;
    HttpServletRequest request;

    public LoginBean() {
        System.setProperty("java.security.auth.login.config", "/Users/Glauter/NetBeansProjects/JAAS/src/java/jaas.config");
        
    }

    public void iniciando() {
    }

    public void login() {

         request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
         
         
        try {
            
            password = EncriptaSenha.encriptaSenha(password);
            
            LoginContext lc = new LoginContext("MasterappConfig", new TestCallbackHandler(username, password));
            lc.login();
           //Após o linha acima o usuário é checado no banco e confirmado usuario e senha... após isso e criado o  subject dentro do loginmodule com todos os principals...   

            Subject subject = lc.getSubject();
            
            //Nesse momento ele mostra no console todos os meus Principals. Significa que veio o UserPrincipal e as minhas roles
            System.out.println(subject.getPrincipals());
            
            //Aqui ele retorn nullpointerexception
            System.out.println(request.getUserPrincipal().toString());
            
        } catch (LoginException e) {
            System.out.println(e.getMessage());
        }
        
    }
    
    public void logout() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();

        try {

            request.logout();

        } catch (ServletException e) {

            context.addMessage(null, new FacesMessage("Logout failed."));
        }
    }

/getters e setters

Não sei o que estou fazendo errado… se alguem puder me mostrar !!!