Wiki Markup |
---|
{span:style=font-size:2em;font-weight:bold} JAX-RS Kerberos Support {span} |
Table of Contents |
---|
Introduction
...
'Negotiate' authentication scheme is used to pass Kerberos service tickets over HTTP.
Example:
Code Block | ||||
---|---|---|---|---|
| ||||
Authorization: Negotiate "the encrypted service ticket"
|
...
As explained on this page, Authorization Policy typically needs to have its type set to "Negotiate" and its "authorization" property set to the name of the JAAS context. AuthorizationPolicy is set as a "policy" property on the interceptor, example:
Code Block | ||||
---|---|---|---|---|
| ||||
WebClient wc = WebClient.create("http://localhost:" + PORT + "/bookstore/books/123");
KerberosAuthOutInterceptor kbInterceptor = new KerberosAuthOutInterceptor();
AuthorizationPolicy policy = new AuthorizationPolicy();
policy.setAuthorizationType(HttpAuthHeader.AUTH_TYPE_NEGOTIATE);
policy.setAuthorization("KerberosClientKeyTab");
kbInterceptor.setPolicy(policy);
WebClient.getConfig(wc).getOutInterceptors().add(kbInterceptor);
Book b = wc.get(Book.class);
|
...
org.apache.cxf.jaxrs.security.KerberosAuthenticationFilter can be used to protected JAX-RS endpoints and enforce that a Negotiate authentication scheme is used by clients, example:
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="kerberosFilter" class="org.apache.cxf.jaxrs.security.KerberosAuthenticationFilter">
<property name="loginContextName" value="KerberosServiceKeyTab"/>
</bean>
<jaxrs:server>
<jaxrs:serviceBeans>
<bean class="org.mycompany.MyCompanyResource"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="kerberosFilter">
</jaxrs:providers>
</jaxrs:server>
|
...
javax.security.auth.callback.CallbackHandler needs to be registered if no Kerberos key tabs are used, here is an example of setting it up from Java:
Code Block | ||||
---|---|---|---|---|
| ||||
public class TestResource {
public static void main(String[] args) {
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
sf.setResourceClasses(BookStore.class);
KerberosAuthenticationFilter filter = new KerberosAuthenticationFilter();
filter.setLoginContextName("KerberosServer");
CallbackHandler handler =
new org.apache.cxf.interceptor.security.NamePasswordCallbackHandler("HTTP/localhost", "http");
filter.setCallbackHandler(handler);
//filter.setLoginContextName("KerberosServerKeyTab");
//filter.setServicePrincipalName("HTTP/ktab");
sf.setProvider(filter);
sf.setAddress("http://localhost:" + PORT + "/");
sf.create();
}
}
|
...
Note that if you have a JAX-RS KerberosAuthenticationFilter protecting the endpoints, then the filter will have an org.ietf.jgss.GSSContext instance available in the current CXF SecurityContext, via its KerberosAuthenticationFilter$KerberosSecurityContext implementation, which can be used to get to org.ietf.jgss.GSSCredential if the credential delegation is supported for a given source principal. The current credential if any can be set as a client property next, for example:
Code Block | ||||
---|---|---|---|---|
| ||||
import org.ietf.jgss.GSSCredential; import org.apache.cxf.jaxrs.security.KerberosAuthenticationFilter; import org.apache.cxf.jaxrs.security.KerberosAuthenticationFilter.KerberosSecurityContext; import org.apache.cxf.phase.PhaseInterceptorChain; import org.apache.cxf.security.SecurityContext; @Path("service") public class MyResource { @Context private javax.ws.rs.core.SecurityContext securityContext; @GET public Book getBookFromKerberosProtectedStore() { WebClient wc = webClient.create("http://internal.com/store"); SecurityContext securityContext = PhaseInterceptorChain.getCurrentMessage().get(SecurityContext.class); if (securityContext instanceof KerberosSecurityContext) { KerberosSecurityContext ksc = (KerberosSecurityContext)securityContext; GSSCredential cred = ksc.getGSSContext().getDelegCred(); if (cred != null) { WebClient.getConfig(wc).getRequestContext().put(GSSCredential.class.getName(), cred); } } return wc.get(Book.class); } } |
...