Search code examples
ejb-3.0kerberoswildfly-10thick-clientjboss-eap-7

Kerberos Authentication Integration for Remoting


I am following these instructions here: Chapter 3. Additional Features - Red Hat Customer Portal

Specifically, I am trying to follow section 3.3 and get Kerberos working with a remoting application.

My standalone.xml looks like the example in the documentation. My service principal, keytab and user work, since I can follow section 3.2 and login through the management interface.

   <security-realm name="krbRealm">
    <server-identities>
     <kerberos>
      <keytab principal="remote/[email protected]" path="tmfkrbrem.keytab" relative-to="jboss.server.config.dir" debug="true"/>
     </kerberos>
    </server-identities>
    <authentication>
     <kerberos remove-realm="true"/>
     <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
    </authentication>
                <authorization>
                    <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
                </authorization>
   </security-realm> 

    <security-domain name="krb-remoting-domain">
      <authentication>
     <login-module code="Remoting" flag="optional">
       <module-option name="password-stacking" value="useFirstPass"/>
     </login-module>
     <login-module code="RealmDirect" flag="required">
       <module-option name="password-stacking" value="useFirstPass"/>
       <module-option name="realm" value="krbRealm"/>
     </login-module>
      </authentication>
      <mapping>
       <mapping-module code="SimpleRoles" type="role">
        <module-option name="testuser" value="Users"/>
       </mapping-module>
      </mapping>
    </security-domain>  

        <subsystem xmlns="urn:jboss:domain:remoting:3.0">
            <endpoint/>
   <http-connector name="http-remoting-connector" connector-ref="default" security-realm="krbRealm"/>
        </subsystem> 

I am using sample client code based on the client shown here: [JBEAP-715] EJB authentication via Kerberos does not work with wildfly-security-api - JBoss Issue Tracker

// Remoting
Context context = null;
try {
   System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
    System.setProperty("java.util.logging.manager", "java.util.logging.LogManager");
    System.setProperty("java.util.logging.config.file", "logging.properties");
    System.setProperty("java.util.logging.ConsoleHandler.level", "TRACE");
    Properties props = new Properties();

    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
    props.put(Context.PROVIDER_URL, "http-remoting://tmf-is3-sec.nsonet.com:8080");
    props.put("jboss.naming.client.ejb.context", true);
    props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    props.put("remote.connection.main.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS","true");
    props.put("remote.connection.main.connect.options.org.xnio.Options.SSL_ENABLED", "false");
    props.put("remote.connection.main.connect.options.org.jboss.remoting3.RemotingOptions.SASL_PROTOCOL", "remote");            
    context = new InitialContext(props);
} catch (Exception e) {
    e.printStackTrace();
}

tmfService tmfBean = (tmfService) context.lookup("tmf-app/com.mentor.tmf.bean//tmfBean!com.mentor.tmf.api.internal.tmfService");
tmfRequest req = new tmfRequest("First test");
req.print();

tmfResponse resp = tmfBean.firstOperation(req);
resp.print();

}

Here is my bean:

@Stateless
@Remote(tmfService.class)
@SecurityDomain("krb-remoting-domain")
@RolesAllowed("Users")
public class tmfBean implements tmfService {
    public tmfBean() {
        // nothing here
    } 

    @Override
    public tmfResponse firstOperation(tmfRequest req) {        
        System.out.println("tmfBean gets request  <" + req.getMyData() + ">\n");        
        tmfResponse rval = new tmfResponse(req.getMyData() + " MODIFIED");
        return rval;
    }    
} 

I get these errors on the client: (login is successful)

Exception in thread "main" javax.naming.AuthenticationException: Failed to connect to any server. Servers tried: [http-remoting://tmf-is3-sec.nsonet.com:8080 (Authentication failed: all available authentication mechanisms failed:

   GSSAPI: Server rejected authentication)] [Root exception is javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
   GSSAPI: Server rejected authentication]
at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:238)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:149)
at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:130)
at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:272)
at org.jboss.naming.remote.client.RemoteContext.lookupInternal(RemoteContext.java:104)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:93)
at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:146)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at com.mentor.tmf.client.tmfTest.main(tmfTest.java:154)
Caused by: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed:
   GSSAPI: Server rejected authentication
at org.jboss.remoting3.remote.ClientConnectionOpenListener.allMechanismsFailed(ClientConnectionOpenListener.java:114)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:389)
at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:241) 

I get this error on the server:

08:06:12,851 INFO  [stdout] (default I/O-1) Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt false ticketCache is null isInitiator false KeyTab is C:\wildfly-10.0.0.Final\standalone\configuration\tmfkrbrem.keytab refreshKrb5Config is false principal is remote/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
08:06:12,853 INFO  [stdout] (default I/O-1) principal is remote/[email protected]
08:06:12,853 INFO  [stdout] (default I/O-1) Will use keytab
08:06:12,854 INFO  [stdout] (default I/O-1) Commit Succeeded 
08:06:12,854 INFO  [stdout] (default I/O-1) 
08:06:13,029 TRACE [org.jboss.remoting.remote.server] (default task-2) Server sending authentication rejected: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)]
 at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(Unknown Source)
 at org.jboss.sasl.gssapi.GssapiServer$1.run(GssapiServer.java:60)
 at org.jboss.sasl.gssapi.GssapiServer$1.run(GssapiServer.java:56)
 ... 27 more
Caused by: KrbException: Checksum failed
 at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
 at sun.security.krb5.internal.crypto.Aes128CtsHmacSha1EType.decrypt(Unknown Source)
 at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
 ... 19 more
Caused by: java.security.GeneralSecurityException: Checksum failed
 at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decryptCTS(Unknown Source)
 at sun.security.krb5.internal.crypto.dk.AesDkCrypto.decrypt(Unknown Source)
 at sun.security.krb5.internal.crypto.Aes128.decrypt(Unknown Source)
 ... 22 more

Any assistance would be appreciated. We cannot find any documentation on how to authenticate a client with Kerberos to access an EJB.

thanks, -Tom


Solution

  • I found the solution. Basically the service principal needs to have both remoting/... and remote/.. in the name for the same account.

    I only had "remote/..." in one account and "remoting/..." in another test account. I deleted the duplicate test account an added "remoting/..." to the service account.

    C:>setspn -a remoting/tmf-is3-sec.nsonet.com tmfkrbrem
    Registering ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com
            remoting/tmf-is3-sec.nsonet.com
    Updated object
    

    The result should look like this:

    C:>setspn -l tmfkrbrem
    Registered ServicePrincipalNames for CN=tmf krbrem.,CN=Users,DC=nsonet,DC=com:
            remoting/tmf-is3-sec.nsonet.com
            remote/tmf-is3-sec.nsonet.com
    

    Then I created a new keytab, but this may not be needed.

    C:>ktpass -princ remote/[email protected] -pass Test1234 -mapuser NSONET\tmfkrbrem -
    ptype KRB5_NT_PRINCIPAL -crypto AES128-SHA1 -kvno 0 -out C:\Users\Administrator\Desktop\tmfkrbrem.keytab
    Targeting domain controller: nso-dc.nsonet.com
    Using legacy password setting method
    Successfully mapped remote/tmf-is3-sec.nsonet.com to tmfkrbrem.
    Key created.
    Output keytab to C:\Users\Administrator\Desktop\tmfkrbrem.keytab:
    Keytab version: 0x502
    keysize 75 remote/[email protected] ptype 1 (KRB5_NT_PRINCIPAL) vno 0 etype 0x11 (AES128-SHA1) keylength
     16 (0x9477d8bdfbf874ae5ad0b24fd611fb30)