Author: tripod
Date: Tue Mar 25 23:30:49 2014
New Revision: 1581599
URL: http://svn.apache.org/r1581599
Log:
OAK-1573 Document External Login and LDAP specifically
Modified:
jackrabbit/oak/trunk/oak-doc/src/site/markdown/overview.md
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/external_login_module.md
Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/overview.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/overview.md?rev=1581599&r1=1581598&r2=1581599&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/overview.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/overview.md Tue Mar 25
23:30:49 2014
@@ -30,5 +30,6 @@ TODO: Document core concepts and archite
* Search and indexing
* Security
* [Permission Evaluation](security/permission_eval.html)
+ * [Authentication / Login Modules](security/external_login_module.html)
* [Oak
Core](https://github.com/apache/jackrabbit-oak/blob/trunk/oak-core/README.md)
* ...
Modified:
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/external_login_module.md
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/external_login_module.md?rev=1581599&r1=1581598&r2=1581599&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/external_login_module.md
(original)
+++
jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/external_login_module.md
Tue Mar 25 23:30:49 2014
@@ -17,37 +17,9 @@
The Oak Security Layer
======================
-External Login Module
+Authentication / Login Modules
------------------------------------------------------------------------------------------------------------------------
-### Overview
-The purpose of the external login module is to provide a base implementation
that allows easy integration of 3rd party
-authentication and identity systems, such as LDAP. The general mode of the
external login module is to use the external
-system as authentication source and as a provider for users and groups.
-
-what it does:
-
-* facilitate the use of a 3rd party system for authentication
-* simplify populating the oak user manager with identities from a 3rd party
system
-
-what it does not:
-
-* provide a transparent oak user manager
-* provide a transparent oak principal provider.
-* offer services for background synchronization of users and groups
-
-### Structure
-The external identity and login handling is split into 3 parts:
-
-1. An external identity provider (IDP). This is a service implementing the
`ExternalIdentityProvider` interface and is responsible to retrieve and
authenticate identities towards an external system (e.g. LDAP).
-2. An synchronization handler. This is a service implementing the
`SyncHandler` interface and is responsible to actually managing the external
identities within the Oak user management. A very trivial implementation might
just create users and groups for external ones on demand.
-3. The external login module (ExtLM). This is the connection between JAAS
login mechanism, the external identity provider and the synchronization handler.
-
-This modularization allows to reuse the same external login module for
different combinations of IDPs and synchronization handlers. Although in
practice, systems usually have 1 of each.
-
-An example where multiple such entities come into play would be the case to
use several LDAP servers for authentication. Here we would configure 2 LDAP
IDPs, 1 Sync handler and 2 ExtLMs.
-
-
### Types of login modules
In order to understand how login modules work and how Oak can help providing
extension points we need to look at how
JAAS authentication works in general and discuss where the actual
credential-verification is performed.
@@ -57,7 +29,9 @@ The following section is copied and adap
The authentication process within the `LoginModule` proceeds in two distinct
phases.
-1. 1. In the first phase, the `LoginModule`'s `login` method gets invoked by
the `LoginContext`'s `login` method.
+1.
+
+ 1. In the first phase, the `LoginModule`'s `login` method gets invoked by
the `LoginContext`'s `login` method.
2. The `login` method for the `LoginModule` then performs the actual
authentication (prompt for and verify a
password for example) and saves its authentication status as private
state information.
3. Once finished, the `LoginModule`'s login method either returns `true`
(if it succeeded) or `false` (if it should
@@ -65,7 +39,9 @@ The authentication process within the `L
retry the authentication or introduce delays. The responsibility of such
tasks belongs to the application.
If the application attempts to retry the authentication, the
`LoginModule`'s `login` method will be called again.
-2. 1. In the second phase, if the `LoginContext`'s overall authentication
succeeded (the relevant REQUIRED, REQUISITE,
+2.
+
+ 1. In the second phase, if the `LoginContext`'s overall authentication
succeeded (the relevant REQUIRED, REQUISITE,
SUFFICIENT and OPTIONAL LoginModules succeeded), then the `commit`
method for the `LoginModule` gets invoked.
2. The `commit` method for a `LoginModule` checks its privately saved state
to see if its own authentication
succeeded.
@@ -83,23 +59,23 @@ flags indicating how to treat their beha
JAAS defines the following module flags:
(The following section is copied and adapted from the javadoc of
[javax.security.auth.login.Configuration])
-1. **Required**
+**Required**
: The LoginModule is required to succeed.
If it succeeds or fails, authentication still continues to proceed down the
LoginModule list.
-2. **Requisite**
+**Requisite**
: The LoginModule is required to succeed.
If it succeeds, authentication continues down the LoginModule list.
If it fails, control immediately returns to the application (authentication
does not proceed down the LoginModule
list).
-3. **Sufficient**
+**Sufficient**
: The LoginModule is not required to succeed.
If it does succeed, control immediately returns to the application
(authentication does not proceed down the
LoginModule list).
If it fails, authentication continues down the LoginModule list.
-4. **Optional**
+**Optional**
: The LoginModule is not required to succeed.
If it succeeds or fails, authentication still continues to proceed down the
LoginModule list.
@@ -108,52 +84,24 @@ LoginModule is configured and succeeds,
LoginModule need to have succeeded for the overall authentication to succeed.
If no Required or Requisite LoginModules
are configured for an application, then at least one Sufficient or Optional
LoginModule must succeed.
-#### Authentication and subject population
-The goal of the external login module is to provide a very simple way of using
-_"the users stored in an external system for authentication and authorization
in the Oak content repository"_. So the
-easiest way of doing this is to import the users on-demand when they log in.
-
-#### Password caching
-In order to prevent extensive authentication calls against the 3rd party
system the user's credentials, in
-particular the passwords need to be cached. There are two different way doing
this.
-
-The first way is to only cache the password (encrypted) in memory and expire
them over time. this has the advantage
-that they are not copied to the local repository and can be invalidated easier
and with a different cycle than the
-actual user synchronization. It has the disadvantage, that users won't be able
to login, if the 3rd party system is
-offline.
-
-The alternative is to cache the passwords in the repository together with the
synced user.
-this has the advantage that the 3rd party system can be offline and users will
-still be able to login. It has the following disadvantages:
-
-- password are copied to the local system and stored with the users in a
encrypted form. This might be a security concern and might not comply with
security policies.
-- it only works for simple password based credentials.
-
-### Behavior of the External Login Module
-
-#### General
-The external login module has 2 main tasks. one is to authenticate credentials
against a 3rd party system, the other is
-to coordinate syncing of the respective users and groups with the JCR
repository (via the UserManager).
-
-If a user needs re-authentication (for example, if the cache validity expired
or if the user is not yet present in the
-local system at all), the login module must check the credentials with the
external system during the `login()` method.
-If authentication succeeds, it must return `true` or throw a `LoginException`
if authentication failed.
-
-There are some nuances to this and it is important to understand the exact
behavior of the login module(s) so that the JAAS login can be configured
correctly:
-
-**LoginModuleImpl**
+### Pre Authenticated Logins
+Pre authenticated logins allows to support 3rd party login modules that wish
to provide the login context with pre authenticated login names, but still want
to rely on the rest of the oak's login module chain. For example an external
SSO login module can extract the userid from a servlet request and use it to
authenticate against the repository. But instead of re-implementing the user
lookup and subject population (and possible external user synchronization) it
just sets a respective
[org.apache.jackrabbit.oak.spi.security.authentication.PreAuthenticatedLogin]
on the shared state.
+Default Login Module
+------------------------------------------------------------------------------------------------------------------------
+### Behavior of the Default Login Module
The behavior of the default login module is relatively simple, so it is
explained first:
upon login():
* if a user does not exist in the repository (i.e. cannot be provided by the
user manager) it **returns `false`**.
+* if an authorizable with the respective userId exists but is a group or a
disabled users, it **throws `LoginException`**
* if a user exists in the repository and the credentials don't match, it
**throws `LoginException`**
* if a user exists in the repository and the credentials match, it **returns
`true`**
- * also, it adds the credentials to the shared state
- * also, it adds the login name to the shared state
- * also, it calculates the principals and adds them to the private state
- * also, it adds the credentials to the private state
+ * also, it adds the credentials to the shared state
+ * also, it adds the login name to the shared state
+ * also, it calculates the principals and adds them to the private state
+ * also, it adds the credentials to the private state
upon commit():
@@ -161,207 +109,134 @@ upon commit():
* if the private state does not contain credentials and principals, it clears
the state and **returns `false`**
+External Login Module
+------------------------------------------------------------------------------------------------------------------------
+
+### Overview
+The purpose of the external login module is to provide a base implementation
that allows easy integration of 3rd party
+authentication and identity systems, such as LDAP. The general mode of the
external login module is to use the external
+system as authentication source and as a provider for users and groups.
+
+what it does:
+
+* facilitate the use of a 3rd party system for authentication
+* simplify populating the oak user manager with identities from a 3rd party
system
+
+what it does not:
+
+* provide a transparent oak user manager
+* provide a transparent oak principal provider.
+* offer services for background synchronization of users and groups
+
+### Structure
+The external identity and login handling is split into 3 parts:
+
+1. An external identity provider (IDP). This is a service implementing the
`ExternalIdentityProvider` interface and is responsible to retrieve and
authenticate identities towards an external system (e.g. LDAP).
+2. An synchronization handler. This is a service implementing the
`SyncHandler` interface and is responsible to actually managing the external
identities within the Oak user management. A very trivial implementation might
just create users and groups for external ones on demand.
+3. The external login module (ExtLM). This is the connection between JAAS
login mechanism, the external identity provider and the synchronization handler.
+
+This modularization allows to reuse the same external login module for
different combinations of IDPs and synchronization handlers. Although in
practice, systems usually have 1 of each.
+
+An example where multiple such entities come into play would be the case to
use several LDAP servers for authentication. Here we would configure 2 LDAP
IDPs, 1 Sync handler and 2 ExtLMs.
+
+
+#### Authentication and subject population
+The goal of the external login module is to provide a very simple way of using
+_"the users stored in an external system for authentication and authorization
in the Oak content repository"_. So the
+easiest way of doing this is to import the users on-demand when they log in.
+
+### Behavior of the External Login Module
+
+#### General
+The external login module has 2 main tasks. one is to authenticate credentials
against a 3rd party system, the other is
+to coordinate syncing of the respective users and groups with the JCR
repository (via the UserManager).
+
+If a user needs re-authentication (for example, if the cache validity expired
or if the user is not yet present in the
+local system at all), the login module must check the credentials with the
external system during the `login()` method.
+
**ExternalLoginModule**
Note:
-* users (and groups) that are synced from the 3rd party system contain a
`rep:syncSource` (TBD) property. This allows to identify the external users and
distinguish them from others.
+* users (and groups) that are synced from the 3rd party system contain a
`rep:externalId` property. This allows to identify the external users and
distinguish them from others.
* to reduce expensive syncing, the synced users and groups have sync timestamp
`rep:lastSynced` and are considered valid for a configurable time. if they
expire, they need to be validated against the 3rd party system again.
upon login():
-* if the passwords are cached in memory and the credentials are valid, it puts
the credentials in the private state and **returns `true`**
-* if the user exists in the 3rd party system and the credentials match, it
puts the credentials in the private state and **returns `true`**
+* if the user exists in the repository and is not an externally synced,
**return `false`**
* if the user exists in the 3rd party system but the credentials don't match
it **throws `LoginException`**
-* if the user does not exist in the 3rd party system, it **returns `false`**
+* if the user exists in the 3rd party system and the credentials match
+ * put the credentials in the shared and private state
+ * possibly sync the user
+ * and **returns `true`**
+* if the user does not exist in the 3rd party system, checks if it needs to
remove the user and then it **returns `false`**
upon commit():
* if there is no credentials in the private state, it **returns `false`**
-* if there are credentials in the private state, possibly sync the user and
then propagate the subject and **return `true`**
+* if there are credentials in the private state propagate the subject and
**return `true`**
-<!--
-* If a user does **not** exist in the 3rd party system, it could be that
- 1. the user was not and will never exist there, and authentication should
proceed to the next login module.
- This is for example the case for the *admin* user that only exists
locally.
- 2. the user was removed from the 3rd party system but still exists
locally. In this case, the user needs to be
- removed locally and authentication needs to proceed to the next login
module
-
- So in both cases above, the external login module needs to returns `false`
in its `login()` method.
-
-* If a user **does** exist in the 3rd party system, it could be that
- 1. no local user with the same userid exists, so the result of the 3rd
party authentication is sufficient enough.
- 2. a local user with the same userid exists (who is not an imported 3rd
party user) then it depends on the
- configuration if to rely on the external authentication or not. This
problem is especially important to note,
- if the external and local users cannot be distinguished by principal
name (which is usually the case).
- A good default is to decline authentication (i.e. return `false`) and
rely on the default login module in such
- cases.
-
-Any `ExternalLoginModule` needs to be configured as **sufficient** and listed
**before** the default `LoginModuleImpl`.
-this will lead to the following behaviors:
-
-1. if a (remote) user does not exist in the repository, he is authenticated
against the 3rd party system and...
- * if the user does not exist in the 3rd party system, the `login()`
returns `false` and the JAAS authentication
- continues with the next login module.
- * if authentication fails, the `login()` throws a `LoginException` and the
overall JAAS authentication continues
- with the next module. Note that this will allow local user override that
also exist in the external system.
- * if authentication succeeds, the 1. phase of the JAAS authentication is
completed. There are extra steps that
- the external login module needs to perform in order to sync the user.
-2. if a (remote) user exists in the repository and he does not need
re-authentication, the `login()` method returns
- `true` and authentication completes.
-3. if a (remote) user exists in the repository and he needs re-authentication
then the user is removed from the
- repository and the same steps as in 1. above apply.
-
-Since the module is configured as **sufficient** any successful authentication
against the 3rd party system will
-complete the first phase of the JAAS authentication and the
`ExternalLoginModule` has time to actually sync the
-user during the 2nd phase in the `commit()` method. But this depends again on
the mode of operation. see pseudo
-code sections below.
--->
-
-#### User Synchronization
-TODO
-
-#### Groups Synchronization
-TODO
+User and Group Synchronization
+------------------------------------------------------------------------------------------------------------------------
+The synchronization of users and groups is triggered by the external login
module, after a user is successfully
+authenticated against the IDP or if it's no longer present on the IDP.
-### Configuration
+### Configuration of the DefaultSyncHandler
+Oak provides a default synchronization handler that is configured via
[org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncConfig].
The handler is configured either via OSGi or during manual [Repository
Construction](../construct.html).
-#### JAAS Configuration
-The external login module as usually configured as **sufficient** and
**before** the `LoginModuleImpl`.
+| Name | Property | Description
|
+|-------------------------------|-------------------------------|------------------------------------------|
+| Sync Handler Name | `handler.name` | Name of this
sync configuration. This is used to reference this handler by the login
modules. |
+| User auto membership | `user.autoMembership` | List of
groups that a synced user is added to automatically |
+| User Expiration Time | `user.expirationTime` | Duration
until a synced user gets expired (eg. '1h 30m' or '1d'). |
+| User Membership Expiration | `user.membershipExpTime` | Time after
which membership expires (eg. '1h 30m' or '1d'). |
+| User membership nesting depth | `user.membershipNestingDepth` | Returns the
maximum depth of group nesting when membership relations are synced. A value of
0 effectively disables group membership lookup. A value of 1 only adds the
direct groups of a user. This value has no effect when syncing individual
groups only when syncing a users membership ancestry. |
+| User Path Prefix | `user.pathPrefix` | The path
prefix used when creating new users. |
+| User property mapping | `user.propertyMapping` | List mapping
definition of local properties from external ones. eg: 'profile/email=mail'.Use
double quotes for fixed values. eg: 'profile/nt:primaryType="nt:unstructured" |
+| Group auto membership | `group.autoMembership` | List of
groups that a synced group is added to automatically |
+| Group Expiration Time | `group.expirationTime` | Duration
until a synced group expires (eg. '1h 30m' or '1d'). |
+| Group Path Prefix | `group.pathPrefix` | The path
prefix used when creating new groups. |
+| Group property mapping | `group.propertyMapping` | List mapping
definition of local properties from external ones. |
+|
| | |
-other config
+LDAP Identity Provider
+------------------------------------------------------------------------------------------------------------------------
+Oak comes with a default implementation of an LDAP identity provider.
-* password caching expiration time (0 == disable password caching)
-* maximum passwords to cache (i.e. num users)
-* synced user expiration
-* synced group expiration
-* synced membership expiration
-* sync groups
-* user intermediate path / split dn
-* group intermediate path / split dn
-* user sync modification attribute
-* group sync modification attribute
-* autoGroupMembership (user / groups)
-* userAttributeMapping
-* groupAttributeMapping
-* ldap user root (dn)
-* ldap group root (dn)
-* ldap userIdAttribute
-* ldap userFilter
-* ldap groupFilter
-* ldap groupNameAttribute
-* ldap groupMembershipAttribute
-* ldap searchTimeout
-* groupNestingDepth
-
-* local/external user precedence. default is: local wins. best use
include/exclude of user patterns. e.g. admin
- should never be external.
-* password sync or not.
-* various cache expiration times (pwd, users, groups)
-*
-
-#### pseudo code for users with synced passwords
-````
-login() {
- extract userid and password from credentials
- find user in repository
- if (user exists in repository) {
- if (user is local user) {
- // not our user - decline.
- return false;
- }
- if (user needs sync) {
- flag user to be synced
- } else {
- // delegate work to default login module
- return false;
- }
- }
- find user in remote system
- if (user exists in remote system) {
- authenticate user against remote system
- if (authentication successful) {
- sync user including the provided password locally
- // delegate further work to default login module
- return false;
- } else {
- throw LoginException();
- }
- } else {
- if (user is flagged) {
- remove user
- }
- return false;
- }
-}
-commit() {
- // nothing to do
- return false;
-}
-````
-
-#### pseudo code for users without synced passwords
-
-````
-login() {
- extract userid and password from credentials
- find user in repository
- if (user exists in repository) {
- if (user is local user) {
- // not our user - decline.
- return false;
- }
- if (user needs sync) {
- flag user to be synced
- } else {
- check if users credentials are cached and not expired
- if (cached credentials match) {
- // authentication successful
- return true;
- }
- // here it could be that the user changed his password on the IDP
- // and he already provided the new password in the login. so we
can't
- // throw the LoginException here but need to revalidate him
against the IDP.
- }
- clear cached credentials
- }
- find user in remote system
- if (user exists in remote system) {
- authenticate user against remote system
- if (authentication successful) {
- flag user to be synced
- cache credentials
- return true;
- } else {
- throw LoginException();
- }
- } else {
- if (user is flagged) {
- remove user
- }
- return false;
- }
-}
-commit() {
- if (user needs to be synced ) {
- sync user
- }
- if (this module did authenticate the user) {
- populate subject with the correct principals
- return true;
- } else {
- return false;
- }
-}
-````
+### Configuration
+The LDAP IPDs are configured through the
[org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapProviderConfig]
+which is populated either via OSGi or during manual [Repository
Construction](../construct.html).
+| Name | Property | Description
|
+|------------------------------|-------------------------|------------------------------------------|
+| LDAP Provider Name | `provider.name` | Name of this LDAP
provider configuration. This is used to reference this provider by the login
modules. |
+| Bind DN | `bind.dn` | DN of the user for
authentication. Leave empty for anonymous bind. |
+| Bind Password | `bind.password` | Password of the
user for authentication. |
+| LDAP Server Hostname | `host.name` | Hostname of the
LDAP server |
+| Disable certificate checking | `host.noCertCheck` | Indicates if server
certificate validation should be disabled. |
+| LDAP Server Port | `host.port` | Port of the LDAP
server |
+| Use SSL | `host.ssl` | Indicates if an SSL
(LDAPs) connection should be used. |
+| Use TLS | `host.tls` | Indicates if TLS
should be started on connections. |
+| Search Timeout | `searchTimeout` | Time in until a
search times out (eg: '1s' or '1m 30s'). |
+| User base DN | `user.baseDN` | The base DN for
user searches. |
+| User extra filter | `user.extraFilter` | Extra LDAP filter
to use when searching for users. The final filter is formatted like:
`(&(<idAttr>=<userId>)(objectclass=<objectclass>)<extraFilter>)` |
+| User id attribute | `user.idAttribute` | Name of the
attribute that contains the user id. |
+| User DN paths | `user.makeDnPath` | Controls if the DN
should be used for calculating a portion of the intermediate path. |
+| User object classes | `user.objectclass` | The list of object
classes an user entry must contain. |
+| Group base DN | `group.baseDN` | The base DN for
group searches. |
+| Group extra filter | `group.extraFilter` | Extra LDAP filter
to use when searching for groups. The final filter is formatted like:
`(&(<nameAttr>=<groupName>)(objectclass=<objectclass>)<extraFilter>)` |
+| Group DN paths | `group.makeDnPath` | Controls if the DN
should be used for calculating a portion of the intermediate path. |
+| Group member attribute | `group.memberAttribute` | Group attribute
that contains the member(s) of a group. |
+| Group name attribute | `group.nameAttribute` | Name of the
attribute that contains the group name. |
+| Group object classes | `group.objectclass` | The list of object
classes a group entry must contain. |
+|
| | |
<!-- references -->
[javax.security.auth.spi.LoginModule]:
http://docs.oracle.com/javase/6/docs/api/javax/security/auth/spi/LoginModule.html
[javax.security.auth.login.Configuration]:
http://docs.oracle.com/javase/6/docs/api/javax/security/auth/login/Configuration.html
-
-
-
+[org.apache.jackrabbit.oak.spi.security.authentication.PreAuthenticatedLogin]:
/oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/PreAuthenticatedLogin.html
+[org.apache.jackrabbit.oak.spi.security.authentication.external.impl.DefaultSyncConfig]:
/oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/DefaultSyncConfig.html
+[org.apache.jackrabbit.oak.security.authentication.ldap.impl.LdapProviderConfig]:
/oak/docs/apidocs/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.html