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


Reply via email to