I want to secure a gemfire(v9.9) cluster with kerberos authentication.
I believe i have to,
- authenticate the client and gemfire server to KDC( active directory in my case), using JAAS and a keytab
- at the client get the session ticket( a
byte []
) from theSubject
, usingSubject.doAs
- pass this byte[] to the gemfire server
- on the gemfire server check if the ticket received is correct
i found some sample code here https://www.programcreek.com/java-api-examples/?code=ampool/monarch/monarch-master/ADS/geode-core/src/main/java/io/ampool/security/KerberosAuthInit.java
i am sucessfully able to do LoginContect.login() and get the Subject
at client and gemfire server
My code:
LoginContext loginCtx = new LoginContext("Client", new TextCallbackHandler());
loginCtx.login();
Subject subject = loginCtx.getSubject();
GSSManager manager = GSSManager.getInstance();
GSSName serverName = manager.createName( servicePrincipalName, GSSName.NT_HOSTBASED_SERVICE);
final GSSContext context = manager.createContext( serverName, new Oid( "1.2.840.113554.1.2.2"), null, GSSContext.DEFAULT_LIFETIME);
byte[] serviceTicket =
Subject.doAs(subject, new PrivilegedExceptionAction<byte[]>() {
@Override
public byte[] run() throws Exception {
byte[] serviceTicket = null;
byte[] token = new byte[0];
// This is a one pass context initialisation.
context.requestMutualAuth(false);
context.requestCredDeleg(false);
serviceTicket = context.initSecContext(token, 0, token.length); //code fails here
/*java.security.PrivilegedActionException:
GSSException: No valid credentials provided
(Mechanism level: Server not found in Kerberos database (7) - UNKNOWN_SERVER)
Caused by: KrbException: Identifier doesn't match expected value (906)
*/
return serviceTicket;
}
});
//send this serviceTicket to gemfire server and then do
//--------------------at the gemfire server level-------------------
String clientContext =
Subject.doAs( serverSubject, new PrivilegedAction<String>() {
public String run() {
try {
String clientName = null;
// Identify the server that communications are being made to.
GSSManager manager = GSSManager.getInstance();
GSSContext context = manager.createContext((GSSCredential) null);
context.acceptSecContext(serviceTicket, 0, serviceTicket.length);
clientName = context.getSrcName().toString();
return clientName;
}
catch ( Exception e) {
e.printStackTrace();
return null;
}
}
}
);
Links i used to reach till here
https://github.com/ekoontz/jaas_and_kerberos https://cwiki.apache.org/confluence/display/GEODE/Geode+Security+Framework
My questions:
- Is my approach correct ?
- How do i get the byte[] session ticket
- at the gemfire server level verify that the ticket is correct