This is an automated email from the ASF dual-hosted git repository.

angela pushed a commit to branch OAK-10069
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit 84ff0c267d4a35a28f27fbb74897754e4206311b
Author: angela <anch...@adobe.com>
AuthorDate: Thu Feb 16 17:47:26 2023 +0100

    OAK-10069 : Best practices on how to setup access control external 
identities
---
 oak-doc/src/site/markdown/dos_and_donts.md         |   1 +
 .../authentication/external/bestpractices.md       | 159 +++++++++++++++++++++
 .../authentication/external/defaultusersync.md     |  47 +++---
 .../security/authentication/external/dynamic.md    |  32 +++--
 .../external/externallogin_examples.md             |  88 +++++++++++-
 .../security/authentication/externalloginmodule.md |   3 +-
 .../security/authorization/bestpractices.md        |   1 +
 oak-doc/src/site/markdown/security/overview.md     |   2 +
 oak-doc/src/site/markdown/security/principal.md    |   6 +-
 9 files changed, 301 insertions(+), 38 deletions(-)

diff --git a/oak-doc/src/site/markdown/dos_and_donts.md 
b/oak-doc/src/site/markdown/dos_and_donts.md
index 41b32dc227..fda15e06a4 100644
--- a/oak-doc/src/site/markdown/dos_and_donts.md
+++ b/oak-doc/src/site/markdown/dos_and_donts.md
@@ -122,6 +122,7 @@ c = d.getParent();                              // 
preferred way to fetch the pa
 ```
 ## Security
 - [Best Practices for Authorization](security/authorization/bestpractices.html)
+- [Best Practices for External 
Authentication](security/authentication/external/bestpractices.html)
 
 ## Misc
 ### Don't use Thread.interrupt()
diff --git 
a/oak-doc/src/site/markdown/security/authentication/external/bestpractices.md 
b/oak-doc/src/site/markdown/security/authentication/external/bestpractices.md
new file mode 100644
index 0000000000..b2ef8bfbf4
--- /dev/null
+++ 
b/oak-doc/src/site/markdown/security/authentication/external/bestpractices.md
@@ -0,0 +1,159 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+# Best Practices for External Authentication
+
+<!-- MACRO{toc} -->
+
+## Before you get started
+
+Before you get started make sure you are familiar with the basic concepts of 
JCR authentication, and it's implementation 
+in Apache Jackrabbit Oak.
+
+External authentication in Oak refers to integrating a third party identity 
provider like LDAP or SAML into the 
+authentication setup optionally combining it with other built-in 
authentication mechanisms.
+
+## Best Practices 
+
+### JAAS Setup
+
+When combining external authentication with other built-in or custom 
+[login 
modules](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/security/auth/spi/LoginModule.html)
 
+make sure to define a 
+[configuration](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/security/auth/login/Configuration.html)
 
+with the optimal order and the proper [control 
flag](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/security/auth/login/AppConfigurationEntry.LoginModuleControlFlag.html)
 
+for each module to cover all cases.
+
+Additional reading: 
https://docs.oracle.com/en/java/javase/11/security/appendix-b-jaas-login-configuration-file.html#GUID-7EB80FA5-3C16-4016-AED6-0FC619F86F8E
+
+#### Combination with Token Authentication
+
+Whenever JCR sessions created with Oak are short-lived (e.g. only lasting for 
a single HTTP request) authentication 
+against an external IDP may not perform well. It is therefore recommended to 
use external authentication in combination 
+with an additional authentication mechanism like e.g. the built-in [token 
login](../tokenmanagement.html).
+
+Make sure the token-login is 'sufficient' and is evaluated prior to the 
external login that connects to the external IDP.
+
+#### Combination with Default Authentication
+
+Oak comes with a default login for user accounts stored and managed inside the 
JCR content repository. This also includes 
+support for default users like an anonymous guest, and an administrator with 
full access to the repository. If this is 
+desired, it is recommend to also add the [default 
`LoginModule`](../default.html#uid_pw) to the JAAS configuration.
+
+The optional order depends on the frequency of default vs external login.
+
+##### Example JAAS Configuration
+
+The following JAAS configuration can e.g. be used when running an Oak 
repository with external authentication 
+in combination with Apache Sling (see also other 
[examples](externallogin_examples.html)):
+
+| Ranking | Control Flag | LoginModule Class Name |
+|---------|--------------|------------------------|
+| 300     | OPTIONAL     | 
org.apache.jackrabbit.oak.spi.security.authentication.GuestLoginModule |
+| 200     | SUFFICIENT   | 
org.apache.jackrabbit.oak.security.authentication.token.TokenLoginModule | 
+| 150     | SUFFICIENT   | 
org.apache.jackrabbit.oak.spi.security.authentication.external.impl.ExternalLoginModuleFactory
 |
+| 100     | SUFFICIENT   | 
org.apache.jackrabbit.oak.security.authentication.user.LoginModuleImpl |
+
+### Synchronization of Users and Groups
+
+The external authentication module in Oak comes with the option to synchronize 
external identities into the content 
+repository (see section [User and Group Synchronization](../usersync.html)).
+
+The following best practices should be followed:
+
+#### External Identity Provider as SSOT
+
+Your external identity provider should be considered the single source of 
truth (SSOT) for all users and groups defined 
+and managed by it. 
+
+In contrast, the data synchronized into the repository should be considered a 
volatile cache and ideally 
+are immutable (i.e. only maintained by system sessions in charge of the 
synchronization). 
+
+The following features provided by the _oak-auth-external_ module help to 
prevent unintended modification of synchronized 
+external identities:
+
+- [Dynamic Membership](defaultusersync.html#dynamic_membership): Enabling 
dynamic membership will result in membership information being stored in 
+a protected property that cannot be altered using regular JCR write or 
Jackrabbit user management API. 
+- [Dynamic Group](defaultusersync.html#dynamic_groups): Can be used in 
combination with dynamic membership when the application requires group 
principals 
+to also exposed through `UserManager` (and not just through `PrincipalManager` 
as it would be needed for permission setup).
+Note though that these group accounts cannot have members added (see section 
[Enforcing dynamic groups](defaultusersync.html#enforcing_dynamic_groups))
+- [Protecting External 
Identities](defaultusersync.html#protect_external_identities): The module comes 
with [configuration 
+ option](defaultusersync.html#configuration_principals) to protect external 
identities. If enabled (as warning or as full 
+ protection) a dedicated validator that will report/fail attempts to modify 
synchronized external identities. This will 
+ help to identify violations of the immutability contract.
+ 
+#### User Management for External Identities
+
+- Properties and membership for external identities must be managed in the 
external IDP. Changes made in the JCR repository 
+using user management API will be overwritten upon the next sync.
+- Never set a password for external users to make sure uid/pw login gets 
authenticated against the external IDP and never 
+against the synchronized user in the repository.
+
+#### Membership Nesting
+
+For performance reasons avoid defining unnecessary membership nesting that 
increase the number of indirections (see 
+[Best Practices for Authorization](../../authorization/bestpractices.html)).
+
+#### Membership crossing IDP boundaries
+
+Introducing membership crossing IDP boundaries should be considered a trust 
boundary violation.
+
+If adding external identities to local groups cannot be avoided please make 
sure to leverage 
+[conditional 
auto-membership](defaultusersync.html#configuration_automembership) 
+or auto-membership configuration in combination with dynamic membership (see 
+[Configuration of the 
DefaultSyncHandler](defaultusersync.html#configuration_sync_handler)).
+
+### Authorization for External Identities
+
+Upon repository login through external authentication the subject is populated 
with principals obtained from the 
+external identity provider. 
+
+In addition, the configured auto-membership will be resolved for the external 
user and its external groups (see 
+autoMembership configuration 
[options](defaultusersync.html#configuration_sync_handler) and section 
[Automatic Membership with 
AutoMembershipConfig](defaultusersync.html#configuration_automembership))
+
+The authenticated session will be subject to regular Oak permission evaluation 
as defined for the instance and 
+described in section [Permissions](../../permission.html). 
+
+#### Access control setup
+
+Synchronized external identities (both in default and in dynamic sync mode) 
are exposed as principals through the 
+[Principal Management API](../../principal.html) and can be used for access 
control setup as described 
+in [Access Control Management](../../accesscontrol.html).
+
+See also section [Best Practices for 
Authorization](../../authorization/bestpractices.html)) for recommendations.
+
+The following options exist if access control setup for external groups should 
be ready before the first user login:
+
+- Pre-sync external groups to make them available to the principal manager 
(see next section)
+- Configure 
[ImportMode](../../accesscontrol/default.html#configuration)=`besteffort` with 
the default Oak 
+  authorization setup and define access control content for principals before 
they exist.
+  
+#### Pre-sync of external groups
+
+The following 2 options exist to populate the repository with external group 
principals before the first user login in 
+order to setup access control:
+
+- The _oak-auth-external_ module comes with a JMX integration that allows for 
synchronization of external identities outside 
+of the regular repository login. See [JMX Synchronization 
Tool](../usersync.html#jmx-synchronization-tool) and
+[SynchronizationMBean](https://jackrabbit.apache.org/oak/docs/apidocs/org/apache/jackrabbit/oak/spi/security/authentication/external/impl/jmx/SynchronizationMBean.html)
 
+for details. This requires the `ExternalIdentityProvider` to implement the 
methods required to retrieve external 
+identities outside of the authentication step. In general this is the 
recommended way to pre-sync groups.
+- In case the `ExternalIdentityProvider` does not support user and group sync 
outside of the regular 
+repository login, external identities can be created using Jackrabbit User 
Management API. It is important to note though
+that the `rep:externalId` cannot be added or changed once the group has been 
persisted as the property is system maintained 
+and protected. Note that mistakes in defining the `rep:externalId`, 
`rep:authorizableId` or `rep:principalName` properties 
+will result in mismatches during authentication, sync and permission 
evaluation that cannot be corrected.
diff --git 
a/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md 
b/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md
index 8b13c8d5eb..55141ad3a4 100644
--- 
a/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md
+++ 
b/oak-doc/src/site/markdown/security/authentication/external/defaultusersync.md
@@ -15,12 +15,14 @@
    limitations under the License.
 -->
 
-User and Group Synchronization : The Default Implementation
+# User and Group Synchronization : The Default Implementation
 
--------------------------------------------------------------------------------
 
-### Default Implementation of Sync API
+<!-- MACRO{toc} -->
 
-#### SyncManager
+## Default Implementation of Sync API
+
+### SyncManager
 
 The default implementation (`SyncManagerImpl`) is intended for use in an 
OSGi-base
 repository setup: it tracks all `SyncHandler` registered via OSGi.
@@ -28,20 +30,20 @@ repository setup: it tracks all `SyncHandler` registered 
via OSGi.
 It can be used in non-OSGi environments by passing a 
`org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard`
 to the constructor.
 
-#### SyncHandler
+### SyncHandler
 
 The [DefaultSyncHandler] comes with a set of configuration options that
 allow to specify the synchronization behavior (see below). Depending on the 
 configuration it chooses between two different `SyncContext` implementations.
 
-#### SyncContext
+### SyncContext
 
 Oak provides the following implementations of the [SyncContext] interface:
 
 - [DefaultSyncContext]: base implementation that synchronizes external user 
and group accounts into the repository
 - [DynamicSyncContext]: derived implementation that provides special handling 
for external groups.
  
-##### DefaultSyncContext
+#### DefaultSyncContext
 
 All users/groups synchronized by this context will get the following 
properties set.
 These properties allow to run separate task for periodical update and make sure
@@ -59,7 +61,7 @@ for further details.
 The [DefaultSyncContext] is exported as part of the 'basic' package space and
 may be used to provide custom implementations.
 
-##### DynamicSyncContext
+#### DynamicSyncContext
 
 Extending from the [DefaultSyncContext] this implementation that provides 
special 
 handling  for external groups in case the [Dynamic Group 
Membership](#dynamic_membership) 
@@ -70,21 +72,22 @@ the group principal names of the external user accounts:
 
 - `rep:externalPrincipalNames` : Optional system-maintained property related 
to [Dynamic Group Membership](#dynamic_membership)
 
-#### SyncResult
+### SyncResult
 
 The [DefaultSyncResultImpl] is exported as part of the 'basic' package space 
 providing a simple `SyncResult` implementation based on a status and a 
[DefaultSyncedIdentity].
 
 
-#### SyncedIdentity
+### SyncedIdentity
 
 The [DefaultSyncedIdentity] is exported as part of the 'basic' package space. 
It 
 maps the ID of a synchronized user/group account to the external identity 
references
 represented by [ExternalIdentityRef].
 
 
+### Dynamic Sync
 <a name="dynamic_membership"></a>
-### Dynamic Group Membership
+#### Dynamic Group Membership
 
 As of Oak 1.5.3 the default sync handler comes with an addition configuration 
 option that allows enabling dynamic group membership resolution for external 
users. 
@@ -95,7 +98,7 @@ The details and effects on other security related modules are 
described in
 section [Dynamic Membership and Dynamic Groups](dynamic.html). 
 
 <a name="dynamic_groups"></a>
-### Dynamic Groups
+#### Dynamic Groups
 
 As of Oak 1.46.0 there exists the option to leverage [Dynamic 
Membership](#dynamic_membership) in combination with a 
 new `Dynamic Groups` configuration option (see also [OAK-9803]). If both 
options are enabled external groups will continue 
@@ -104,7 +107,7 @@ User Management API without losing the benefits of the 
dynamic membership.
 See section [Dynamic Membership and Dynamic Groups](dynamic.html) for details 
and comparison.
 
 <a name="xml_import"></a>
-#### XML Import
+### XML Import
 
 The protected nature of the `rep:externalPrincipalNames` is also reflected 
during
 XML import of user accounts:
@@ -118,9 +121,9 @@ the target system the sync will then result in a full sync 
of group membership o
 will re-create the `rep:externalPrincipalNames` property.
 
 <a name="validation"></a>
-#### Validation
+### Validation
 
-##### rep:externalPrincipalNames
+#### rep:externalPrincipalNames
 
 As of Oak 1.5.3 a dedicated `Validator` implementation asserts that the 
protected,
 system-maintained property `rep:externalPrincipalNames` is only written by the 
@@ -140,7 +143,7 @@ with external user/group accounts.
 | 0072              | Property 'rep:externalPrincipalNames' requires 
'rep:externalId' to be present on the Node. |
 | 0073              | Property 'rep:externalId' cannot be removed if 
'rep:externalPrincipalNames' is present. |
 
-##### rep:externalId
+#### rep:externalId
 
 If protection of the `rep:externalId` property is enabled (since Oak 1.5.8) the
 validator performs the following checks:
@@ -150,7 +153,8 @@ validator performs the following checks:
 | 0074              | Attempt to add, modify or remove the system maintained 
property 'rep:externalId'. |
 | 0075              | Property 'rep:externalId' may only have a single value 
of type STRING. |
  
-##### Protecting synchronized external users/groups 
+<a name="protect_external_identities"></a> 
+#### Protecting synchronized external users/groups 
 
 If protection of synchronized external users/groups is enabled (since Oak 
1.44.0) an additional validator is present
 which either warns upon or prevents creation, modification and removal of 
external identities that have been synchronized 
@@ -175,7 +179,8 @@ The following constraint violations will be reported:
 | 0076 | Attempt to remove protected external identity '%s'                    
     |
 | 0076 | Attempt to remove node '%s' from protected external identity          
     |
 
-##### Enforcing dynamic groups
+<a name="enforcing_dynamic_groups"></a> 
+#### Enforcing dynamic groups
 
 If `user.dynamicMembership` is enabled together with `group.dynamicGroups` a 
separate validator will be present to
 make sure no members are added to the dynamic groups through regular API calls 
(`Group.addMember(Authorizable)` and 
@@ -196,6 +201,7 @@ to a dynamic external group:
 <a name="configuration"></a>
 ### Configuration
 
+<a name="configuration_sync_handler"></a>
 #### Configuration of the DefaultSyncHandler
 
 The default `SyncHandler` implementations are configured via 
[DefaultSyncConfig]:
@@ -219,6 +225,12 @@ The default `SyncHandler` implementations are configured 
via [DefaultSyncConfig]
 | Group 'Dynamic Groups'        | `group.dynamicGroups`         | Only takes 
effect in combination with `user.dynamicMembership` and will result in external 
groups being synced as dynamic groups. |
 | | | |
 
+Note, that the following options relate to the [dynamic sync](dynamic.html) 
feature:
+- `user.dynamicMembership` : Enabling dynamic membership for external users.
+- `user.enforceDynamicMembership` : If enabled together with 
`user.dynamicMembership` previously synced membership information will be 
migrated to dynamic membership upon user sync. Otherwise it takes no effect.
+- `group.dynamicGroups` : Only takes effect in combination with 
`user.dynamicMembership` and will result in external groups being synced as 
dynamic groups.
+
+<a name="configuration_automembership"></a>
 #### Automatic Membership with AutoMembershipConfig
 Since Oak 1.42.0 ([OAK-9463]) the auto-membership behavior can be extended to 
allow for conditional group membership 
 based on characteristics of a given synced external identity. In addition to 
configuration options `group.autoMembership` 
@@ -230,6 +242,7 @@ The `DefaultSyncHandler` is tracking services implementing 
[AutoMembershipConfig
 If present the additional membership defined by the [AutoMembershipConfig], 
will be reflected upon default and dynamic 
 sync together with the original, 'global' auto-membership configuration.
 
+<a name="configuration_principals"></a>
 #### Configuration of the 'Apache Jackrabbit Oak External 
PrincipalConfiguration'
 
 Please note that the `ExternalPrincipalConfiguration` _("Apache Jackrabbit Oak 
External PrincipalConfiguration")_ 
diff --git 
a/oak-doc/src/site/markdown/security/authentication/external/dynamic.md 
b/oak-doc/src/site/markdown/security/authentication/external/dynamic.md
index 1be242c2c7..f0ed493c7f 100644
--- a/oak-doc/src/site/markdown/security/authentication/external/dynamic.md
+++ b/oak-doc/src/site/markdown/security/authentication/external/dynamic.md
@@ -15,14 +15,16 @@
    limitations under the License.
 -->
 
-User and Group Synchronization : Dynamic Membership and Dynamic Groups
+# User and Group Synchronization : Dynamic Membership and Dynamic Groups
 ----------------------------------------------------------------------
 
+<!-- MACRO{toc} -->
+
 As of Oak 1.5.3 the default sync handler comes with an additional 
configuration 
 option (see section [Configuration](defaultusersync.html#configuration) 
 that allows enabling dynamic group membership resolution for external users. 
 
-Enabling dynamic membership in the [DefaultSyncConfig] will change the way 
external
+Enabling dynamic sync options in the [DefaultSyncConfig] will change the way 
external
 groups are synchronized (see [OAK-4101]) and how automatic group membership 
 is being handled (see [OAK-4087]).
 
@@ -32,14 +34,14 @@ The key benefits of dynamic membership resolution are:
 - avoid storing/updating auto-membership which is assigned to all external 
users
 - ease principal resolution upon repository login
 
-See also [FAQ](faq.html#Dynamic_Sync) for frequently asked questions about 
thes dynamic sync.
+See also [FAQ](faq.html#Dynamic_Sync) for frequently asked questions about the 
dynamic sync.
 
-### SyncContext with Dynamic Membership
+## SyncContext with Dynamic Membership
 
 With the default `SyncHandler` this configuration option will show the 
following 
 effects:
 
-#### External Groups
+### External Groups
 
 - If enabled the handler will use an alternative [SyncContext] to synchronize 
external groups (`DynamicSyncContext`).
 - Instead of synchronizing membership information alongside the group 
accounts, this `DynamicSyncContext`
@@ -61,7 +63,7 @@ in Oak 1.6.1 to allow for optimized resolution of a principal 
names from a given
 of `ExternalIdentityProvider` needs to also implement `PrincipalNameResolver`.
 See also [OAK-5210].
 
-#### Automatic Membership
+### Automatic Membership
 
 - If enabled automatic membership assignment for existing, local groups will 
not longer be written to the repository
 - Instead, the `ExternalPrincipalConfiguration` _("Apache Jackrabbit Oak 
External PrincipalConfiguration")_ will keep 
@@ -85,9 +87,9 @@ See also [OAK-5210].
   and reflect autoMembership for synchronized external users in the User 
Management API (see below).
   The same applies for the conditional auto-membership as introduced with 
[OAK-9463].
   
-### Effect of Dynamic Membership on other Security Modules
+## Effect of Dynamic Membership on other Security Modules
   
-#### Principal Management
+### Principal Management
 
 The dynamic (principal) membership features comes with a dedicated 
`PrincipalConfiguration` 
 implementation (i.e. [ExternalPrincipalConfiguration]) that is in charge of 
securing  
@@ -107,7 +109,7 @@ A given external principal will be accessible though the 
principal management AP
 if it can be read from any of the `rep:externalPrincipalNames` properties 
 present using a dedicated query.
 
-##### API Overview
+#### API Overview
 
 - `extUserName`       : the principal name of an external user
 - `extGroupName`      : the principal name of an external group
@@ -121,8 +123,8 @@ present using a dedicated query.
 | `PrincipalManager.getGroupMembership(extUserPrincipal)`  | ok           | ok 
                | ok                     | Dynamic group principals include 
both declared external groups and configured auto-membership principals 
(including inherited principals).|
 | `PrincipalManager.getGroupMembership(extGroupPrincipal)` | ok           | - 
<sup>2</sup>     | - <sup>2,3</sup>       | <sup>2</sup> Group membership gets 
flattened and stored with the external user. Group-group relationship is not 
preserved.<br/><sup>3</sup> For dynamic groups synced into the repository the 
configured auto-membership principals are resolved, see also user management 
API below.  |
 
-#### User Management
-##### User Management without Dynamic Groups Option
+### User Management
+#### User Management without Dynamic Groups Option
 
 Unless the 'Dynamic Groups' option is set additionally, the dynamic membership 
option will effectively disable the
 synchronization of the external group account information into the 
repository's user management feature.
@@ -148,7 +150,7 @@ of external user identities reflected in the corresponding 
API calls, most notab
 `Group.isDeclaredMember`, `Group.getMembers`, `Group.getDeclaredMembers` as 
well as `Authorizable.memberOf`
 and `Authorizable.declaredMemberOf()`.
 
-##### User Management with Dynamic Groups Option enabled
+#### User Management with Dynamic Groups Option enabled
 
 If the 'Dynamic Groups' flag is turned on in addition, external group accounts 
will continue to be synchronized into the 
 repository's user management. However, membership information will not be 
stored together with the groups but instead will 
@@ -164,7 +166,7 @@ Note, that manually adding members to these dynamic 
external groups using `Group
 equivalent Oak API operations will be prevented by a dedicated validator that 
