Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

 

...

 

Span
style

font-size:2em;font-weight:bold

...

JAX-RS

...

Kerberos

...

Support
 

 

 

Table of Contents

Introduction

Please see MIT Kerberos Tutorial for a good introduction to Kerberos.
The Windows guide as well as this Wikipedia page are also worth checking.

Setup

Unix

1. Install the packages

> sudo apt-get install krb5-kdc krb5-admin-server

During the installation enter "localhost" as the host name for Kerberos servers (unless you have more specific host names to enter) and set a default realm, example, "MYCOMPANY.COM".

...

Follow

...

the

...

1.2

...

step

...

from

...

this

...

blog

...

entry

...

to

...

get

...

this

...

default

...

realm

...

set

...

up

...

properly.

...

2.

...

Create

...

principals

...

From

...

the

...

step

...

1.3

...

at

...

this

...

blog

...

entry

...

:

2.1

...

Create

...

master

...

key:

...


>

...

sudo

...

kdb5_util

...

create

...

-s

...

2.2

...

Create

...

user

...

and

...

service

...

principals

...

>

...

sudo

...

kadmin.local

...

followed

...

by

...

>

...

addprinc

...

alice

...


>

...

addprinc

...

HTTP/localhost

...

where

...

'HTTP/localhost'

...

is

...

the

...

typical

...

service

...

principal

...

name

...

used

...

in

...

the

...

Negotiate

...

scheme,

...

replace

...

'localhost'

...

if

...

needed.

...


Add

...

more

...

user

...

and

...

service

...

principals

...

too

...

as

...

required.

...

3

...

Start

...

KDC

...

>

...

sudo

...

krb5kdc

...

4.

...

Create

...

an

...

optional

...

ticket

...

cache

...

>

...

klist

...

returns

...

an

...

empty

...

response

...

>

...

kinit

...

alice

...

>

...

klist

...

confirms

...

a

...

TGT

...

for

...

'alice'

...

is

...

in

...

the

...

cache.

...

2.4

...

Create

...

keytabs

...

When

...

keytabs

...

are

...

available,

...

the

...

principal

...

password

...

does

...

not

...

have

...

to

...

be

...

specified

...

in

...

the

...

login

...

configuration.

...


Please

...

follow

...

the

...

step

...

1.4

...

from

...

this

...

blog

...

entry.

Note, creating a keytab actually resets an original principal password, example, after creating a keytab for 'alice' one would not be able to use the original password (TODO: apparently this can be restored - find out how). Thus, if you'd like to experiment with keytabs then you may want to have few user and service principals created, with only selected principals using keytabs.

Windows

Please check the relevant Windows configuration guide such as this one.

HTTP Negotiate scheme

'Negotiate' authentication scheme is used to pass Kerberos service tickets over HTTP.
Example:

Code Block
java
java
|http://coheigea.blogspot.com/2011/10/using-kerberos-with-web-services-part-i.html].

Note, creating a keytab actually resets an original principal password, example, after creating a keytab for 'alice' one would not be able to use the original password (TODO: apparently this can be restored - find out how). Thus, if you'd like to experiment with keytabs then you may want to have few user and service principals created, with only selected principals using keytabs. 

h3. Windows

