Authentication with External Login Module : Examples
- Authentication with External Login Module : Examples
Integration with Standard Oak Authentication used for Apache Sling
The following JAAS configuration can be used in combination with Apache Sling.
Example JAAS Configuration
Example {
org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule optional;
org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule sufficient;
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModule sufficient
sync.handlerName="your-synchandler_name"
idp.name="your_idp_name";
org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl sufficient;
};
Understanding the Configuration
The LoginModule Sequence
-
The
GuestLoginModule
is in charge of handling unauthenticated guest login without passing [GuestCredentials]. In other words: if no credentials can be obtained during the login phase, an new instance of [GuestCredentials] is pushed to the shared state and this module succeeds. Due to the optional flag success is not required and the authentication proceeds down the list of modules. This module helps to cover non-standard guest login withnull
credentials as it is performed by Apache Sling (compatibility with Jackrabbit 1.0) -
The
TokenLoginModule
is in charge of handling repository authentication request withTokenCredentials
:- Login Success: If token-login succeeds the sufficient flag makes sure
authentication does not proceed down the
LoginModule
list. This means that it will not hit theExternalIdentityProvider
and will not re-sync an external user as long as the login token is valid. - Login Failure: If it fails (e.g. other type of
Credentials
) the authentication will proceed down theLoginModule
list. - Commit: If the login failed the login module will test if the
Credentials
passed to the login ask for generation of a new login token. If this login succeeded it will populate theSubject
withPrincipal
s,Credentials
andAuthInfo
.
NOTE: In this setup the
TokenLoginModule
is expected to only handle subsequent authentication request after having issued a login token. The latter is achieved by providingCredentials
attributes that force theTokenLoginModule
to generate a new login token in the commit phase. The application should then use that login toke for subsequent requests.See Token Authentication and Token Management for details and for a description of the default implementation.
- Login Success: If token-login succeeds the sufficient flag makes sure
authentication does not proceed down the
-
The
ExternalLoginModule
is in charge of handling authentication request for users managed by anExternalIdentityProvider
.-
Login Success: If user authentication against the IDP succeeds the module synchronizes the external user into the repository according to the logic defined in the configure
SyncHandler
. If the user has been synced before it might be updated. If and how often a user gets re-synced is an implementation detail of theSyncHandler
. -
Login Failure: If the authentication fails (e.g. wrong IDP or invalid
Credentials
), the login will proceed to theLoginModuleImpl
. -
Commit: If the login succeeded the login module will populate the
Subject
withPrincipal
s,Credentials
andAuthInfo
.NOTE: if no login token is generated upon first login, any subsequent login for external users will end up being handled by this module (including connection to the IDP) or fail.
-
-
The
LoginModuleImpl
is in charge of handling authentication request for users managed and created through the repository's user management API; i.e. users that are not defined by anExternalIdentityProvider
. This includes built-in system users like the administrator, the guest-user (aka anonymous) orSystemUsers
. It also handles impersonation logins.-
Login Success: If regular user authentication (or impersonation) succeeds the sufficient flag makes sure authentication does not proceed down the
LoginModule
list i.e. omits unnecessarily trying to authenticate a local user against the external IDP. -
Login Failure: If the authentication fails (e.g. no local user that could have uid/pw matching the passed
Credentials
), it will continue down theLoginModule
list. -
Commit: If the login succeeded the login module will populate the
Subject
withPrincipal
s,Credentials
andAuthInfo
.NOTE: if no login token is generated upon first login, any subsequent login for local users will end up being handled by this module or fail.
-
Integration with Standard Oak Authentication
Example JAAS Configuration
Example {
org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule sufficient;
org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl sufficient;
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModule required
sync.handlerName="your-synchandler_name"
idp.name="your_idp_name";
};
Understanding the Configuration
The LoginModule Sequence
-
The
TokenLoginModule
is in charge of handling repository authentication request withTokenCredentials
:- Login Success: If token-login succeeds the sufficient flag makes sure
authentication does not proceed down the
LoginModule
list. This means that it will not hit theExternalIdentityProvider
and will not re-sync an external user as long as the login token is valid. - Login Failure: If it fails (e.g. other type of
Credentials
) the authentication will proceed down theLoginModule
list. - Commit: If the login failed the login module will test if the
Credentials
passed to the login ask for generation of a new login token. If this login succeeded it will populate theSubject
withPrincipal
s,Credentials
andAuthInfo
.
NOTE: In this setup the
TokenLoginModule
is expected to only handle subsequent authentication request after having issued a login token. The latter is achieved by providingCredentials
attributes that force theTokenLoginModule
to generate a new login token in the commit phase. The application should then use that login toke for subsequent requests.See Token Authentication and Token Management for details and for a description of the default implementation.
- Login Success: If token-login succeeds the sufficient flag makes sure
authentication does not proceed down the
-
The
LoginModuleImpl
is in charge of handling authentication request for users managed and created through the repository's user management API; i.e. users that are not defined by anExternalIdentityProvider
. This includes built-in system users like the administrator, the guest-user (aka anonymous) orSystemUsers
. It also handles impersonation logins.-
Login Success: If regular user authentication (or impersonation) succeeds the sufficient flag makes sure authentication does not proceed down the
LoginModule
list i.e. omits unnecessarily trying to authenticate a local user against the external IDP. -
Login Failure: If the authentication fails (e.g. no local user that could have uid/pw matching the passed
Credentials
), it will continue down theLoginModule
list. -
Commit: If the login succeeded the login module will populate the
Subject
withPrincipal
s,Credentials
andAuthInfo
.NOTE: if no login token is generated upon first login, any subsequent login for local users will end up being handled by this module or fail.
-
-
The
ExternalLoginModule
is in charge of handling authentication request for users managed by anExternalIdentityProvider
.-
Login Success: If user authentication against the IDP succeeds the module synchronizes the external user into the repository according to the logic defined in the configure
SyncHandler
. If the user has been synced before it might be updated. If and how often a user gets re-synced is an implementation detail of theSyncHandler
. -
Login Failure: If the authentication fails (e.g. wrong IDP or invalid
Credentials
), the whole login will fail because theExternalLoginModule
is configured to be required and the last module in the chain. -
Commit: If the login succeeded the login module will populate the
Subject
withPrincipal
s,Credentials
andAuthInfo
.NOTE: if no login token is generated upon first login, any subsequent login for external users will end up being handled by this module (including connection to the IDP) or fail.
-
Login with Different Credentials
GuestCredentials
TokenLoginModule
will ignoreLoginModuleImpl
by default supportsGuestCredentials
; success depends on the existence of a valid guest user in the repository. If it succeeds authentication doesn't move down toExternalLoginModule
.ExternalLoginModule
by default doesn't supportGuestCredentials
but may do if a suitableCredentialsSupport
is configured.
SimpleCredentials
TokenLoginModule
will ignoreLoginModuleImpl
by default supportsSimpleCredentials
and it will succeed if the credentials are successfully validated against a local repository user. It is not expected to succeed for synced external users,which should not have their password synced. If it succeeds authentication doesn't move down toExternalLoginModule
.ExternalLoginModule
by default supportSimpleCredentials
and will succeed if authenticating an external against the external IDP including sync is successful. If none of the other modules succeeded theExternalLoginModule
is required to succeed.
TokenCredentials
TokenLoginModule
supportsTokenCredentials
and will succeed if the credentials are valid. If it succeeds authentication doesn't move down the module list. If it fails overall authentication is expected to fail as the subsequent modules are not expected to supportTokenCredentials
.LoginModuleImpl
does not supportTokenCredentials
and will fail.ExternalLoginModule
is not expected to supportTokenCredentials
and thus overall authentication is expected to fail ifTokenLoginModule
failed.
ImpersonationCredentials
TokenLoginModule
will ignoreLoginModuleImpl
by default supportsImpersonationCredentials
and it will succeed if impersonation for the target user is allowed. If it succeeds authentication doesn't move down toExternalLoginModule
.ExternalLoginModule
by default doesn't supportImpersonationCredentials
but may do if a suitableCredentialsSupport
is configured.
Other Credentials
- Overall login success only if the
ExternalLoginModule
supports these credentials TokenLoginModule
will ignoreLoginModuleImpl
will ignoreExternalLoginModule
will only succeed if configured with a suitableCredentialsSupport
that ensures that authentication against the external IDP is successful.
Integration with Pre-Authentication and Login Module Chain
Example JAAS Configuration
Example {
your.org.PreAuthenticationLoginModule optional;
org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl optional;
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModule sufficient
sync.handlerName="your-synchandler_name"
idp.name="your_idp_name";
};
See Pre-Authenticated Login for an example
LoginModule
that illustrates how the pre-authentication is being pushed
to the shared stated.
Note: This configuration has been slightly adjusted from the example in
OAK-3508 marking the pre-auth login to be optional. This highlights
the fact that subsequent LoginModule
s are in charge of respecting the
PreAuthenticatedLogin
marker and properly populating the Subject
in
the second commit phase.
Also, in the example implementation the login never succeeds (in which case
sufficient would actually work as well). However, if it ever succeeded the
PreAuthenticatedLogin
marker would be meaningless and the pre-auth module
in fact would have to populate the Subject
i.e. relying on details
defined and handled by other LoginModule
s.
Understanding the Configuration
The LoginModule Sequence
-
The custom pre-auth module is in charge of handling custom pre-auth
Credentials
shared between the code performing the authentication outside of the scope of the repository and this module. It's only task is to create thePreAuthenticatedLogin
marker and push it to the shared stated to inform subsequent modules, which will always be consulted due to the optional flag. - Login Success: not desired as we want subsequent modules to verify if there is a matching identity for thePreAuthenticatedLogin
and later on populate the subject. - Login Failure: the default passing over the responsibility the other modules in the chain. - Commit: Nothing to do. -
The
LoginModuleImpl
will try to resolve the repository user associated with thePreAuthenticatedLogin
or perform regular login with the loginCredentials
if noPreAuthenticatedLogin
is present. - Login Success: If there exists a valid user for the givenPreAuthenticatedLogin
orCredentials
login will always succeed in case of a pre-auth login. Otherwise credentials are regularly evaluated (e.g. password validation). The authentication will continue down the chain due to the optional flag. - Login Failure: If no matching user exists or if the user is not valid (e.g. disabled). In case of regular authentication it will fail if theCredentials
cannot be validated. Then authentication it will again continue down theLoginModule
list. - Commit: If the login succeeded the login module will populate theSubject
withPrincipal
s,Credentials
andAuthInfo
. -
The
ExternalLoginModule
will try to resolve thePreAuthenticatedLogin
or alternatively theCredentials
to aSyncedIdentity
. - If noSyncedIdentity
exists the user is retrieved from external IDP and eventually synced into the repository. In case noPreAuthenticatedLogin
is present retrieving identity additionally includes credentials validation. - If there exists aSyncedIdentity
the module will validate it. In case ofPreAuthenticatedLogin
it checks if the identity needs to be synced again. - Login Success: If there exists a valid external identity on the IDP and it has be synced with the repository. - Login Failure: If no matching/valid identity exists on the IDP or if there exists aSyncedIdentity
that doesn't belong to the IDP or we have aPreAuthenticatedLogin
marker and theSyncedIdentity
doesn't need a re-sync. - Commit: If the login succeeded the login module will populate theSubject
withPrincipal
s,Credentials
andAuthInfo
.
Login with Different Credentials
Custom Pre-Auth Credentials
- Custom pre-auth module will push
PreAuthenticatedLogin
on the shared state - Overall login suceeds if any of the subsequent modules is able to deal
with the
PreAuthenticatedLogin
.
GuestCredentials
- Custom pre-auth module will ignore
- Overall login success if the subsequent modules allow for login with
GuestCredentials
LoginModuleImpl
by default supportsGuestCredentials
; success depends on the existence of a valid guest user in the repository.ExternalLoginModule
by default doesn't supportGuestCredentials
but may do if a suitableCredentialsSupport
is configured.
SimpleCredentials
- Custom pre-auth module will ignore
- Overall login success if the subsequent modules allow for login with
SimpleCredentials
LoginModuleImpl
by default supportsSimpleCredentials
and it will succeed if the credentials are successfully validated against a local repository user.ExternalLoginModule
by default supportSimpleCredentials
and will succeed if authentication against the external IDP including sync is successful.
ImpersonationCredentials
- Custom pre-auth module will ignore
- Overall login success if the subsequent modules allow for login with
ImpersonationCredentials
LoginModuleImpl
by default supportsImpersonationCredentials
and it will succeed if impersonation for the target user is allowed.ExternalLoginModule
by default doesn't supportImpersonationCredentials
but may do if a suitableCredentialsSupport
is configured.
Other Credentials
- Overall login success only if the
ExternalLoginModule
supports these credentials - Custom pre-auth module will ignore
LoginModuleImpl
will ignoreExternalLoginModule
will only succeed if configured with a suitableCredentialsSupport
that ensures that authentication against the external IDP is successful.
FAQ
Why are the custom ‘PreAuthCredentials’ not public?
The custom Credentials
shared between the code performing the authentication
(outside of the repository) and the custom PreAuthenticationLoginModule
implementation must neither be public nor shared with other implementations
in order to prevent un-authenticated login.
Why is the ‘LoginModuleImpl’ not flagged SUFFICIENT?
If LoginModuleImpl
was defined to be sufficient external identities
would never be synced again if the PreAuthenticatedLogin
marker is
present in the shared state.
Why is the ‘ExternalLoginModule’ not flagged REQUIRED?
If ExternalLoginModule
was required to succeed, login for local users
was no longer possible. It also would mean that pre-authenticated login
for a SyncedIdentity
that doesn't needs a re-sync would not longer
be possible and would ultimately fail the repository authentication.