Versions Compared

Key

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

...

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

Encrypted

...

Tokens

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.

...

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.

Authorization Code

As described above, AuthorizationCodeGrantService service and AuthorizationCodeDataProvider data provider can support a redirection-based Authorization Code flow.

...

Implicit grant is supported the same way Authorization Code grant is except that the response no code is created, a token is issued immediately and returned to the client running within a web browser is formatted differently, using URI fragments.

ImplicitGrantService service and AuthorizationCodeDataProvider asks OAuthDataProvider data provider can support a redirection-based Implicit flowto issue a new token after a user has approved it.

Note the only difference is the use of ImplicitGrantService instead of AuthorizationCodeGrantService.

...

Client Credentials

Register ClientCredentialsGrantHandler handler with AccessTokenService for this grant be supported.

CXF-based clients can use a helper ClientCredentialsGrant bean to request a new access token with OAuthClientUtils.

Resource Owner Password Credentials

Register ResourceOwnerGrantHandler handler with AccessTokenService for this grant be supported.

...

CXF-based clients can use a helper RefreshTokenGrant bean to request a new access token with OAuthClientUtils.

SAML and JWT Assertions

SAML2 Bearer and JWT assertions can be used as token grants.

Please see JAXRS OAuth2 Assertions section for more information.

 

Custom Grants

If you need to customize the way the well-known grant requests are handled then consider extending one of the grant handlers listed in the previous sub-sections.

Alternatively create a custom AccessTokenGrantHandler and register it with AccessTokenService. Additionally, consider providing a related related AccessTokenGrant implementation for making it easy for the client code to request a new access token with this custom grant.

Redirection Flow Filters

AuthorizationCodeRequestFilter AuthorizationRequestFilter implementations can be registered with AuthorizationCodeService AuthorizationCodeGrantService or ImplicitGrantService in order to pre-process code requests. For example, JwtRequestCodeFilter can be used to process JWS-signed or JWE-encrypted code requests.

AuthorizationCodeResponseFilter implementations can be registered with AuthorizationCodeService in order to post-process code responses.

AccessTokenResponse Filters

AccessTokenResponseFilter implementations can be registered with AccessTokenService in order to post-process access token responses. For example,  OIDC id_token IdToken can be added to a response with a filter. Filters can also calculate an access token response signature, etc IdTokenResponseFilter.

PreAuthorized access tokens

...

Using CXF OAuth service implementations will help a lot with setting up an OAuth server. As you can see from the above sections, these services rely on a custom OAuthDataProvider implementation.

The main task of OAuthDataProvider is to persist and generate access tokens. Additionally, as noted above, AuthorizationCodeDataProvider needs to persist and remove the code grant registrations. The way it's done is really application-specific. Consider starting with a basic memory based implementation and then move on to keeping the data in some DB.

Note that OAuthDataProvider supports retrieving Client instances but it has no methods for creating or removing Clients. The reason for it is that the process of registering third-party clients is very specific to a particular OAuth2 application, so CXF does not offer a registration support service and hence OAuthDataProvider has no Client create/update methods. You will likely need to do something like this:

...

public class CustomOAuthProvider implements OAuthDataProvider {
   public Client registerClient(String applicationName, String applicationURI, ...) {}
   public void removeClient(String cliendId) {}
   // etc
   // OAuthDataProvider methods
}

CustomOAuthProvider will also remove all tokens associated with a given Client in removeClient(String cliendId).

Finally OAuthDataProvider may need to convert opaque scope values such as "readCalendar" into a list of OAuthPermissions. AuthorizationCodeGrantService and OAuth2 security filters will depend on it (assuming scopes are used in the first place). In the former case AuthorizationCodeGrantService will use this list to populate OAuthAuthorizationData - the reason this bean only sees Permissions is that some of the properties OAuthPermission keeps are of no interest to OAuthAuthorizationData handlers.Finally OAuthDataProvider may need to convert opaque scope values such as "readCalendar" into a list of OAuthPermissions. AuthorizationCodeGrantService and OAuth2 security filters will depend on it (assuming scopes are used in the first place). 

Default Providers

CXF 3.1.7 ships JPA2 (JPAOAuthDataProvider and JPACodeDataProvider), Ehcache (DefaultEHCacheOAuthDataProvider and DefaultEHCacheCodeDataProvider) and JCache (JCacheOAuthDataProvider and JCacheCodeDataProvider) provider implementations which take care of all the persistence tasks: saving or removing registered clients, tokens and code grants. These providers can be easily customized.

...

Keeping the state in the session

Note that that SessionAuthenticityTokenProvider has been further updated in CXF 3.1.0 to support signing and/or encrypting some of the redirection properties that would otherwise have to be kept as HTML form hidden fields (see "Authorization Service" section).

CXF  ships org.apache.cxf.rs.security.oauth2.provider.JoseSessionTokenProvider ships JoseSessionTokenProvider which uses CXF JOSE that can be used as a SessionAuthenticityTokenProvider which JWS-signs and/or JWE-encrypts the properties and saves the result in the session. The HTML authorization forms will only have to have an "authenticityToken" property which the provider will use to match the session signed/encryped data and decrypt and/or validate the session data.

