Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
230 views
in Technique[技术] by (71.8m points)

Java SPNEGO Authentication & Kerberos Constrained Delegation (KCD) to backend service

I have a Java web application which do SPNEGO authentication of clients in a Windows Active Directory environment. To authenticate the user we use code from the good old SPNEGO SourceForge project.

String encodedAuthToken = (String) credentials;
LOG.debug("Encoded auth token: " + encodedAuthToken);
byte[] authToken = B64Code.decode(encodedAuthToken);
GSSManager manager = GSSManager.getInstance();

try {
    Oid krb5Oid = new Oid("1.3.6.1.5.5.2");
    GSSName gssName = manager.createName(_targetName, null);
    GSSCredential serverCreds = manager.createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, krb5Oid, GSSCredential.INITIATE_AND_ACCEPT);
    GSSContext gContext = manager.createContext(serverCreds);

    if (gContext != null) { 
        while (!gContext.isEstablished()) {
            authToken = gContext.acceptSecContext(authToken, 0, authToken.length);
        }
        if (gContext.isEstablished()) {
            // Login succeeded!
            String clientName = gContext.getSrcName().toString();
        }
    }
}

The authentication works good but we also have a requirement to delegate the user credentials to a back-end service (Exchange EWS), using constrained delegation. When configuring this in our AD it looks like a small difference, but it's not. See: AD delegation settings

The difference is described here: msdn.microsoft.com/en-us/library/cc246080.aspx?f=255&MSPPError=-2147217396 With unconstrained delegation we could simply use the available delegated credentials when we call the back-end service and it would all be good:

GSSCredential delegatedCreds = gContext.getDelegCred()
SpnegoHttpURLConnection conn = new SpnegoHttpURLConnection(clientCreds);

With constrained delegation we have no access to the users TGT and it seems we need to use the MS-SFU (S4U2proxy) Kerberos extension which Java 8 is suppose to support. The only example I could find is this one: https://github.com/ymartin59/java-kerberos-sfudemo (thanks Yves Martin for that!)

Now to my problem... After my authentication I basically end up with the username of the authenticated user (see "clientName" in code above).

Do we really need to use the S4U2self mechanism to impersonate the user here? The client just sent us it's Kerberos Service Ticket (wrapped in the SPNEGO token I can't decode). Ideally we should be able to use that service ticket and my own service's TGT to authenticate the user (using the S4U2proxy mechanism)? But I do not understand how.

So now I'm wondering if it's possible to tie together our SPNEGO authentication with S4U2proxy delegation?

Many thanks for any input on this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I've actually been doing something like this recently but am using spring security kerberos. I put an example on github here. The key thing that I found that I needed set up to use constrained delegation like you want it and S4U2Proxy was to make sure (if you're using Oracle/OpenJDK) you set isInitiator=true in your JAAS Config so that when getDelegCred is called you get back a Krb5ProxyCredential. See comment here. With that credential, you can use it to create service ticket tokens on the Users behalf for the services you are constrained to use in the normal fashion, like this.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...