That sounds very interesting as it is a quite simple solution. It might
have some securtiy implications though. Still it might be interesting to
describe this for other users.
If I remember correctly then the only way to achieve delegation without
MS Extensions is to send the forwardable Ticket Granting Ticket in the
request. If that is true for your case you should be aware that this means
the server can fully impersonate the user. This means it can access his
mail on an Exchange server, access all his files, ... This is a high
security risk.
A more secure way might be the STS aproach were the server can request a
Service Ticket on behalf of the user at the STS Server using the ST it
got. So the STS Server can have rules which resources the server may
access on behalf of the user. Of course this solution is a lot more
complicated.
Christian
Am 19.07.2012 20:37, schrieb Josef Bajada:
Hi all,
First of all I wanted to thank you all for your prompt replies and efforts to
propose a solution.
We've just managed to find a (quite simple) solution that works well and also
does not require any additional code to take care of it within the business
logic.
I'm explaining what we did here in case someone needs to do it and finds this
thread.
It also proves that Kerberos delegation also works well in Java without MS
extensions :)
Unfortunately the solution depends on Tomcat (7 or greater) and Spring.
What we did is that we wrote our own AuthSupplier, lets call it
TomcatPrincipalSpnegoAuthSupplier.
What this does is:
//the following is Spring dependent
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
//the following is Tomcat dependent
GenericPrincipal principal = (GenericPrincipal) request.getUserPrincipal();
//Tomcat 7 introduced Spnego auth, and with it the method getGssCredential() in
GenericPrincipal which is populated by RealmBase if the ticket can be used for
delegation
GSSCredential delegateCredential = principal.getGssCredential();
From then on one can use the normal GSSManager, GSSContext and GSSName etc. to
request the new token based on the existent GSSCredential from the KDC.
(Refer to the existent SpnegoAuthSupplier how to do it, Sergey's latest commit
includes the code to request a token based on an existent GSSCredential and a
specified SPN)
In the <jaxws:client> definition in the application context we then put:
<http:conduit ...>
...
<http:authSupplier class="my.package.TomcatPrincipalSpnegoAuthSupplier"/>
</http:conduit>
That way the business logic using the JAX-WS client does not have to do
anything, and does not even know it is being authenticated using Kerberos
delegation.
One final thing one needs to make sure that the client is sending a Kerberos
ticket which is forwardable and the application's account is flagged as
'Account is Trusted for Delegation', otherwise you'll be going around in
circles.
We'll need to make some null and instanceof checks for the AuthSupplier before
we go with it into production, and for it to work in instances when its not
being called from within a Servlet Request context (separate worker thread or
whatever), in which case it makes sense to fall back to the default
SpnegoAuthSupplier. I see that Sergey has just split the SpnegoAuthSupplier to
extend a separate AbstractSpnegoAuthSupplier so it might make sense to also
extend that in our Tomcat specific one, once it becomes available on the stable
release of CXF.
Our code would then just be the above 3 lines and if the request, principal and
delegateCredential are not null we create the GSSContext and call
getToken(authPolicy, gsscontext), otherwise we just do
super.getAuthorization(), or something along these lines.
Not sure how we could go about making this functionality available in CXF given
its dependence on Tomcat, however it would be great to include it out of the
box in CXF.
Thanks again, hope this thread helps others who try to achieve the same thing.
Regards,
Josef Bajada
Senior Technical Architect
GO
GO, Fra Diego Street, Marsa, MRS 1501, Malta.
t +356 2594 6826 f +356 2124 0112
w www.go.com.mt
This email and any files or content transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they are
addressed. This message contains confidential information and is intended only
for the individual named. If you are not the named addressee you should not
disseminate, distribute or copy this e-mail. Please notify the sender
immediately by e-mail if you have received this e-mail by mistake and delete
this e-mail from your system. If you are not the intended recipient you are
notified that disclosing, copying, distributing or taking any action in
reliance on the contents of this information is strictly prohibited. The
Company and the originator of this email accept no liability for the content of
this email, or for the consequences of any actions taken on the basis of the
information provided, unless that information is subsequently confirmed in
writing. If you are not the intended recipient you are notified that
disclosing, copying, distributing or taking any action in reliance on the
contents of this information is strictly prohibited.
Warning: Although the Company and the originator have taken reasonable
precautions to ensure no viruses are present in this email, the company cannot
accept responsibility for any loss or damage arising from the use of this email
or attachments.
-----Original Message-----
From: Christian Schneider [mailto:cschneider...@gmail.com] On Behalf Of
Christian Schneider
Sent: 19 July 2012 17:49
To: users@cxf.apache.org
Subject: Re: Kerberos authentication using delegation from Principal Ticket
I think an interceptor like you proposed might be the best solution long term
as it allows to keep the auth stuff out of the business code.
Christian
Am 19.07.2012 17:31, schrieb Sergey Beryozkin:
Hi Christian
On 19/07/12 06:53, Christian Schneider wrote:
I don“t think a static gssCredential in the spring config can help.
The credentials may be different on each call.
I thought Spring would be able to offer some per-request wrapper :-)
Instead I think we need to set the property on the client just before
the call. This is how it would look in the wsdl_first example:
org.apache.cxf.endpoint.Client client =
org.apache.cxf.frontend.ClientProxy.getClient(customerService);
client.setThreadLocalRequestContext(true);
Map<String, Object> reqContext = client.getRequestContext();
reqContext.put("org.ietf.jgss.GSSCredential", gssCredentials);
customers = customerService.getCustomersByName("Smith");
Not sure if this works but it should be worth a try.
Yeah, that is possible too - another option is to get a GSSCredential
retrieved from within a custom out interceptor (itself registered from
Spring) and then set it on a current message. I guess much depends on
the way the credential can be actually obtained from the original
SecurityContext which Tomcat and/or Spring Sec create, lets see what
solution Josef will find :-).
Cheers, Sergey
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
Talend Application Integration Division http://www.talend.com
Josef Bajada
Senior Technical Architect
GO
GO, Fra Diegu Street, Marsa, MRS 1501.
t +356 2594 6826
________________________________
--
Christian Schneider
http://www.liquid-reality.de
Open Source Architect
Talend Application Integration Division http://www.talend.com