Topic: [Resolved] JAAS Swing Bonita EJB3

I'm developing a swing application that execute workflow actions. My .bar file was deploied in Jboss Server with Bonita, configured to use EJB3.

I want to use JAAS login in my swing application only to put the user nome in workflow actions.

How can i do it?

Re: [Resolved] JAAS Swing Bonita EJB3

Hi,

it depends on your jaas configuration. Are you using a jaas configuration provided by Bonita or your own ?
If it is your, you just need to update your login module to accept new users. If it is one from Bonita you need to add the login/pasworg in jaas-x.cfg.

Regards
Charles

Re: [Resolved] JAAS Swing Bonita EJB3

Hi,

do you succeed to do what you want?

Re: [Resolved] JAAS Swing Bonita EJB3

no, i need to authenticate in my database and do Bonita use my user in actions in workflow process

Re: [Resolved] JAAS Swing Bonita EJB3

Hi,

you need to developp your own LoginModule to access and query your db to return the user id, after you need to configure jaas on the client and server side.
More resources about jaas

HTH

Re: [Resolved] JAAS Swing Bonita EJB3

Using PlainLoginModule works correctly, just that I want to use my User registered in the database.

So, I implemented the files "LoginModule" and "CallbackHandler" and when I try to instantiate the process, the User fiza empty.

Why?

Client: Swing
    File: jaas-jboss.cfg

  Bonita {
    com.consystem.jsirc.bonita.auth.JSircLoginModule required debug=true;
    org.jboss.security.ClientLoginModule required password-stacking=useFirstPass;
  };

Server: Jboss + Bonita configured EJB3
    File: jaas-jboss.cfg
 

Bonita {
    com.consystem.jsirc.bonita.auth.JSircLoginModule required debug=true;
    org.jboss.security.ClientLoginModule required password-stacking=useFirstPass;
  };

package com.consystem.jsirc.bonita.auth;

import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class JSircLoginModule implements LoginModule {

    // estado inicial
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map sharedState;
    private Map options;

    // opção configuravel
    private boolean debug = false;

    // estado da autenticacao
    private boolean succeeded = false;
    private boolean commitSucceeded = false;

    // usuario e senha
    private String username;
    private char[] password;

    // JsircPrincipal
    private JsircPrincipal userPrincipal;

    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map<String, ?> sharedState, Map<String, ?> options) {

        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;

        // inicializa configuração de opções
        debug = "true".equalsIgnoreCase((String) options.get("debug"));

    }

    @Override
    public boolean login() throws LoginException {

        // prompt for a user name and password
        if (callbackHandler == null)
            throw new LoginException(
                    "Error: nenhum CallbackHandler disponível "
                            + "para armazenar as informações de autenticação do usuário");

        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("user name: ");
        callbacks[1] = new PasswordCallback("password: ", false);

        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            char[] tmpPassword = ((PasswordCallback) callbacks[1])
                    .getPassword();
            if (tmpPassword == null) {
                // treat a NULL password as an empty password
                tmpPassword = new char[0];
            }
            password = new char[tmpPassword.length];
            System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
            ((PasswordCallback) callbacks[1]).clearPassword();

        } catch (java.io.IOException ioe) {
            throw new LoginException(ioe.toString());
        } catch (UnsupportedCallbackException uce) {
            throw new LoginException(
                    "Erro: "
                            + uce.getCallback().toString()
                            + " não está disponível o armazenador de informações de autenticação do usuário");
        }

        // print debugging information
        if (debug) {
            System.out.println("\t\t[JSircLoginModule] "
                    + "user entered user name: " + username);
            System.out.print("\t\t[JSircLoginModule] "
                    + "user entered password: ");
            for (int i = 0; i < password.length; i++)
                System.out.print(password[i]);
            System.out.println();
        }

        // verify the username/password
        boolean usernameCorrect = false;
        boolean passwordCorrect = false;
        if (username.equals("testUser"))
            usernameCorrect = true;
        if (usernameCorrect && password.length == 12 && password[0] == 't'
                && password[1] == 'e' && password[2] == 's'
                && password[3] == 't' && password[4] == 'P'
                && password[5] == 'a' && password[6] == 's'
                && password[7] == 's' && password[8] == 'w'
                && password[9] == 'o' && password[10] == 'r'
                && password[11] == 'd') {

            // authentication succeeded!!!
            passwordCorrect = true;
            if (debug)
                System.out.println("\t\t[JSircLoginModule] "
                        + "authentication succeeded");
            succeeded = true;
            return true;
        } else {

            // authentication failed -- clean out state
            if (debug)
                System.out.println("\t\t[JSircLoginModule] "
                        + "authentication failed");
            succeeded = false;
            username = null;
            for (int i = 0; i < password.length; i++)
                password[i] = ' ';
            password = null;
            if (!usernameCorrect) {
                throw new FailedLoginException("Nome de usuário está incorreto");
            } else {
                throw new FailedLoginException("Senha incorreta");
            }
        }

    }

    @Override
    public boolean commit() throws LoginException {
        if (succeeded == false) {
            return false;
        } else {
            // add a Principal (authenticated identity)
            // to the Subject

            // assume the user we authenticated is the JsircPrincipal
            userPrincipal = new JsircPrincipal(username);
            if (!subject.getPrincipals().contains(userPrincipal))
                subject.getPrincipals().add(userPrincipal);

            if (debug) {
                System.out.println("\t\t[JSircLoginModule] "
                        + "added JsircPrincipal to Subject");
            }

            // in any case, clean out state
            username = null;
            for (int i = 0; i < password.length; i++)
                password[i] = ' ';
            password = null;

            commitSucceeded = true;
            return true;
        }

    }

    @Override
    public boolean abort() throws LoginException {
        if (succeeded == false) {
            return false;
        } else if (succeeded == true && commitSucceeded == false) {
            // login succeeded but overall authentication failed
            succeeded = false;
            username = null;
            if (password != null) {
                for (int i = 0; i < password.length; i++)
                    password[i] = ' ';
                password = null;
            }
            userPrincipal = null;
        } else {
            // overall authentication succeeded and commit succeeded,
            // but someone else's commit failed
            logout();
        }
        return true;

    }

    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(userPrincipal);
        succeeded = false;
        succeeded = commitSucceeded;
        username = null;
        if (password != null) {
            for (int i = 0; i < password.length; i++)
                password[i] = ' ';
            password = null;
        }
        userPrincipal = null;
        return true;

    }

}

