Versions Compared

Key

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

...

Table of Contents

Introduction

New:

  • Ehcache and JCache OAuthDataProviders can represent access tokens in JWT OAuth2 module now depends on CXF cxf-rt-rs-security-jose module with the utility code in place to support a number of OAuth2 features depending on JOSE

CXF provides the implementation of OAuth 2.0. See also the JAX-RS OAuth page for information about OAuth 1.0.

...

where 'ts' attribute is used to pass a timestamp value.

Encrypted Tokens

Note: consider using JWE Encryption with JWT access tokens (see next section).

Typically, the tokens are persisted in the storage. The alternative approach is to completely encrypt the token state and return the encrypted representation back to a client: the processing time to do with the encryption and decryption might increase but the server wins on avoiding the DB / storage lookups.    

...

Code Block
SecretKey key = CryptoUtils.getSecretKey();

// create a new token, encrypt its state and return

ServerAccessToken token = new BearerAccessToken(client, 3600L);

String encryptedToken = ModelEncryptionSupport.encryptAccessToken(token, key);

token.setTokenKey(encryptedToken);

return token;

// decrypt a token given a token key

ModelEncryptionSupport.decryptAccessToken(this, encryptedToken, key);
 

JWT Tokens

JWT Token can be JWE-encrypted and the encrypted string passed to ServerAccessToken as access token id parameter.

Starting from CXF 3.1.8 some of CXF OAuthDataProvider implementations (EhCache and JCache based) support Access Token representations in JWT. This means that ServerAccessTokens created by data providers are converted to a sequence of JSON JWT claims and then JWS signed and/or JWE encrypted.

Custom data providers can extend AbstractOAuthDataProvider to depend on the code which converts ServerAccessTokens to JWT and use JwtTokenUtils to convert JOSE token representations back to ServerAccessToken.

For example, here is how one can configure an Ehcache or JCache based provider to use JWT:

Code Block
<bean id="oauthProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuthDataProviderImpl">
       <property name="useJwtFormatForAccessTokens" value="true"/>
</bean>

 

Additionally, in order to sign and/or encrypt, this provider can be injected with an instance of OAuthJoseJwtProducer or AccessTokenService endpoint where this provider is registered can be configured as follows:

 

Code Block
<jaxrs:server id="oauthServer1" address="https://localhost:${testutil.ports.jaxrs-oauth2-serviceJwt}/services">
 <jaxrs:serviceBeans>
   <ref bean="tokenService"/>
</jaxrs:serviceBeans><!-- Sign -->
<jaxrs:properties>
 <entry key="rs.security.signature.properties" value="org/apache/cxf/systest/jaxrs/security/alice.rs.properties"/>
 <entry key="rs.security.signature.key.password.provider" value-ref="keyPasswordProvider"/>
 </jaxrs:properties>
 </jaxrs:server>

 

Note that Ehcache and JCache providers will still persist the complete ServerAccessToken representations - once JOSE sequence is created it becomes a new tokenId of the current ServerAccessToken, with the original tokenId becoming a JWT 'jti' claim.

One can configure the providers to persist access tokens only as these newly created JOSE sequences:

 

Code Block
<bean id="oauthProvider" class="org.apache.cxf.systest.jaxrs.security.oauth2.common.OAuthDataProviderImpl">
       <property name="useJwtFormatForAccessTokens" value="true"/>
       <property name="storeJwtTokenKeyOnly" value="true"/>
</bean>

Only a JOSE sequence representing a given ServerAccessToken will be persisted. The providers will recreate ServerAccessToken from this sequence when the token is needed by the runtime.

 

Resource server (RS) will need to make a decision how to validate this JWT token. It can continue validating it remotely with AccessTokenValidationService or TokenIntrsopectionService (see below for more info about these services) or if RS has an access to the keys used to sign/encrypt JWT then it can use a local JWT validation, example:

 

Code Block
<bean id="jwtTokenValidator" class="org.apache.cxf.rs.security.oauth2.filters.JwtAccessTokenValidator"/>
<bean id="oAuthFilterLocalValidation" class="org.apache.cxf.rs.security.oauth2.filters.OAuthRequestFilter">
    <property name="tokenValidator" ref="jwtTokenValidator"/>
</bean>
   
<jaxrs:server 
    depends-on="tls-config" 
    address="https://localhost:${testutil.ports.jaxrs-oauth2-filtersJwt}/securedLocalValidation">
    <jaxrs:serviceBeans>
        <ref bean="serviceBean"/>
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <ref bean="oAuthFilterLocalValidation"/>
    </jaxrs:providers>
    <jaxrs:properties>
         <entry key="rs.security.signature.in.properties" value="org/apache/cxf/systest/jaxrs/security/alice.rs.properties"/>
    </jaxrs:properties>
</jaxrs:server>

 

When to use JWT ? The pros are: might be easier to align with some newer OAuth2 related specifications, might be possible to avoid a remote validation call, possible OAuth2 server storage optimization. Cons: the extra cost of validating (or decrypting), access token value reported to and used by clients becomes larger. If JWS only is used - care should be taken to avoid putting some sensitive JWT claims given that JWS payload can be introspected.

 

See JAX-RS JOSE wiki page for more information on how to See JAX-RS JOSE wiki page for more information on how to sign and encrypt JSON Web Tokens.

JwtAccessTokenUtils provides utility method for encrypting and decrypting an access token represented as JWT.

Note more support for JWT access tokens is on the way. 

Custom tokens

If needed, users can use their own custom token types, with the only restriction that the custom token type implementations have to extend org.apache.cxf.rs.security.oauth2.common.ServerAccessToken.

...

Note, OAuthDataProvider implementations processing a revocation request should simply ignore the invalid tokens as recommended by the specification which will let TokenRevocationService return HTTP 200 which is done to minimize a possible attack surface (specifically for bad clients not to see if their requests failed or succeeded) and throw the exceptions only if the token revocation feature is not currently supported.

DynamicRegistrationService

This service is currently a work in progress and may become available in CXF 3.1.8 or CXF 3.1.9. It will support the dynamic client registration and management.

AuthorizationMetadatService

This service is currently a work in progress and may become available in CXF 3.1.8 or CXF 3.1.9. It will support OAuth2 server configuration queries at ".well-known/oauth-authorization-server".

Supported Grants

The following subsections briefly describe how the well-known grant types can be supported on the server side. Please also check the "Client Side Support" section on how to use the related AccessTokenGrant implementations to request the access tokens.

...