Token Authentication and Token Management
General
The token based authentication has been completely refactor in Oak and has the following general characteristics.
- Dedicated API for managing login tokens defined in the package
org.apache.jackrabbit.oak.spi.security.authentication.token
. - Pluggable configuration of the new token management API
- Complete separation of token based authentication into a separate
LoginModule
.
Token Authentication
As of Oak the token based authentication is handled by a dedicated TokenLoginModule. It is both responsible for creating new login tokens and validating TokenCredentials passed to the repository login.
This token specific login module implementation obtains the TokenProvider from the security configuration as defined for the content repository. The token management implementation present with a given repository can be changed or extended at runtime (see section Configuration below).
TokenLoginModule
The TokenLoginModule
designed to support and issue TokenCredentials
. The
authentication phases behave as follows:
Phase 1: Login
- if no
TokenProvider
is available returnsfalse
- if a
TokenProvider
has been configured it retrieves JCR credentials from the CallbackHandler using the CredentialsCallback - in case of
TokenCredentials
validates these credentials: if it succeeds it pushes the users ID to the shared state and returnstrue
; otherwise throwsLoginException
- for other credentials the method returns
false
Phase 1: Commit
- if phase 1 succeeded the subject is populated and the method returns
true
- in case phase 1 did not succeed this method will test if the shared state contain
credentials that ask for a new token being created; if this succeeds it will
create a new instance of
TokenCredentials
, push the public attributes to the shared stated and update the subject with the new credentials; finally the commit call returnsfalse
Example JAAS Configuration
jackrabbit.oak {
org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule sufficient;
org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl required;
};
Token Management API
Oak 1.0 defines the following interfaces used to manage login tokens:
- TokenConfiguration: Interface to obtain a
TokenProvider
instance (see section configuration below). - TokenProvider: Interface to read and manage login tokens.
- TokenInfo: Information associated with a given login token and token validity.
In addition Oak comes with a default implementation of the provider interface
that is able to aggregate multiple TokenProvider
s:
- CompositeTokenConfiguration: Extension of the
CompositeConfiguration
to combined different token management implementations. - CompositeTokenProvider: Aggregation of the
TokenProvider
implementations defined by the configurations contained theCompositeTokenConfiguration
See section Pluggability for an example.
Characteristics of the Default Implementation
The characteristics of the default token management implementation is described in section Token Management : The Default Implementation.
Configuration
The configuration options of the default implementation are described in the Configuration section.
Pluggability
The default security setup as present with Oak 1.0 is able to deal with
custom token management implementations and will collect multiple
implementations within CompositeTokenConfiguration
present with the
SecurityProvider
. The CompositeTokenConfiguration
itself will
combine the different TokenProvider
implementations using the CompositeTokenProvider
.
In an OSGi setup the following steps are required in order to add a custom token provider implementation:
- implement
TokenProvider
interface - expose the custom provider by your custom
TokenConfiguration
service - make the configuration available to the Oak repository.
- make sure the
TokenConfiguration
is listed as required service with the SecurityProvider (see also Introduction)
Examples
Example TokenConfiguration
@Component()
@Service({TokenConfiguration.class, SecurityConfiguration.class})
public class MyTokenConfiguration extends ConfigurationBase implements TokenConfiguration {
public TokenConfigurationImpl() {
super();
}
public TokenConfigurationImpl(SecurityProvider securityProvider) {
super(securityProvider, securityProvider.getParameters(NAME));
}
@Activate
private void activate(Map<String, Object> properties) {
setParameters(ConfigurationParameters.of(properties));
}
//----------------------------------------------< SecurityConfiguration >---
@Nonnull
@Override
public String getName() {
return NAME;
}
//-------------------------------------------------< TokenConfiguration >---
@Nonnull
@Override
public TokenProvider getTokenProvider(Root root) {
return new MyTokenProvider(root, getParameters());
}
}