package com.consystem.jsirc.bonita.auth;

import java.io.IOException;

public class JsircCallbackHandler implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof TextOutputCallback) {

                // display the message according to the specified type
                TextOutputCallback toc = (TextOutputCallback) callbacks[i];
                switch (toc.getMessageType()) {
                case TextOutputCallback.INFORMATION:
                    System.out.println(toc.getMessage());
                    break;
                case TextOutputCallback.ERROR:
                    System.out.println("ERROR: " + toc.getMessage());
                    break;
                case TextOutputCallback.WARNING:
                    System.out.println("WARNING: " + toc.getMessage());
                    break;
                default:
                    throw new IOException("Unsupported message type: "
                            + toc.getMessageType());
                }

            } else if (callbacks[i] instanceof NameCallback) {

                // prompt the user for a username
                NameCallback nc = (NameCallback) callbacks[i];

                System.err.print(nc.getPrompt());
                nc.setName("testUser");

                // System.err.flush();
                // nc
                // .setName((new BufferedReader(new InputStreamReader(
                // System.in))).readLine());

            } else if (callbacks[i] instanceof PasswordCallback) {

                // prompt the user for sensitive information
                PasswordCallback pc = (PasswordCallback) callbacks[i];
                System.err.print(pc.getPrompt());

                char[] password = { 't', 'e', 's', 't', 'P', 'a', 's', 's',
                        'w', 'o', 'r', 'd' };
                pc.setPassword(password);

                // System.err.flush();
                // pc.setPassword(readPassword(System.in));

            } else {
                throw new UnsupportedCallbackException(callbacks[i],
                        "Unrecognized Callback");
            }
        }

    }

    // Reads user password from given input stream.
    private char[] readPassword(InputStream in) throws IOException {

        char[] lineBuffer;
        char[] buf;
        int i;

        buf = lineBuffer = new char[128];

        int room = buf.length;
        int offset = 0;
        int c;

        loop: while (true) {
            switch (c = in.read()) {
            case -1:
            case '\n':
                break loop;

            case '\r':
                int c2 = in.read();
                if ((c2 != '\n') && (c2 != -1)) {
                    if (!(in instanceof PushbackInputStream)) {
                        in = new PushbackInputStream(in);
                    }
                    ((PushbackInputStream) in).unread(c2);
                } else
                    break loop;

            default:
                if (--room < 0) {
                    buf = new char[offset + 128];
                    room = buf.length - offset - 1;
                    System.arraycopy(lineBuffer, 0, buf, 0, offset);
                    Arrays.fill(lineBuffer, ' ');
                    lineBuffer = buf;
                }
                buf[offset++] = (char) c;
                break;
            }
        }

        if (offset == 0) {
            return null;
        }

        char[] ret = new char[offset];
        System.arraycopy(buf, 0, ret, 0, offset);
        Arrays.fill(buf, ' ');

        return ret;
    }

}

