<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">
<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>
                                <td>
                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">JBoss Community</a></h1>
                                                                </td>
                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
Re: Security propagation from remote EJB clients to AS7
</h3>
<span style="margin-bottom: 10px;">
created by <a href="http://community.jboss.org/people/rodakr">Radek Rodak</a> in <i>JBoss AS 7 Development</i> - <a href="http://community.jboss.org/message/644551#644551">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">
<div class="jive-rendered-content"><p>Hi</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>1)</p><p>Can you provide client sample code using SASL Security ( for now PLAIN example would be enought ).</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><span>( or just add this example to </span><a class="jive-link-external-small" href="https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide-EJBinvocationsfromaremoteclientusingJNDI" target="_blank">https://docs.jboss.org/author/display/AS71/Developer+Guide#DeveloperGuide-EJBinvocationsfromaremoteclientusingJNDI</a><span> )</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>2)</p><p>I looked in source code of  org.jboss.sasl.JBossSaslProvider.java  ( jboss-sasl-1.0.0.Beta9.jar )</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Ony SASL MECH I see here are:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>"ANONYMOUS"</p><p>"PLAIN",</p><p>"DIGEST-MD5",</p><p>"JBOSS-LOCAL-USER"</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Could you also add "GSSAPI"  (  here how to from Darran Lofthouse <a class="jive-link-wiki-small" href="http://community.jboss.org/docs/DOC-17302" target="_blank">http://community.jboss.org/wiki/SASLAndKerberos</a> )</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Basically I would like to do this but with AS7.1:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p><a class="jive-link-external-small" href="http://community.jboss.org/docs/DOC-16137" target="_blank">http://community.jboss.org/wiki/EJB3AuthenticationWithSPNEGO</a></p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>I tried to call remote ejb after sucessfull JAAS Login, but JAAS Login Context seams to not get propagatet to Server over Jboss Remote...</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Here how I tried ( the same Code but calling Web URL Secured with SPNEGO works, so KRB5 Java Setup is ok)  :</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>import java.io.BufferedReader;</p><p>import java.io.IOException;</p><p>import java.io.InputStreamReader;</p><p>import java.security.AccessController;</p><p>import java.security.Principal;</p><p>import java.security.PrivilegedExceptionAction;</p><p>import java.security.Security;</p><p>import java.util.Collections;</p><p>import java.util.Hashtable;</p><p>import java.util.Properties;</p><p>import java.util.Set;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>import javax.naming.Context;</p><p>import javax.naming.InitialContext;</p><p>import javax.naming.NamingException;</p><p>import javax.security.auth.Subject;</p><p>import javax.security.auth.callback.Callback;</p><p>import javax.security.auth.callback.CallbackHandler;</p><p>import javax.security.auth.callback.NameCallback;</p><p>import javax.security.auth.callback.PasswordCallback;</p><p>import javax.security.auth.callback.TextInputCallback;</p><p>import javax.security.auth.callback.TextOutputCallback;</p><p>import javax.security.auth.callback.UnsupportedCallbackException;</p><p>import javax.security.auth.login.LoginContext;</p><p>import javax.security.sasl.Sasl;</p><p>import javax.security.sasl.SaslClient;</p><p>import javax.security.sasl.SaslException;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>import test.ejb3.TestServiceItf;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>public class TestServiceClient {</p><p>    static String JAAS_CONFIG_ENTRY = "com.sun.security.jgss.krb5.initiate";</p><p>    static BufferedReader br = new BufferedReader( new InputStreamReader (System.in));</p><p>    </p><p>    </p><p>    </p><p>    public static void main(String[] args) throws Exception {</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>        LoginContext lc = null;</p><p>        try {</p><p>            System.out.println("\n >> Enter Win user Name : ");</p><p>            //String callbackUser  = br.readLine ();</p><p>            String callbackUser  = "rrad";</p><p>            System.out.println("\n >> Enter Win User AD password : ");</p><p>            </p><p>            //String callbackPwd  = br.readLine ();</p><p>            String callbackPwd ="radoslaw13";</p><p>            // jaas collback might be needed for ticket refresh...</p><p>            lc = new LoginContext(JAAS_CONFIG_ENTRY,new NamePasswordCallbackHandler2(callbackUser,callbackPwd ));</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>            lc.login();</p><p>            //and get a subject</p><p>            Subject mySubject = lc.getSubject();</p><p>            System.out.println(" *********??????????********>>>> subject: "+mySubject);</p><p>            Set<Principal> sp = mySubject.getPrincipals();</p><p>            if ( sp == null ) System.out.println(" 0 principals ");</p><p>            else {</p><p>                System.out.println(+sp.size()+" principals");</p><p>                for ( Principal p : sp ) {</p><p>                    System.out.println("principal name :"+p.getName());</p><p>                }</p><p>            }</p><p>            // in case if not passed to java as property.. </p><p>            System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");</p><p>            System.setProperty( "sun.security.krb5.debug", "true");</p><p>                  </p><p>            </p><p>            PrivilegedExceptionAction<String> action = new GetAction( null, null  );</p><p>            //jaas call the service</p><p>            String aRet = (String)mySubject.doAs(mySubject, action);</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>            // successfuly called, read returned values</p><p>            System.out.println("successfully caled protected Method  : "+aRet);</p><p>        } catch (Exception e) {</p><p>            e.printStackTrace();</p><p>            System.exit(-1);</p><p>        }</p><p>    }</p><p>    </p><p>    /**</p><p>     *  dummy readLine Helper</p><p>     * @return</p><p>     */</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    public static String readLine(String message)</p><p>        {</p><p>            String s = null;</p><p>            System.out.println(message);</p><p>            try {</p><p>                InputStreamReader converter = new InputStreamReader(System.in);</p><p>                BufferedReader in = new BufferedReader(converter);</p><p>                s = in.readLine();</p><p>            } catch (Exception e) {</p><p>                System.out.println("Error! Exception: "+e); </p><p>            } finally {</p><p>                System.out.println("");</p><p>            }</p><p>            return s;</p><p>        }</p><p>    </p><p>    </p><p>    </p><p>     </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    </p><p>}</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>class GetAction implements PrivilegedExceptionAction<String> {</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    private String toke;</p><p>    private String user;</p><p>    private String testEjbItf="test.ejb3.TestServiceItf";</p><p>    // context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);</p><p>    private String testEjbJndi="ejb:/sl-securityTestEjb3//TestServiceSLEJB3Bean!test.ejb3.TestServiceItf";</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    </p><p>    public GetAction(String user , String token) {</p><p>        this.user = user;</p><p>        this.toke=token;</p><p>        </p><p>    }</p><p>    </p><p>    static {</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>        try {</p><p>            Sasl.createSaslClient(new String[]{"PLAIN"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("rrad","radoslaw13" ) );</p><p>        } catch (SaslException e) {</p><p>            // TODO Auto-generated catch block</p><p>            e.printStackTrace();</p><p>        }</p><p>        </p><p>        }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    // make shure </p><p>    public String run() throws Exception { </p><p>        </p><p>        //Sasl.createSaslClient(new String[]{"GSSAPI"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("xxx","yyy" ) );</p><p>        //Sasl.createSaslClient(new String[]{"PLAIN"}, null, "remoting", "ux2084", Collections.EMPTY_MAP, new NamePasswordCallbackHandler2("xxx","yyy" ) );</p><p>        javax.security.auth.Subject currentSubject = javax.security.auth.Subject.getSubject( AccessController.getContext());</p><p>        if ( currentSubject == null ) System.out.println(" our Action runs as Subject: null ");</p><p>        else System.out.println(" our Action runs as Subject: "+currentSubject.toString());</p><p>        Context ctx = getInitialContext();</p><p>        System.out.println("Initial Context created");</p><p>        System.out.println("lookup"+testEjbJndi+" @RolesAllowed({\"BackofficeRole\"})");</p><p>        Class itfClass = Thread.currentThread().getContextClassLoader().loadClass(testEjbItf);</p><p>        TestServiceItf testService = (TestServiceItf)  ctx.lookup(testEjbJndi);</p><p>        System.out.println("lookup testEjbJndi successful");</p><p>        System.out.println(" call unsecured Method permittAllMethod()");</p><p>        Subject asu = testService.permittAllMethod(" calling unsecured");</p><p>        System.out.println(" successfully called, received Subject: "+asu);</p><p>        System.out.println(" call secured Method with role "+testService.BACKOFFICE_ROLE);</p><p>        asu = testService.pwvAuthenticatorSecuredMethod(" calling secured");</p><p>        System.out.println(" successfully called, received Subject: "+asu);</p><p>        return "Test ok";</p><p>    }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    private static Context getInitialContext() throws NamingException {</p><p>         final Hashtable jndiProperties = new Hashtable();</p><p>         jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");</p><p>         jndiProperties.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");</p><p>         final Context context = new InitialContext(jndiProperties);</p><p>         return context;</p><p>        }</p><p>    </p><p>    </p><p>}</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>class NamePasswordCallbackHandler2 implements CallbackHandler</p><p>{</p><p>    /**</p><p>     * The username to be provided when prompted.</p><p>     */</p><p>    private String username;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    /**</p><p>     * The password to be provided when prompted.</p><p>     */</p><p>    private String password;</p><p>    </p><p>    private String url;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    /**</p><p>     * Create a new NamePasswordCallbackHandler (required Cams default </p><p>     * constructor that is dynamically called by the authentication</p><p>     * server).</p><p>     * @param anURL </p><p>     * @param callbackPwd </p><p>     * @param callbackUser </p><p>     */</p><p>    public NamePasswordCallbackHandler2(String callbackUser, String callbackPwd)</p><p>    {</p><p>        this.username = callbackUser;</p><p>        this.password = callbackPwd;</p><p>    }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    /**</p><p>     * Set the username.</p><p>     *</p><p>     * @param username the username to be provided to a NameCallback.</p><p>     */</p><p>    public void setUsername(String username)</p><p>    {</p><p>        if (username == null)</p><p>        {</p><p>            this.username = "";</p><p>            return;</p><p>        }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>        this.username = username;</p><p>    }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    /**</p><p>     * Set the password.</p><p>     *</p><p>     * @param password the password to be provided to a PasswordCallback.</p><p>     */</p><p>    public void setPassword(String password)</p><p>    {</p><p>        if (password == null)</p><p>        {</p><p>            this.password = "";</p><p>            return;</p><p>        }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>        this.password = password;</p><p>    }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>    public void handle(Callback[] callbacks)</p><p>    throws IOException, UnsupportedCallbackException</p><p>  {</p><p>    for(int i = 0; i < callbacks.length; i++)</p><p>    {</p><p>      if(callbacks[i] instanceof TextOutputCallback)</p><p>      {</p><p>        // Display the message according to the specified type</p><p>        TextOutputCallback toc = (TextOutputCallback)callbacks[i];</p><p>        switch(toc.getMessageType())</p><p>        {</p><p>        case TextOutputCallback.INFORMATION:</p><p>          log(toc.getMessage());</p><p>          break;</p><p>        case TextOutputCallback.ERROR:</p><p>          log("ERROR: " + toc.getMessage());</p><p>          break;</p><p>        case TextOutputCallback.WARNING:</p><p>          log("WARNING: " + toc.getMessage());</p><p>          break;</p><p>        default:</p><p>          throw new IOException("Unsupported message type: "+toc.getMessageType());</p><p>        }</p><p>      }</p><p>      else if(callbacks[i] instanceof NameCallback)</p><p>      {</p><p>        // If username not supplied on cmd line, prompt the user for the username.</p><p>        NameCallback nc = (NameCallback)callbacks[i];</p><p>        if (username == null || username.isEmpty()) {</p><p>          System.err.print(nc.getPrompt());</p><p>          System.err.flush();</p><p>          nc.setName((new BufferedReader(new InputStreamReader(System.in))).readLine());</p><p>        }</p><p>        else {</p><p>          log("username: "+username);</p><p>          nc.setName(username);</p><p>        }</p><p>      }</p><p>      else if(callbacks[i] instanceof PasswordCallback)</p><p>      { </p><p>        PasswordCallback pc = (PasswordCallback)callbacks[i];</p><p>        </p><p>        // If password not supplied on cmd line, prompt the user for the password.</p><p>        if (password == null || password.isEmpty()) {</p><p>          System.err.print(pc.getPrompt());</p><p>          System.err.flush();</p><p>  </p><p>          // Note: JAAS specifies that the password is a char[] rather than a String</p><p>          String tmpPassword = (new BufferedReader(new InputStreamReader(System.in))).readLine();</p><p>          int passLen = tmpPassword.length();</p><p>          char[] passwordArray = new char[passLen];</p><p>          for(int passIdx = 0; passIdx < passLen; passIdx++)</p><p>            passwordArray[passIdx] = tmpPassword.charAt(passIdx);</p><p>          pc.setPassword(passwordArray);</p><p>        }</p><p>        else {</p><p>          String tPass = new String();</p><p>          for(int p = 0; p < password.length(); p++)</p><p>            tPass += "*";</p><p>          log("password: "+tPass);</p><p>          pc.setPassword(password.toCharArray());</p><p>        }        </p><p>      }</p><p>      else if(callbacks[i] instanceof TextInputCallback)</p><p>      {</p><p>        // Prompt the user for the username</p><p>        TextInputCallback callback = (TextInputCallback)callbacks[i];</p><p>        System.err.print(callback.getPrompt());</p><p>        System.err.flush();</p><p>        callback.setText((new BufferedReader(new InputStreamReader(System.in))).readLine());</p><p>      }</p><p>      else</p><p>      {</p><p>        throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");</p><p>      }</p><p>    }</p><p>  }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>  private void log(String str) { System.out.println(str); }</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Happy New Year</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Radek Rodak</p></div>
<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
<p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/644551#644551">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in JBoss AS 7 Development at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2225">Community</a></p>
</div></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>