You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by David Mansfield <da...@cobite.com> on 2015/05/04 23:36:54 UTC

[PATCH] canonicalized host name for kerberos (SPNEGO)

Hi All,

The attached patch (against 3.0.4 git) implements an additional 
property, useCanonicalHostname, which is supported by the 
AbstractSpnegoAuthSupplier, and therefore available to 
SpnegoAuthSupplier and KerberosAuthOutInterceptor.

The default behavior is not modified.  If useCanonicalHostname is set, 
then the service principal will be created using the canonical name of 
the remote host.

For example, if there is a CNAME DNS record for host.example.com which 
refers to an A record host-a-b-c.example.com, the default behavior would 
be to generate a service principal HTTP/host.example.com. When 
useCanonicalHostname is set to true, the service principal would be 
HTTP/host-a-b-c.example.com. Most browsers and many other HTTP user 
agents perform this kind of canonicalization.

This can be configured in XML as follows:

     <bean id="myAuthSupplier" class="org.apache.cxf.transport.http.auth.SpnegoAuthSupplier">
         <property name="useCanonicalHostname" value="true" />
     </bean>
     
     <http-conf:conduit name="...">
         <http-conf:authorization>
             <sec:AuthorizationType>Negotiate</sec:AuthorizationType>
             <sec:Authorization>CXFClient</sec:Authorization>
         </http-conf:authorization>
         
         <http-conf:authSupplier bean="myAuthSupplier" />
     </http-conf:conduit>


Or similarly for KerberosAuthOutInterceptor.

-- 
Thanks,
David Mansfield
Cobite, INC.

On 05/03/2015 10:20 AM, David Mansfield wrote:
> FYI: this much I have confirmed.  Using the following class as 
> replacement to the default KerberosAuthOutInterceptor does the trick.
>
> A small bit of refactoring and I should have this down in the Abstract 
> base class.
>
> package com.cobite.cxf.interceptor;
>
> import java.net.InetAddress;
> import java.net.URI;
> import java.util.logging.Level;
>
> public class KerberosAuthOutInterceptor extends 
> org.apache.cxf.jaxrs.security.KerberosAuthOutInterceptor {
>     private String realm;
>
>     private String getCanonicalHostName(String hostName) {
>     String canonicalHostName = hostName;
>     try {
>         InetAddress in = InetAddress.getByName(hostName);
>         canonicalHostName = in.getCanonicalHostName();
>         LOG.fine("resolved hostName="+hostName+" to 
> canonicalHostName="+canonicalHostName);
>     } catch (Exception e) {
>         LOG.warning("unable to resolve canonical hostname: 
> "+hostName+": "+e.getMessage());
>     }
>     return canonicalHostName;
>     }
>         @Override
>     protected String getCompleteServicePrincipalName(URI currentURI) {
>         String name = "HTTP/" + 
> getCanonicalHostName(currentURI.getHost());
>         if (realm != null) {
>             name += "@" + realm;
>         }
>         if (LOG.isLoggable(Level.FINE)) {
>             LOG.fine("Service Principal Name is " + name);
>         }
>         return name;
>     }
>
>     public void setRealm(String realm) {
>         this.realm = realm;
>     }
> }
>
>