Re: [Resolved] JAAS Swing Bonita EJB3

Hi,

do you have any trace or log to see where is the issue ?

Re: [Resolved] JAAS Swing Bonita EJB3

This is the problem, there is no error or something abnormal.

I implemented only these two classes that showed up. Are you sure that the source code of the client SWING "JSircLoginModule" and "JsircCallbackHandler" must be equal to those placed in JBOSS?

   
You do not have any sample source code that makes the User Authentication not use the "PlainLoginModule?

Re: [Resolved] JAAS Swing Bonita EJB3

I solved the problem, I copied much of the code for "PlainLoginModule" picked only the parts of User Authentication in the configuration file JAAS



Bonita {
  com.consystem.jsirc.bonita.auth.JSircLoginModule required debug=true;
  org.jboss.security.ClientLoginModule required password-stacking=useFirstPass;
};
LoginContext loginContext = null;

        try {
            char[] senha = { 'p', 'a', 's', 's' };
            loginContext = new LoginContext("Bonita",
                    new SimpleCallbackHandler("bruno", senha));

        } catch (LoginException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
package com.consystem.jsirc.bonita.auth;

import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.Arrays;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class JsircCallbackHandler implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {

        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof TextOutputCallback) {

                // display the message according to the specified type
                TextOutputCallback toc = (TextOutputCallback) callbacks[i];
                switch (toc.getMessageType()) {
                case TextOutputCallback.INFORMATION:
                    System.out.println(toc.getMessage());
                    break;
                case TextOutputCallback.ERROR:
                    System.out.println("ERROR: " + toc.getMessage());
                    break;
                case TextOutputCallback.WARNING:
                    System.out.println("WARNING: " + toc.getMessage());
                    break;
                default:
                    throw new IOException("Unsupported message type: "
                            + toc.getMessageType());
                }

            } else if (callbacks[i] instanceof NameCallback) {

                // prompt the user for a username
                NameCallback nc = (NameCallback) callbacks[i];

                System.err.print(nc.getPrompt());
                nc.setName("testUser");

                // System.err.flush();
                // nc
                // .setName((new BufferedReader(new InputStreamReader(
                // System.in))).readLine());

            } else if (callbacks[i] instanceof PasswordCallback) {

                // prompt the user for sensitive information
                PasswordCallback pc = (PasswordCallback) callbacks[i];
                System.err.print(pc.getPrompt());

                char[] password = { 't', 'e', 's', 't', 'P', 'a', 's', 's',
                        'w', 'o', 'r', 'd' };
                pc.setPassword(password);

                // System.err.flush();
                // pc.setPassword(readPassword(System.in));

            } else {
                throw new UnsupportedCallbackException(callbacks[i],
                        "Unrecognized Callback");
            }
        }

    }

    // Reads user password from given input stream.
    private char[] readPassword(InputStream in) throws IOException {

        char[] lineBuffer;
        char[] buf;
        int i;

        buf = lineBuffer = new char[128];

        int room = buf.length;
        int offset = 0;
        int c;

        loop: while (true) {
            switch (c = in.read()) {
            case -1:
            case '\n':
                break loop;

            case '\r':
                int c2 = in.read();
                if ((c2 != '\n') && (c2 != -1)) {
                    if (!(in instanceof PushbackInputStream)) {
                        in = new PushbackInputStream(in);
                    }
                    ((PushbackInputStream) in).unread(c2);
                } else
                    break loop;

            default:
                if (--room < 0) {
                    buf = new char[offset + 128];
                    room = buf.length - offset - 1;
                    System.arraycopy(lineBuffer, 0, buf, 0, offset);
                    Arrays.fill(lineBuffer, ' ');
                    lineBuffer = buf;
                }
                buf[offset++] = (char) c;
                break;
            }
        }

        if (offset == 0) {
            return null;
        }

        char[] ret = new char[offset];
        System.arraycopy(buf, 0, ret, 0, offset);
        Arrays.fill(buf, ' ');

        return ret;
    }

}

10

Re: [Resolved] JAAS Swing Bonita EJB3

Cool.
Thanks for this great sample code.