Please check the relevant Windows configuration guide such as [this one|http://technet.microsoft.com/en-us/library/cc753173%28v=ws.10%29].

h2. HTTP Negotiate scheme 

'Negotiate' authentication scheme is used to pass Kerberos service tickets over HTTP.
Example:
{code:java}
Authorization: Negotiate "the encrypted service ticket"
{code} 

h2. GSS API

Please see [this|http://docs.oracle.com/javase/7/docs/technotes/guides/security/jgss/tutorials/index.html] GSS API tutorial as well as check this [blog|http://www.javaactivedirectory.com/] for a number of GSS API examples. Understanding GSS API may help when the way CXF Kerberos handlers work needs to be customized or when the available GSS credentials created outside of CXF need to be made available to CXF (for the credential delegation). 

h2. JAAS Kerberos Module Configuration

[

GSS API

Please see this GSS API tutorial as well as check this blog for a number of GSS API examples. Understanding GSS API may help when the way CXF Kerberos handlers work needs to be customized or when the available GSS credentials created outside of CXF need to be made available to CXF (for the credential delegation).

JAAS Kerberos Module Configuration

com.sun.security.auth.module.Krb5LoginModule

...

is

...

typically

...

used

...

to

...

login

...

to

...

Kerberos

...

servers.

...

Client

...

configuration

...

HTTPConduit

Please see this page for the information about Spnego/Kerberos HTTPConduit client support.

Interceptor

org.apache.cxf.jaxrs.security.KerberosAuthOutInterceptor

...

can

...

be

...

used

...

as

...

an

...

alternative

...

to

...

configuring

...

HTTPConduit.

...

KerberosAuthOutInterceptor

...

and

...

the

...

HTTPConduit

...

Spnego

...

handler

...

share

...

the

...

same

...

base

...

code.

...

Having

...

HTTPConduit

...

configuration

...

can

...

be

...

enough

...

in

...

many

...

cases

...


especially

...

when

...

SSL

...

is

...

also

...

being

...

setup

...

at

...

the

...

conduit

...

level.

...

Using

...

the

...

interceptor

...

can

...

be

...

handy

...

when

...

testing

...

as

...

well

...

as

...

when

...

setting

...

few

...

extra

...

properties

...

which

...

is

...

not

...

easy

...

to

...

set

...

up

...

at

...

the

...

generic

...

HTTP

...

Conduit

...

Authorization

...

Policy

...

level.

...

The

...

interceptor

...

properties

...

are

...

explained

...

in

...

the

...

following

...

sub-sections

...

Authorization

...

Policy

...

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
java
java


{code:java}
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);
{code}

In

...

this

...

example,

...

the

...

KerberosClientKeyTab

...

policy

...

is

...

used

...

which

...

links

...

to

...

the

...

available

...

keytab;

...

otherwise

...

AuthorizationPolicy

...

'UserName'

...

and

...

'Password'

...

properties

...

would

...

most

...

likely

...

have

...

to

...

be

...

set

...

too

...

(with

...

the

...

possible

...

exceptions

...

on

...

Windows)

...

Configuring the service principal name

Service principal identifies a target service.

By default, the service principal name is calculated by concatenating "HTTP",

...

"/"

...

and

...

the

...

name

...

of

...

the

...

target

...

host,

...

example,

...

when

...

invoking

...

on

...

"http://localhost:8080/services",

...

the

...

service

...

principal

...

name

...

is

...

set

...

to

...

"HTTP/localhost".

...

The

...

"servicePrincipalName"

...

and

...

"realm"

...

properties

...

can

...

be

...

used

...

to

...

customize

...

it,

...

example,

...

setting

...

"servicePrincipalName"

...

to

...

"HTTP/www.mycompany.com"

...

and

...

realm

...

to

...

"services.org"

...

will

...

result

...

in

...

the

...

"HTTP/www.mycompany.com@services.org"

...

service

...

principal

...

name

...

being used.

When the "servicePrincipalName" is not specified, the target host from the provided endpoint URL is used to construct one as-is.  To perform canonicalization of this hostname (e.g. if a CNAME record host.example.com points to an A record host-x.example.com, then use "host-x.example.com" when constructing the servicePrincipalName), the "useCanonicalHostname" property can be set to "true".

Using JAAS Configuration

Both HTTPConduit and interceptor handlers need a "java.security.auth.login.config"

...

system

...

property

...

set

...

up.

...

This

...

property

...

needs

...

to

...

point

...

to

...

the

...

file

...

containing

...

the

...

configuration

...

of

...

the

...

specific

...

Kerberos

...

login

...

module.

...

Instead

...

of

...

setting

...

this

...

system

...

property

...

and

...

maintaining

...

a

...

configuration

...

file,

...

one

...

might

...

want

...

to

...

use

...

an

...

implementation

...

of

...

javax.security.auth.login.Configuration

...

and

...

set

...

it

...

on

...

the

...

interceptor

...

as

...

a

...

"loginConfig"

...

property.

How to avoid setting username and password properties

Typically, one may have to set AuthorizationPolicy UserName and Password properties for the Kerberos login module to authenticate the user.

The next option is to create a keytab as noted in the Setup section, which will let one to avoid specifying a password property.
Finally, if the user actually owns the Java process which runs the code then no username and password properties have to be provided, assuming the Kerberos login configuration has 'useTicketCache' and possibly 'renewTGT' properties set to "true"

Server configuration

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
xml
xml


{code:xml}

<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>
{code}

KerberosAuthenticationFilter

...

will

...

set

...

a

...

CXF

...

SecurityContext

...

on

...

the

...

current

...

message

...

if

...

the

...

authentication

...

has

...

been

...

successful.

...

This

...

SecurityContext

...

will

...

return

...

an

...

instance

...

of

...

KerberosAuthenticationFilter$KerberosPrincipal,

...

this

...

Principal

...

will

...

return

...

a

...

'simple'

...

and

...

'kerberos'

...

source

...

principal

...

names,

...

example,

...

given

...

"HTTP/localhost@myrealm.com",

...

Principal#getName

...

will

...

return

...

"HTTP/localhost",

...

and

...

KerberosPrincipal#getKerberosName

...

will

...

return

...

"HTTP/localhost@myrealm.com".

...

Service

...

principal

...

name

...

and

...

JAAS

...

Configuration

...

Service

...

principal

...

name

...

and

...

JAAS

...

Configuration

...

can

...

be

...

optionally

...

set

...

up

...

the

...

same

...

way

...

they

...

can

...

be

...

with

...

KerberosAuthOutInterceptor,

...

using

...

'servicePrincipalName'

...

+

...

'realm'

...

and

...

"loginConfig"

...

properties.

...

CallbackHandler

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
java
java


{code:java}
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();
 }
}
{code} 

In this 

In this example,

...

the

...

KerberosServer

...

policy

...

is

...

used.

...

Credential

...

Delegation

...

Please

...

see

...

this

...

section

...

on

...

the

...

way

...

client-side

...

credential

...

delegation

...

can

...

be

...

both

...

enabled

...

and

...

implemented

...

at

...

the

...

HTTP

...

conduit

...

level.

...

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
java
java


{code:java}

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

}
{code}

The

...

HTTPConduit

...

or

...

KerberosAuthOutInterceptor

...

handler

...

will

...

use

...

the

...

available

...

GSSCredential.

...

Also

...

note

...

that

...

KerberosAuthOutInterceptor

...

can

...

have

...

its

...

"credDelegation"

...

property

...

set

...

to

...

"true"

...

if

...

it

...

is

...

used

...

instead

...

of

...

HTTPConduit

...

on

...

the

...

client

...

side,

...

when

...

enabling

...

the

...

delegation

...

initially.

...