Multiple Factor Verification

Note that that SessionAuthenticityTokenProvider has been updated in CXF 3.0.2 to accept request parameters and a reference to the authenticated user. This allows for introducing a multiple factor session verification: when the provider created a session property it can for example sent a message to a user's mobile phone expect the authorization consent form return the sent value.

...

Protecting resources with OAuth filters

OAuthRequestFilter request handler can be used to protect the resource server when processing the requests from the third-party clients. Add it as a jaxrs:provider to the endpoint which deals with the clients requesting the resources.

...

1. Retrieve a ServerAccessToken by delegating to a matching registered AccessTokenValidator. AccessTokenValidator is expected to check the validity of the incoming token parameters and possibly delegate to OAuthDataProvider to find the token representation - this is what the filter will default to if no matching AccessTokenValidator is found and the Authorization scheme is 'Bearer'.

...

3. AccessToken may have a list of OAuthPermissions OAuthPermission. For every permission it will:

...

4. Finally, it will create a CXF SecurityContext using this list of OAuthPermissions, the UserSubject representing the client or the end user who authorized the grant used to obtain this token.

...

If you use HTTP Authorization header or WS-Security Binary token to pass OAuth2 tokens to SOAP endpoints then OAuthRequestInterceptor can be used to validate such tokens. It is OAuthRequestFilter running as CXF interceptor which will work OOB for tokens passed with Authorization header and it can be easily extended to support WS-Security binary tokens

...

The injected MessageContext provides an access to OAuthContext which has been set by OAuth2 filters described in the previous section. OAuthContext will act as a container of the information which can be useful to the custom application code which do not need to deal with the OAuth2 internals. OAuthContextUtils provides a number of utility methods for retrieving and working with OAuthContext.

...

JAX-RS makes it straightforward to support the redirection, while OAuthClientUtils class makes it possible to encapsulate most of the complexity away from the client application code, so ultimately the code required to support is typically not that complex at all, while at the same it offers the most flexibility.

...

Note that in the above example, an instance of AuthorizationCodeGrant is passed as the last parameter to OAuthClientUtils.getAccessToken() method, alongside the references to the AccessTokenService client and OAuthClientUtils.Consumer bean keeping the client id and secret.

CXF provides the utility grant beans for all the grants it supports, AuthorizationCodeGrant, ClientCredentialsGrant, ResourceOwnerGrant and RefreshTokenGrantsee the information on grants above. Please use the appropriate grant bean relevant to your application when requesting an access token or create a custom AccessTokenGrant bean implementation.

...

Also note that AuthorizationCodeGrantService can return XML or JSON OAuthAuthorizationData representations. That makes it easy for a client code to get OAuthAuthorizationData and offer a pop-up window or get the input from the command-line. Authorizing the third-party application might even be automated in this case - which can lead to a complete 3-leg OAuth flow implemented without a human user being involved.

Reporting error details

This section lists all the error properties that can be returned to the client application. CXF OAuth2 services will always report a required 'error' property but will omit the optional error properties by default (for example, in case of access token grant handlers throwing OAuthServiceException initialized with OAuthError which may have the optional properties set).
When reporting the optional error properties is actually needed then setting a 'writeCustomErrors' property to 'true' will help:

Code Block
xml
xml
<bean id="oauthProvider" class="oauth2.manager.OAuthManager"/>

<bean id="accessTokenService" class="org.apache.cxf.rs.security.oauth2.services.AccessTokenService">
    <property name="dataProvider" ref="oauthProvider"/>
    <property name="writeCustomErrors" value="true"/>
</bean>

OAuth2 and JOSE

See JAX-RS Jose wiki page for the information about JOSE and how it is supported in CXF,

//TODO: describe how Jose is used in CXF OAuth2

"true"/>
</bean>

OAuth2 and JOSE

See JAX-RS JOSE wiki page for the information about JOSE and how it is supported in CXF,

CXF OAuth2 depends on its JOSE implementation which is referred to the sections above. Particularly:

OAuth2 and OIDC

 //TODO

CXF shipis OIDC RP and IDP service code which depends on its OAuth2 and JOSE implementations. See this page for more information.

Design considerations

This section will talk about various design considerations one need to take into account when deploying OAuth-based solutions.

...

Let's assume that the 3rd party client has been allowed to read the public user Calendars at "/calendar/{id}" only, how to make sure that the client won't try to:
1. update the calendar available at the same path
2. read the private Calendars available at "/calendar/{id}/private"

As noted above, OAuthPermission has an optional URIs property. Thus one way to solve the problem with the private calendar is to add, say, a uri "/calendar/{id}" or "/calendar/1" (etc) property to OAuthPermission (representing a scope like "readCalendar") and the OAuth filter will make sure no subresources beyond "/calendar/{id}" can be accessed. Note, adding a "*" at the end of a given URI property, for example, "/a*" will let the client access "/a", "/a/b", etc.

...

CXF 2.6.1 provides an initial support for a SAML2 SSO SP profile. This will make it easier to minimize a number of sign ins to a single attempt and run OAuth2 Authorization servers separately from the application endpoints.

The work started in CXF 3.1.0 for integrating with 7 offers OpenId Connect RP support.