问题
I would like to configure Tomcat to be able to connect to AD and authenticate users accordingly.
In addition, I would also like to invoke some web services (in this case, Share Point) using the client credentials.
So far, I've managed to successfully configure Tomcat to use SPNEGO authentication, as described in the tutorial at http://tomcat.apache.org/tomcat-7.0-doc/windows-auth-howto.html. Note that I have used Tomcat's SPNEGO authentication (not Source Forge's or Waffle).
I did not use Source Forge's implementation since I wanted to keep things simple and use Tomcat's as provided out of the box. In addition, I wanted all the authentication and authorization to be handled by Tomcat, using the SPNEGO as the authentication method in WEB.XML
and Tomcat's JNDI realm for authorization.
Also I have not used WAFFLE, since this is Windows only.
I'm using CXF as my Web Service stack. According to the CXF documentation at http://cxf.apache.org/docs/client-http-transport-including-ssl-support.html#ClientHTTPTransport%28includingSSLsupport%29-SpnegoAuthentication%28Kerberos%29, all you need to do to authenticate with the a web service (in my case, Share Point) is to use:
<conduit name="{http://example.com/}HelloWorldServicePort.http-conduit"
xmlns="http://cxf.apache.org/transports/http/configuration">
<authorization>
<AuthorizationType>Negotiate</AuthorizationType>
<Authorization>CXFClient</Authorization>
</authorization>
</conduit>
and configure CXFClient in jaas.conf (in my case, where Tomcat's server JAAS configuration is located, such that my jass.conf
looks like:
CXFClient {
com.sun.security.auth.module.Krb5LoginModule required client=true useTicketCache=true debug=true;
};
com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required
doNotPrompt=true
principal="HTTP/tomcatsrv.corporate.intra@CORPORATE.INTRA"
useKeyTab=true
keyTab="C:/Program Files/Apache/apache-tomcat-7.0.27/conf/tomcatsrv.keytab"
storeKey=true
debug=true;
};
com.sun.security.jgss.krb5.accept {
com.sun.security.auth.module.Krb5LoginModule required
doNotPrompt=true
principal="HTTP/tomcatsrv.corporate.intra@CORPORATE.INTRA"
useKeyTab=true
keyTab="C:/Program Files/Apache/apache-tomcat-7.0.27/conf/tomcatsrv.keytab"
storeKey=true
debug=true;
};
Yet, when I'm invoking the web service, it is invoked under the service username (i.e. Tomcat's username configured in AD and in tomcatsrv.keytab
), rather than the client's username (e.g. duncan.attard).
So my question is this: Is there some way in which the client's username can be delegated (or use some sort of impersonation) to CXF so that when I invoke Share Point's web service (e.g. I want to upload a file using Copy.asmx), the file is uploaded as duncan.attard
and not as tomcat.srv
.
Thanks all, your help is much appreciated.
回答1:
Technically, this works perfectly. Here's the recipe:
- You do not need a login module name if you work with credential delegation.
- You have to make sure that the user account is eligible for delegation.
Take a look at the implementation of Tomcat's GenericPrincipal, it will save you the GSS credential if there is one. Cast request.getPrincipal
to GenericPrincipal
and get the credential.
Now say you have the credential:
- Construct a Subject with the
Principal
and theGSSCredential
as private credential. - Wrap the CXF code into a PrivilegedAction.
- Pass the constructed subject and an instance of your privileged action to the
Subject.doAs
method and the system will construct anAccessControlContext
on behalf of the passed subject and will invoke everything in JAAS on behalf of that context. CXF should use those if it is implemented correctly. This is likesu
orsudo
on Unix.
The easiest way to test that is to create an InitialDirContext
in the privileged action on behalf of the client to your Active Directory. This is how I test a working credential delegation environment.
来源:https://stackoverflow.com/questions/11499671/configure-tomcat-for-kerberos-and-impersonation