is enabled as soon as the _Dynamic Groups_
 option is present together with _Dynamic Membership_.
 
-##### API Overview
+#### API Overview
 
 - `extUserId`  : the ID of a synchronized external user
 - `extGroupId` : the ID of a synchronized external group
@@ -197,7 +199,7 @@ option is present together with _Dynamic Membership_.
 | `autoGroup.getDeclaredMembers()`                         | ok           | 
(ok) <sup>5,12</sup>| ok <sup>12</sup>      |  |
 | `autoGroup.getMembers()`                                 | ok           | 
(ok) <sup>5,12</sup>| ok <sup>12</sup>      |  |
 
-#### Authentication
+### Authentication
 
 The authentication setup provided by Oak is not affected by the dynamic 
membership 
 handling as long as the configured `LoginModule` implementations rely on the 
@@ -205,7 +207,7 @@ handling as long as the configured `LoginModule` 
implementations rely on the
 _("Apache Jackrabbit Oak External PrincipalConfiguration")_ is properly 
registered 
 with the `SecurityProvider` (see section 
[Configuration](defaultusersync.html#configuration)).
 
-#### Authorization
+### Authorization
 
 The authorization modules shipped with Oak only depend on `Principal`s (and 
not on
 user management functionality) and are therefore not affected by the dynamic 
diff --git 
a/oak-doc/src/site/markdown/security/authentication/external/externallogin_examples.md
 
b/oak-doc/src/site/markdown/security/authentication/external/externallogin_examples.md
index 2717910b1b..3175c640db 100644
--- 
a/oak-doc/src/site/markdown/security/authentication/external/externallogin_examples.md
+++ 
b/oak-doc/src/site/markdown/security/authentication/external/externallogin_examples.md
@@ -18,8 +18,92 @@
 Authentication with External Login Module : Examples
 ----------------------------------------------------
 
-- [Integration with Standard Oak Authentication](#standard)
-- [Integration with Pre-Authentication and Login Module Chain](#preauth)
+<!-- MACRO{toc} -->
+
+<a name="standard-sling"></a>
+### 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 with `null` credentials 
as it is performed by 
+  Apache Sling (compatibility with Jackrabbit 1.0)
+
+- The `TokenLoginModule` is in charge of handling repository authentication 
+  request with `TokenCredentials`: 
+    - _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 the `ExternalIdentityProvider` 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 the `LoginModule` 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 the `Subject` with `Principal`s,
+    `Credentials` and `AuthInfo`.
+    
+    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 providing `Credentials` attributes that force
+    the `TokenLoginModule` 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](../tokenmanagement.html) 
for
+    details and for a description of the default implementation.
+    
+- The `ExternalLoginModule` is in charge of handling authentication request for
+  users managed by an `ExternalIdentityProvider`.
+    - _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 the `SyncHandler`.
+    - _Login Failure_: If the authentication fails (e.g. wrong IDP or invalid
+      `Credentials`), the login will proceed to the `LoginModuleImpl`.
+    - _Commit_: If the login succeeded the login module will populate the 
+      `Subject` with `Principal`s, `Credentials` and `AuthInfo`.
+   
+      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 an `ExternalIdentityProvider`. This
+  includes built-in system users like the administrator, the guest-user
+  (aka anonymous) or `SystemUsers`. 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 the `LoginModule` list. 
+    - _Commit_: If the login succeeded the login module will populate the 
+      `Subject` with `Principal`s, `Credentials` and `AuthInfo`.
+      
+      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.
+     
 
 <a name="standard"></a>
 ### Integration with Standard Oak Authentication
diff --git 
a/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md 
b/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
index 60a6bd6b2f..11440b25da 100644
--- a/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
+++ b/oak-doc/src/site/markdown/security/authentication/externalloginmodule.md
@@ -36,8 +36,9 @@ What it does not:
 * provide a transparent oak principal provider.
 * offer services for background synchronization of users and groups
 
-<a name="details"></a>
+See also [Best Practices for External 
Authentication](external/bestpractices.html).
 
+<a name="details"></a>
 ### Implementation Details
 The external identity and login handling is split into 3 parts:
 
diff --git a/oak-doc/src/site/markdown/security/authorization/bestpractices.md 
b/oak-doc/src/site/markdown/security/authorization/bestpractices.md
index 6c4ddebee4..5fad4fc81f 100644
--- a/oak-doc/src/site/markdown/security/authorization/bestpractices.md
+++ b/oak-doc/src/site/markdown/security/authorization/bestpractices.md
@@ -158,6 +158,7 @@ Don't specify redundant access control setup just to be on 
the safe side:
 
 - If access is granted, avoid repeating the same setup down the hierarchy.
 - Avoid setup for principals with administrative access for which permission 
evaluation is omitted. It might even create a false sense of security.
+- Avoid redundant membership as it will impact performance of permission 
evaluation
 
 ### Principal by principle
 
diff --git a/oak-doc/src/site/markdown/security/overview.md 
b/oak-doc/src/site/markdown/security/overview.md
index 8cdabcc87d..e1fd787a8d 100644
--- a/oak-doc/src/site/markdown/security/overview.md
+++ b/oak-doc/src/site/markdown/security/overview.md
@@ -37,6 +37,7 @@ The Oak Security Layer
      * [User and Group Synchronization](authentication/usersync.html)
      * [Identity Management](authentication/identitymanagement.html)
      * [LDAP Integration](authentication/ldap.html)
+     * [Best Practices](authentication/external/bestpractices.html)
 
 ### Authorization
 
@@ -44,6 +45,7 @@ The Oak Security Layer
      * [Access Control Management](accesscontrol.html)
      * [Permission Evaluation](permission.html)
      * [Combining Multiple Authorization Models](authorization/composite.html)
+     * [Best Practices](authorization/bestpractices.html)
   
 #### Access Control Management
 
diff --git a/oak-doc/src/site/markdown/security/principal.md 
b/oak-doc/src/site/markdown/security/principal.md
index bcde86c14d..cd3da47856 100644
--- a/oak-doc/src/site/markdown/security/principal.md
+++ b/oak-doc/src/site/markdown/security/principal.md
@@ -21,12 +21,12 @@ Principal Management
 <a name="jcr_api"></a>
 ### JCR API
 
-JCR itself doesn't come with a dedicated principal management API. Nevertheless
-the specification mentions `java.security.Principal` as key feature for access 
+JCR itself doesn't come with a dedicated principal management API. 
Nevertheless,
+the specification mentions `java.security.Principal` as a key feature for 
access 
 control management but leaves the discovery of principals to the 
implementation 
 (see [Section 
16.5.7](https://s.apache.org/jcr-2.0-spec/16_Access_Control_Management.html#16.5.7%20Principal%20Discovery)).
 
-Therefore an API for principal management has been defined as part of the
+Therefore, an API for principal management has been defined as part of the
 extensions present with Jackrabbit API.
 
 <a name="jackrabbit_api"></a>


Reply via email to