[jboss-dev-forums] [JBoss AS 7 Development] - Re: Security propagation from remote EJB clients to AS7

Radek Rodak do-not-reply at jboss.com
Wed Jan 4 04:24:15 EST 2012


Radek Rodak [http://community.jboss.org/people/rodakr] created the discussion

"Re: Security propagation from remote EJB clients to AS7"

To view the discussion, visit: http://community.jboss.org/message/644551#644551

--------------------------------------------------------------
Hi

1)
Can you provide client sample code using SASL Security ( for now PLAIN example would be enought ).

( or just add this example to  https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide-EJBinvocationsfromaremoteclientusingJNDI https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide-EJBinvocationsfromaremoteclientusingJNDI )

2)
I looked in source code of  org.jboss.sasl.JBossSaslProvider.java  ( jboss-sasl-1.0.0.Beta9.jar )

Ony SASL MECH I see here are:

"ANONYMOUS"
"PLAIN",
"DIGEST-MD5",
"JBOSS-LOCAL-USER"

Could you also add "GSSAPI"  (  here how to from Darran Lofthouse  http://community.jboss.org/docs/DOC-17302 http://community.jboss.org/wiki/SASLAndKerberos )

Basically I would like to do this but with AS7.1:

 http://community.jboss.org/docs/DOC-16137 http://community.jboss.org/wiki/EJB3AuthenticationWithSPNEGO

I tried to call remote ejb after sucessfull JAAS Login, but JAAS Login Context seams to not get propagatet to Server over Jboss Remote...

Here how I tried ( the same Code but calling Web URL Secured with SPNEGO works, so KRB5 Java Setup is ok)  :



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
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.TextInputCallback;
import javax.security.auth.callback.TextOutputCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;

import test.ejb3.TestServiceItf;

public class TestServiceClient {
    static String JAAS_CONFIG_ENTRY = "com.sun.security.jgss.krb5.initiate";
    static BufferedReader br = new BufferedReader( new InputStreamReader (System.in));



    public static void main(String[] args) throws Exception {


        LoginContext lc = null;
        try {
            System.out.println("\n >> Enter Win user Name : ");
            //String callbackUser  = br.readLine ();
            String callbackUser  = "rrad";
            System.out.println("\n >> Enter Win User AD password : ");

            //String callbackPwd  = br.readLine ();
            String callbackPwd ="radoslaw13";
            // jaas collback might be needed for ticket refresh...
            lc = new LoginContext(JAAS_CONFIG_ENTRY,new NamePasswordCallbackHandler2(callbackUser,callbackPwd ));

            lc.login();
            //and get a subject
            Subject mySubject = lc.getSubject();
            System.out.println(" *********??????????********>>>> subject: "+mySubject);
            Set<Principal> sp = mySubject.getPrincipals();
            if ( sp == null ) System.out.println(" 0 principals ");
            else {
                System.out.println(+sp.size()+" principals");
                for ( Principal p : sp ) {
                    System.out.println("principal name :"+p.getName());
                }
            }
            // in case if not passed to java as property.. 
            System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
            System.setProperty( "sun.security.krb5.debug", "true");


            PrivilegedExceptionAction<String> action = new GetAction( null, null  );
            //jaas call the service
            String aRet = (String)mySubject.doAs(mySubject, action);

            // successfuly called, read returned values
            System.out.println("successfully caled protected Method  : "+aRet);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    /**
     *  dummy readLine Helper
     * @return
     */

    public static String readLine(String message)
        {
            String s = null;
            System.out.println(message);
            try {
                InputStreamReader converter = new InputStreamReader(System.in);
                BufferedReader in = new BufferedReader(converter);
                s = in.readLine();
            } catch (Exception e) {
                System.out.println("Error! Exception: "+e); 
            } finally {
                System.out.println("");
            }
            return s;
        }






}

class GetAction implements PrivilegedExceptionAction<String> {

    private String toke;
    private String user;
    private String testEjbItf="test.ejb3.TestServiceItf";
    // context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    private String testEjbJndi="ejb:/sl-securityTestEjb3//TestServiceSLEJB3Bean!test.ejb3.TestServiceItf";


    public GetAction(String user , String token) {
        this.user = user;
        this.toke=token;

    }

    static {

        try {
            Sasl.createSaslClient(new String[]{"PLAIN"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("rrad","radoslaw13" ) );
        } catch (SaslException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        }

    // make shure 
    public String run() throws Exception { 

        //Sasl.createSaslClient(new String[]{"GSSAPI"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("xxx","yyy" ) );
        //Sasl.createSaslClient(new String[]{"PLAIN"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("xxx","yyy" ) );
        javax.security.auth.Subject currentSubject = javax.security.auth.Subject.getSubject( AccessController.getContext());
        if ( currentSubject == null ) System.out.println(" our Action runs as Subject: null ");
        else System.out.println(" our Action runs as Subject: "+currentSubject.toString());
        Context ctx = getInitialContext();
        System.out.println("Initial Context created");
        System.out.println("lookup"+testEjbJndi+" @RolesAllowed({\"BackofficeRole\"})");
        Class itfClass = Thread.currentThread().getContextClassLoader().loadClass(testEjbItf);
        TestServiceItf testService = (TestServiceItf)  ctx.lookup(testEjbJndi);
        System.out.println("lookup testEjbJndi successful");
        System.out.println(" call unsecured Method permittAllMethod()");
        Subject asu = testService.permittAllMethod(" calling unsecured");
        System.out.println(" successfully called, received Subject: "+asu);
        System.out.println(" call secured Method with role "+testService.BACKOFFICE_ROLE);
        asu = testService.pwvAuthenticatorSecuredMethod(" calling secured");
        System.out.println(" successfully called, received Subject: "+asu);
        return "Test ok";
    }

    private static Context getInitialContext() throws NamingException {
         final Hashtable jndiProperties = new Hashtable();
         jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
         jndiProperties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");
         final Context context = new InitialContext(jndiProperties);
         return context;
        }


}

class NamePasswordCallbackHandler2 implements CallbackHandler
{
    /**
     * The username to be provided when prompted.
     */
    private String username;

    /**
     * The password to be provided when prompted.
     */
    private String password;

    private String url;

    /**
     * Create a new NamePasswordCallbackHandler (required Cams default 
     * constructor that is dynamically called by the authentication
     * server).
     * @param anURL 
     * @param callbackPwd 
     * @param callbackUser 
     */
    public NamePasswordCallbackHandler2(String callbackUser, String callbackPwd)
    {
        this.username = callbackUser;
        this.password = callbackPwd;
    }


    /**
     * Set the username.
     *
     * @param username the username to be provided to a NameCallback.
     */
    public void setUsername(String username)
    {
        if (username == null)
        {
            this.username = "";
            return;
        }

        this.username = username;
    }

    /**
     * Set the password.
     *
     * @param password the password to be provided to a PasswordCallback.
     */
    public void setPassword(String password)
    {
        if (password == null)
        {
            this.password = "";
            return;
        }

        this.password = password;
    }

    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:
          log(toc.getMessage());
          break;
        case TextOutputCallback.ERROR:
          log("ERROR: " + toc.getMessage());
          break;
        case TextOutputCallback.WARNING:
          log("WARNING: " + toc.getMessage());
          break;
        default:
          throw new IOException("Unsupported message type: "+toc.getMessageType());
        }
      }
      else if(callbacks[i] instanceof NameCallback)
      {
        // If username not supplied on cmd line, prompt the user for the username.
        NameCallback nc = (NameCallback)callbacks[i];
        if (username == null || username.isEmpty()) {
          System.err.print(nc.getPrompt());
          System.err.flush();
          nc.setName((new BufferedReader(new InputStreamReader(System.in))).readLine());
        }
        else {
          log("username: "+username);
          nc.setName(username);
        }
      }
      else if(callbacks[i] instanceof PasswordCallback)
      { 
        PasswordCallback pc = (PasswordCallback)callbacks[i];

        // If password not supplied on cmd line, prompt the user for the password.
        if (password == null || password.isEmpty()) {
          System.err.print(pc.getPrompt());
          System.err.flush();

          // Note: JAAS specifies that the password is a char[] rather than a String
          String tmpPassword = (new BufferedReader(new InputStreamReader(System.in))).readLine();
          int passLen = tmpPassword.length();
          char[] passwordArray = new char[passLen];
          for(int passIdx = 0; passIdx < passLen; passIdx++)
            passwordArray[passIdx] = tmpPassword.charAt(passIdx);
          pc.setPassword(passwordArray);
        }
        else {
          String tPass = new String();
          for(int p = 0; p < password.length(); p++)
            tPass += "*";
          log("password: "+tPass);
          pc.setPassword(password.toCharArray());
        }        
      }
      else if(callbacks[i] instanceof TextInputCallback)
      {
        // Prompt the user for the username
        TextInputCallback callback = (TextInputCallback)callbacks[i];
        System.err.print(callback.getPrompt());
        System.err.flush();
        callback.setText((new BufferedReader(new InputStreamReader(System.in))).readLine());
      }
      else
      {
        throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
      }
    }
  }

  private void log(String str) { System.out.println(str); }


Happy New Year

Radek Rodak
--------------------------------------------------------------

Reply to this message by going to Community
[http://community.jboss.org/message/644551#644551]

Start a new discussion in JBoss AS 7 Development at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2225]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-dev-forums/attachments/20120104/d50def3d/attachment.html 


More information about the jboss-dev-forums mailing list