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;
    }
}


--
Thanks,
David Mansfield
Cobite, INC.
On 04/29/2015 04:43 AM, Colm O hEigeartaigh wrote:
Either a github pull request, or else you can create a JIRA and attach the
diff there if you prefer. Yes your changes sound fine, so long as the
current behaviour can be enabled via a switch
(useCanonicalHostname=true/false sounds fine).

Colm.

On Tue, Apr 28, 2015 at 7:48 PM, David Mansfield <[email protected]> wrote:

Yes.  Does the below summary sound ok?  Not sure how can I get the socket
reference in the auth supplier, but I haven't really looked too hard.

Once I have it ready, I can do a pull request in github or a patch here or
whatever.  What's your preference?

The document http://cxf.apache.org/coding-guidelines.html doesn't seem
too stringent, I'll be careful I promise!

Thanks,
David

On 04/28/2015 06:54 AM, Colm O hEigeartaigh wrote:

Would you be willing to submit a patch for this?

Colm.

On Mon, Apr 27, 2015 at 5:44 PM, David Mansfield <[email protected]>
wrote:

  Hi All,
Most (*) SPNEGO client implementations will canonicalize a host name when
using it to create a service principal.

CXF seems to be an exception.  If a CNAME is used, say:
mywebservice.example.com is a CNAME for
sysadmins-like-really-long-hostnames.example.com, most setups will
expect
a request for HTTP/
[email protected]. In this
case, CXF will not be able to authenticate.

I note, is IS possible to specify the servicePrincipalName directly, but
that breaks the transparency of using a CNAME in the first place, as the
configuration will need to reference the specific back-end providing the
service.

Providing hostname canonicalization will fix the need to "know" about the
details behind the scenes.

As this behavior would be a defaults-changing one, maybe we could add
useCanonicalHostname=true/false (default false I guess).

Implementation-wise, I think you need to get the socket, and then:

    socket.getInetAddress().getCanonicalHostName()

This would replace:
   uri.getHost()

that is currently used in
org.apache.cxf.transport.http.auth.AbstractSpnegoAuthSupplier


(*) Most that I have personally used :-)

--
Thanks,
David Mansfield
Cobite, INC.





Reply via email to