This is nearly the same question as How to delegate the kerberos client credentials to the server?
But there is no answer. That's why I raise the question again. Hopefully someone can help.
It's possible to get a service ticket for the client (remote user) in the server side in order to use that ticket to authenticate against another backend?
Scenario: User (IE) ==> AppServer (Tomcat, under Linux) ==> Backend (webservice - REST service on Windows)
We have SPNEGO auth running and working in the AppServer
The AD user in the keytab file on in the AppServer has the rights to do the delegation (hopefully)
What are the preconditions that the GSSManager can create a credential that can be used for delegation? (´context.getDelegCred()´ should not fail after ´GSSManager.getInstance().createContext(this.serverCredentials)´?
There must be someone who has solved this problem?
Does "Forwardable Ticket true" mean that user from keytab file has delegation rights? Does anyone know this?
Thanks in advance
Output from HelloKDC.java (see extract from bellow)
Client Principal = HTTP/servername.domain.com@CORP1.AD1.COMPANY.NET
Server Principal = krbtgt/CORP1.AD1.COMPANY.NET@CORP1.AD1.COMPANY.NET
Session Key = EncryptionKey: keyType=23 keyBytes (hex dump)=
0000: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx ................
Forwardable Ticket true
Forwarded Ticket false
Proxiable Ticket false
Proxy Ticket false
Postdated Ticket false
Renewable Ticket false
Initial Ticket false
Auth Time = Wed Dec 20 16:52:03 CET 2017
Start Time = Wed Dec 20 16:52:03 CET 2017
End Time = Thu Dec 21 02:52:03 CET 2017
Renew Till = null
Client Addresses Null
Private Credential: /opt/app/tomcat/ssoad1/servername.domain.com.keytab for HTTP/servername.domain.com@CORP1.AD1.COMPANY.NET
Connection test successful.
Extract from HelloKDC.java (also from net.sourceforge.spnego):
// Name of our krb5 config file
final String krbfile = "/opt/app/tomcat/ssoad1/krb5.ini";
// Name of our login config file
final String loginfile = "/opt/app/tomcat/ssoad1/jaas.conf";
// Name of our login module
//final String module = "spnego-client";
final String module = "com.sun.security.jgss.krb5.initiate";
// set some system properties
System.setProperty("java.security.krb5.conf", krbfile);
System.setProperty("java.security.auth.login.config", loginfile);
System.setProperty("sun.security.krb5.debug", "true");
final LoginContext loginContext = new LoginContext(module);
// attempt to login
loginContext.login();
// output some info
System.out.println("Subject=" + loginContext.getSubject());
// logout
loginContext.logout();
System.out.println("Connection test successful.");
jaas.conf:
com.sun.comcurity.jgss.krb5.initiate {
com.sun.comcurity.auth.module.Krb5LoginModule required
doNotPrompt=true
principal="HTTP/servername.domain.com@CORP1.AD1.COMPANY.NET"
useKeyTab=true
keyTab="/opt/app/tomcat/ssoad1/servername.domain.com.keytab"
storeKey=true;
};
com.sun.security.jgss.krb5.accept {
com.sun.security.auth.module.Krb5LoginModule required
doNotPrompt=true
principal="HTTP/servername.domain.com@CORP1.AD1.COMPANY.NET"
useKeyTab=true
keyTab="/opt/app/tomcat/ssoad1/servername.domain.com.keytab"
storeKey=true
useTicketCache=true
isInitiator=true
refreshKrb5Config=true
moduleBanner=true
storePass=true;
};
spnego-client {
com.sun.security.auth.module.Krb5LoginModule required;
};
spnego-server {
com.sun.security.auth.module.Krb5LoginModule required
principal="HTTP/servername.domain.com@CORP1.AD1.COMPANY.NET"
useKeyTab=true
keyTab="/opt/app/tomcat/ssoad1/servername.domain.com.keytab"
storeKey=true
useTicketCache=true
isInitiator=false
refreshKrb5Config=true
moduleBanner=true
;
};
krb5.ini
[libdefaults]
default_realm = CORP1.AD1.COMPANY.NET
default_keytab_name = FILE:/opt/app/tomcat/ssoad1/servername.domain.com.keytab
default_tkt_enctypes = rc4-hmac
default_tgs_enctypes = rc4-hmac
forwardable = true
renewable = true
noaddresses = true
clockskew = 300
udp_preference_limit = 1
[realms]
CORP1.AD1.COMPANY.NET = {
kdc = ndcr001k.corp1.ad1.company.net:88
default_domain = domain.com
}
[domain_realm]
.domain.com = CORP1.AD1.COMPANY.NET
from net.sourceforge.spnego.SpnegoAuthenticator.java
SpnegoAuthenticator.LOCK.lock();
try {
LOGGER.fine("create context");
LOGGER.fine("serverCredentials="+this.serverCredentials.toString());
context = SpnegoAuthenticator.MANAGER.createContext(this.serverCredentials);
context.requestCredDeleg(true);
LOGGER.fine("clientModuleName="+clientModuleName.toString());
LOGGER.fine("context.getCredDelegState()="+context.getCredDelegState());
token = context.acceptSecContext(gss, 0, gss.length); // When I understand right : gss contains the token from the authorized client (IE Windows user)
LOGGER.fine("token="+token);
LOGGER.fine("context.getDelegCred()="+context.getDelegCred());
} finally {
SpnegoAuthenticator.LOCK.unlock();
}
creates the following Exception:
javax.servlet.ServletException: GSSException: No valid credentials provided
net.sourceforge.spnego.SpnegoHttpFilter.doFilter(SpnegoHttpFilter.java:287)
Root Cause
GSSException: No valid credentials provided
sun.security.jgss.krb5.Krb5Context.getDelegCred(Krb5Context.java:511)
sun.security.jgss.GSSContextImpl.getDelegCred(GSSContextImpl.java:614)
sun.security.jgss.spnego.SpNegoContext.getDelegCred(SpNegoContext.java:1064)
sun.security.jgss.GSSContextImpl.getDelegCred(GSSContextImpl.java:614)
net.sourceforge.spnego.SpnegoAuthenticator.doSpnegoAuth(SpnegoAuthenticator.java:503)