You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2021/04/07 09:27:29 UTC

[isis] 04/04: ISIS-2484: adds docs on security implementations

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

danhaywood pushed a commit to branch 2.0.0-M5
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 739aa6a3e09861dac90a92a96304e819689c112f
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Apr 7 10:27:10 2021 +0100

    ISIS-2484: adds docs on security implementations
---
 .../src/main/adoc/modules/core/pages/about.adoc    |  15 +-
 .../adoc/modules/core/partials/module-nav.adoc     |   2 +-
 .../adoc/modules/secman/pages/shiro-realm.adoc     |   7 +-
 .../images}/activeds-ldap-groups.png               | Bin
 .../images}/activeds-ldap-mojo-partition.png       | Bin
 .../images}/activeds-ldap-mojo-root-dse.png        | Bin
 .../images}/activeds-ldap-sasl-authentication.png  | Bin
 .../images}/activeds-ldap-users.png                | Bin
 .../configure-shiro-to-use-isis-ldap-realm.png     | Bin
 .../adoc/modules/shiro-realm-ldap/pages/about.adoc |   4 +
 .../shiro-realm-ldap/pages}/ldap-realm.adoc        |   0
 .../setup-and-configure-dependencyManagement.adoc  |  40 ++
 .../setup-and-configure-mavendeps-jdo.adoc         |  21 +-
 .../setup-and-configure-mavendeps-jpa.adoc         |  21 +-
 .../setup-and-configure-mavendeps-webapp.adoc      |  22 +-
 .../ROOT/pages/setup-and-configuration.adoc        |  57 +--
 .../ROOT/pages/setup-and-configuration.adoc        |  54 +--
 security/adoc/modules/ROOT/pages/about.adoc        |  71 +--
 .../domain-services-api-for-applications.adoc      |  43 --
 .../adoc/modules/ROOT/partials/module-nav.adoc     |   2 -
 .../configure-isis-to-use-bypass.PNG               | Bin 12091 -> 0 bytes
 .../src/main/adoc/modules/bypass/pages/about.adoc  |  29 +-
 .../main/adoc/modules/keycloak/pages/about.adoc    |  36 +-
 .../adoc/modules/keycloak/partials/module-nav.adoc |   1 -
 .../configuration/configure-isis-to-use-shiro.png  | Bin 11356 -> 0 bytes
 .../configure-shiro-to-use-custom-jdbc-realm.png   | Bin 33149 -> 0 bytes
 .../ini/configure-shiro-to-use-ini-realm.png       | Bin
 .../shiro/images/ini/shiro-ini-realm.drawio.svg    |   1 +
 .../modules/shiro/images/shiro-design.drawio.svg   |   1 +
 .../src/main/adoc/modules/shiro/pages/about.adoc   | 529 ++++++++++++++++++++-
 .../pages/about/configuring-isis-to-use-shiro.adoc | 113 -----
 .../pages/about/enhanced-wildcard-permission.adoc  |  65 ---
 .../adoc/modules/shiro/pages/about/ini-realm.adoc  | 141 ------
 .../adoc/modules/shiro/pages/about/jdbc-realm.adoc | 111 -----
 .../adoc/modules/shiro/pages/about/run-as.adoc     | 101 ----
 .../modules/shiro/pages/about/shiro-caching.adoc   |  40 --
 .../adoc/modules/shiro/partials/module-nav.adoc    |   1 -
 .../src/main/adoc/modules/spring/pages/about.adoc  |  21 +
 .../ROOT/pages/setup-and-configuration.adoc        |  54 +--
 .../ROOT/pages/setup-and-configuration.adoc        |  54 +--
 40 files changed, 749 insertions(+), 908 deletions(-)

diff --git a/core/security/src/main/adoc/modules/core/pages/about.adoc b/core/security/src/main/adoc/modules/core/pages/about.adoc
index 9c868a9..bb09c09 100644
--- a/core/security/src/main/adoc/modules/core/pages/about.adoc
+++ b/core/security/src/main/adoc/modules/core/pages/about.adoc
@@ -1,5 +1,16 @@
-= Security API
+= Security Component SPIs
 
 :Notice: 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 ag [...]
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
+The core framework defines two SPIs that define the security architecture:
+
+* the xref:refguide:core:index/security/authentication/Authenticator.adoc[Authenticator] SPI allows for different authentication implementations to be used
+
+* the xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] SPI allows for different authorization mechanisms to be used
+
+By "authentication" we mean logging into the application using some credentials, typically a username and password.
+Authentication also means looking up the set of roles to which a user belongs.
+
+And by "authorization" we mean permissions: granting roles to have access to features (domain object members) of the app, and granting users to those roles.
+
+
diff --git a/core/security/src/main/adoc/modules/core/partials/module-nav.adoc b/core/security/src/main/adoc/modules/core/partials/module-nav.adoc
index 0c16738..569a640 100644
--- a/core/security/src/main/adoc/modules/core/partials/module-nav.adoc
+++ b/core/security/src/main/adoc/modules/core/partials/module-nav.adoc
@@ -1,5 +1,5 @@
 
 
 
-* xref:security:core:about.adoc[API]
+* xref:security:core:about.adoc[Security Component SPI]
 
diff --git a/extensions/security/secman/adoc/modules/secman/pages/shiro-realm.adoc b/extensions/security/secman/adoc/modules/secman/pages/shiro-realm.adoc
index c48bddb..6d9d623 100644
--- a/extensions/security/secman/adoc/modules/secman/pages/shiro-realm.adoc
+++ b/extensions/security/secman/adoc/modules/secman/pages/shiro-realm.adoc
@@ -4,14 +4,17 @@
 :page-partial:
 
 
-The SecMan extension includes a Shiro realm, which fits in as follows:
+WARNING: TODO - not yet reviewed for v2.
 
-The general configuration is as follows:
+Because each user to be authorised must exist in the SecMan database, this means that it can also act as a secondary authenticator.
+It does this by providing an implementation of the Shiro `Realm` API, which fits in as follows:
 
 image::shiro-realm/configure-shiro-to-use-isisaddons-security-module-realm.PNG[width="600px"]
 
 where the `IsisModuleSecurityRealm` realm is the implementation provided by the module.
 
+Using this design the password management can be handled to a subsidiary (delegate) Shiro realm (for example, using the xref:shiro-realm-ldap:about.adoc[]).
+
 In the configuration above user passwords are stored in the database.  The module uses link:http://www.mindrot.org/projects/jBCrypt/[jBCrypt] so that passwords are only stored in a (one-way) encrypted form in the database.
 
 
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-groups.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-groups.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-groups.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-groups.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-mojo-partition.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-mojo-partition.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-mojo-partition.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-mojo-partition.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-mojo-root-dse.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-mojo-root-dse.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-mojo-root-dse.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-mojo-root-dse.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-sasl-authentication.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-sasl-authentication.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-sasl-authentication.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-sasl-authentication.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-users.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-users.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/activeds-ldap-users.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/activeds-ldap-users.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/configure-shiro-to-use-isis-ldap-realm.png b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/configure-shiro-to-use-isis-ldap-realm.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ldap/configure-shiro-to-use-isis-ldap-realm.png
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/images/configure-shiro-to-use-isis-ldap-realm.png
diff --git a/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/about.adoc b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/about.adoc
index 9105a3b..27e829f 100644
--- a/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/about.adoc
+++ b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/about.adoc
@@ -14,3 +14,7 @@ WARNING: TODO
 // == Setting up Users/Groups in Apache Directory Studio
 
 
+
+The Shiro framework also ships with an implementation of an LDAP-based realm; LDAP is often used to manage user/passwords and corresponding user groups.
+
+Apache Isis extends Shiro's implementation this  `IsisLdapRealm`, which provides more flexibility for both group/role and role/permissions management.
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/ldap-realm.adoc b/extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/ldap-realm.adoc
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/pages/about/ldap-realm.adoc
rename to extensions/security/shiro-realm-ldap/adoc/modules/shiro-realm-ldap/pages/ldap-realm.adoc
diff --git a/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-dependencyManagement.adoc b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-dependencyManagement.adoc
new file mode 100644
index 0000000..a3737e7
--- /dev/null
+++ b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-dependencyManagement.adoc
@@ -0,0 +1,40 @@
+= Dependency Management
+
+:Notice: 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 ag [...]
+:page-partial:
+
+
+
+If your application inherits from the Apache Isis starter app (`org.apache.isis.app:isis-app-starter-parent` then that will define the version automatically:
+
+[source,xml,subs="attributes+"]
+.pom.xml
+----
+<parent>
+    <groupId>org.apache.isis.app</groupId>
+    <artifactId>isis-app-starter-parent</artifactId>
+    <version>{page-isisrel}</version>
+    <relativePath/>
+</parent>
+----
+
+Alternatively, import the core BOM.
+This is usually done in the top-level parent pom of your application:
+
+[source,xml,subs="attributes+"]
+.pom.xml
+----
+<dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core</artifactId>
+            <version>{page-isisrel}</version>
+            <scope>import</scope>
+            <type>pom</type>
+        </dependency>
+    </dependencies>
+</dependencyManagement>
+----
+
+
diff --git a/security/spring/src/main/adoc/modules/spring/pages/about.adoc b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jdo.adoc
similarity index 64%
copy from security/spring/src/main/adoc/modules/spring/pages/about.adoc
copy to mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jdo.adoc
index b168dc9..7de63ca 100644
--- a/security/spring/src/main/adoc/modules/spring/pages/about.adoc
+++ b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jdo.adoc
@@ -1,10 +1,25 @@
-= Sring Security
+= Maven pom.xml
 
 :Notice: 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 ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 
-This guide describes the configuration of the Spring implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
+include::docs:mavendeps:partial$setup-and-configure-dependencyManagement.adoc[leveloffset=+1]
 
 
+== Dependency
+
+For every Maven module that includes JDO entities, add the following dependency:
+
+[source,xml]
+.pom.xml
+----
+<dependencies>
+    <dependency>
+        <groupId>org.apache.isis.mavendeps</groupId>
+        <artifactId>isis-mavendeps-jdo</artifactId>
+        <type>pom</type>
+    </dependency>
+</dependencies>
+----
+
diff --git a/security/spring/src/main/adoc/modules/spring/pages/about.adoc b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jpa.adoc
similarity index 64%
copy from security/spring/src/main/adoc/modules/spring/pages/about.adoc
copy to mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jpa.adoc
index b168dc9..86d9e01 100644
--- a/security/spring/src/main/adoc/modules/spring/pages/about.adoc
+++ b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-jpa.adoc
@@ -1,10 +1,25 @@
-= Sring Security
+= Maven pom.xml
 
 :Notice: 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 ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 
-This guide describes the configuration of the Spring implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
+include::docs:mavendeps:partial$setup-and-configure-dependencyManagement.adoc[leveloffset=+1]
 
 
+== Dependency
+
+For every Maven module that includes JPA entities, add the following dependency:
+
+[source,xml]
+.pom.xml
+----
+<dependencies>
+    <dependency>
+        <groupId>org.apache.isis.mavendeps</groupId>
+        <artifactId>isis-mavendeps-jpa</artifactId>
+        <type>pom</type>
+    </dependency>
+</dependencies>
+----
+
diff --git a/security/spring/src/main/adoc/modules/spring/pages/about.adoc b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-webapp.adoc
similarity index 64%
copy from security/spring/src/main/adoc/modules/spring/pages/about.adoc
copy to mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-webapp.adoc
index b168dc9..ec6d152 100644
--- a/security/spring/src/main/adoc/modules/spring/pages/about.adoc
+++ b/mavendeps/adoc/modules/mavendeps/partials/setup-and-configure-mavendeps-webapp.adoc
@@ -1,10 +1,26 @@
-= Sring Security
+= Maven pom.xml
 
 :Notice: 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 ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 
-This guide describes the configuration of the Spring implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
+include::docs:mavendeps:partial$setup-and-configure-dependencyManagement.adoc[leveloffset=+1]
+
+
+== Dependency
+
+In the webapp module of your application, add the following dependency:
+
+[source,xml]
+.pom.xml
+----
+<dependencies>
+    <dependency>
+        <groupId>org.apache.isis.mavendeps</groupId>
+        <artifactId>isis-mavendeps-webapp</artifactId>
+        <type>pom</type>
+    </dependency>
+</dependencies>
+----
 
 
diff --git a/persistence/jdo/adoc/modules/ROOT/pages/setup-and-configuration.adoc b/persistence/jdo/adoc/modules/ROOT/pages/setup-and-configuration.adoc
index fe485e0..7e88c0c 100644
--- a/persistence/jdo/adoc/modules/ROOT/pages/setup-and-configuration.adoc
+++ b/persistence/jdo/adoc/modules/ROOT/pages/setup-and-configuration.adoc
@@ -2,64 +2,9 @@
 
 :Notice: 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 ag [...]
 
-
-
 This section describes how to include the JDO module and set its configuration properties.
 
-
-== Maven pom.xml
-
-=== Dependency Management
-
-If your application inherits from the Apache Isis starter app (`org.apache.isis.app:isis-app-starter-parent` then that will define the version automatically:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<parent>
-    <groupId>org.apache.isis.app</groupId>
-    <artifactId>isis-app-starter-parent</artifactId>
-    <version>{page-isisrel}</version>
-    <relativePath/>
-</parent>
-----
-
-Alternatively, import the core BOM.
-This is usually done in the top-level parent pom of your application:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<dependencyManagement>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core</artifactId>
-            <version>{page-isisrel}</version>
-            <version>2.0.0-SNAPSHOT</version>
-            <scope>import</scope>
-            <type>pom</type>
-        </dependency>
-    </dependencies>
-</dependencyManagement>
-----
-
-
-=== Dependency
-
-For every Maven module that includes JPA entities, add the following dependency:
-
-[source,xml]
-.pom.xml
-----
-<dependencies>
-    <dependency>
-        <groupId>org.apache.isis.mavendeps</groupId>
-        <artifactId>isis-mavendeps-jpa</artifactId>
-        <type>pom</type>
-    </dependency>
-</dependencies>
-----
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-jdo.adoc[leveloffset=+1]
 
 
 == Update AppManifest
diff --git a/persistence/jpa/adoc/modules/ROOT/pages/setup-and-configuration.adoc b/persistence/jpa/adoc/modules/ROOT/pages/setup-and-configuration.adoc
index f5708cc..a4fd264 100644
--- a/persistence/jpa/adoc/modules/ROOT/pages/setup-and-configuration.adoc
+++ b/persistence/jpa/adoc/modules/ROOT/pages/setup-and-configuration.adoc
@@ -6,60 +6,8 @@
 
 This section describes how to include the JPA module and setup its configuration properties.
 
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-jpa.adoc[leveloffset=+1]
 
-== Maven pom.xml
-
-=== Dependency Management
-
-If your application inherits from the Apache Isis starter app (`org.apache.isis.app:isis-app-starter-parent` then that will define the version automatically:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<parent>
-    <groupId>org.apache.isis.app</groupId>
-    <artifactId>isis-app-starter-parent</artifactId>
-    <version>{page-isisrel}</version>
-    <relativePath/>
-</parent>
-----
-
-Alternatively, import the core BOM.
-This is usually done in the top-level parent pom of your application:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<dependencyManagement>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core</artifactId>
-            <version>{page-isisrel}</version>
-            <version>2.0.0-SNAPSHOT</version>
-            <scope>import</scope>
-            <type>pom</type>
-        </dependency>
-    </dependencies>
-</dependencyManagement>
-----
-
-
-=== Dependency
-
-For every Maven module that includes JPA entities, add the following dependency:
-
-[source,xml]
-.pom.xml
-----
-<dependencies>
-    <dependency>
-        <groupId>org.apache.isis.mavendeps</groupId>
-        <artifactId>isis-mavendeps-jpa</artifactId>
-        <type>pom</type>
-    </dependency>
-</dependencies>
-----
 
 
 == Update AppManifest
diff --git a/security/adoc/modules/ROOT/pages/about.adoc b/security/adoc/modules/ROOT/pages/about.adoc
index 32a79cb..b2a49d3 100644
--- a/security/adoc/modules/ROOT/pages/about.adoc
+++ b/security/adoc/modules/ROOT/pages/about.adoc
@@ -4,12 +4,12 @@
 :page-partial:
 
 
-This guide describes the authentication and authorization features available to secure your Apache Isis application.
+This guide describes how to secure your Apache Isis application by configuring an appropriate implementation of its authentication and authorization SPIIs.
 
 
-== Terminology
+== Security Architecture
 
-Apache Isis has built-in support for authentication and authorization:
+Apache Isis defines an SPI for both authentication and authorization:
 
 * By "authentication" we mean logging into the application using some credentials, typically a username and password.
 Authentication also means looking up the set of roles to which a user belongs.
@@ -17,11 +17,22 @@ Authentication also means looking up the set of roles to which a user belongs.
 The framework allows for different authentication mechanisms through the xref:refguide:core:index/security/authentication/Authenticator.adoc[Authenticator] SPI.
 .
 
-* By "authorization" we mean permissions: granting roles to have access to features (domain object members) of the app.
+* By "authorization" we mean permissions: granting roles to have access to features (domain object members) of the app, and granting users to those roles.
 +
 The framework allows for different authorization mechanisms through the xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] SPI.
 
-There are two levels of permissions:
+
+There are several implementations of these SPIs to choose from; these make up the bulk of this guide.
+
+include::security:bypass:partial$module-nav.adoc[]
+include::security:shiro:partial$module-nav.adoc[]
+include::security:keycloak:partial$module-nav.adoc[]
+include::security:spring:partial$module-nav.adoc[]
+
+
+== Permissions
+
+The xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] SPI defines two types of permissions:
 
 * _Read_ permission means that the user can view the object member; it will be rendered in the UI.
 +
@@ -33,9 +44,9 @@ For actions this means that they can be invoked.
 
 If there is neither _read_ nor _write_ permissions then the feature will be invisible to the user.
 
-[NOTE]
-.What about auditing?
-====
+
+== Auditing
+
 A further aspect of security is auditing: recording what data was modified by which user.
 
 Apache Isis provides the xref:refguide:applib:index/services/iactn/InteractionContext.adoc[InteractionContext] can be used to track the actions being invoked, and the xref:refguide:applib:index/services/publishing/spi/EntityPropertyChangeSubscriber.adoc[EntityPropertyChangeSubscriber] captures what data was modified as a result (auditing).
@@ -44,46 +55,38 @@ The xref:security:audit-trail:about.adoc[Audit Trail] module provides an impleme
 
 For xref:refguide:applib:index/services/publishing/spi/CommandSubscriber.adoc[CommandSubscriber] SPI can be also be used to capture actions.
 The xref:userguide:command-log:about.adoc[Command Log] extension provides a simple implementation of this SPI.
-====
-
 
-== Implementations
 
-[#shiro]
-=== Shiro
+== Programmers' API
 
-The framework provides an API for both authentication and authorization, and provides an implementation that integrates with link:http://shiro.apache.org[Apache Shiro].
-Shiro in turn uses the concept of a _realm_ as a source for both authentication and optionally authorization.
+Generally speaking your domain objects (or more generally your application) should be agnostic of the user/roles that are interacting with them; applying security permissions is the responsibility of the framework.
 
-Shiro ships with a simple text-based realm -- the `IniRealm` -- which reads users (and password), user roles and role permissions from the `shiro.ini` file.
-The xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are both configured to use this realm.
+If you need to determine the identity of the current user, you can usually use Apache Isis' xref:refguide:applib:index/services/user/UserService.adoc[UserService] API, in the form of  xref:refguide:applib:index/services/user/UserMemento.adoc[UserMemento].
 
-The Shiro framework ships with an implementation of an LDAP-based realm; LDAP is often used to manage user/passwords and corresponding user groups.
-Apache Isis extends Shiro's implementation this  `IsisLdapRealm`, which provides more flexibility for both group/role and role/permissions management.
+For example:
 
+[source,java]
+----
+final UserMemento user = userService.getUser();
+final List<RoleMemento> roles = user.getRoles();
+for (RoleMemento role : roles) {
+    String roleName = role.getName();
+    ...
+}
+----
 
-=== Bypass
+Each role's `name` property encodes both the realm that provided the role, and the role identity itself.
 
-The framework provides a "bypass" implementation, useful for quick-n-dirty prototyping when you want to in effect disable (bypass) security completely.
+If using the xref:vw::about.adoc[Wicket viewer], then note there will also be another role which is used internally (namely `org.apache.isis.viewer.wicket.roles.USER`).
 
-=== KeyCloak
 
-WARNING: TODO: v2 - to document.
 
-=== Spring
 
-WARNING: TODO: v2 - WIP, to document
+== Extensions
 
-== SecMan
-
-The xref:security:ROOT:about.adoc[SecMan extension]'s primary purpose is for authorisation, defining a database of roles and permissions associated with
-those roles.
-It also maps users to roles.
+In addition to the security SPI implementations, there are a number of security-related extesions.
 
+The most significant of these is probably xref:security:secman:about.adoc[SecMan], which uses a database of users, roles and permission entities (either xref:pjpa:ROOT:about.adoc[JPA] or xref:pjdo:ROOT:about.adoc[JDO]) to manage authorisation.
 As these users, roles and permissions are domain objects, they can be administered through Apache Isis itself.
 
-Because each user to be authorised must exist in the SecMan database, this means that it can also act as a secondary authenticator.
-It does this by providing an implementation of the Shiro `Realm` API.
-Using this design the password management can be handled to a subsidiary (delegate) Shiro realm (for example, LDAP, as discussed <<shiro, above>>).
-
 
diff --git a/security/adoc/modules/ROOT/pages/domain-services-api-for-applications.adoc b/security/adoc/modules/ROOT/pages/domain-services-api-for-applications.adoc
deleted file mode 100644
index b4456cd..0000000
--- a/security/adoc/modules/ROOT/pages/domain-services-api-for-applications.adoc
+++ /dev/null
@@ -1,43 +0,0 @@
-= Domain Services
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-
-Generally speaking your domain objects (or more generally your application) should be agnostic of the user/roles that are interacting with them; applying security permissions is the responsibility of the framework.
-
-Still, on very rare occasion you may have a need, in which case you can either use Apache Isis' `UserService` API or you can reach further down the stack and use the JEE Servlet API.
-
-
-== `UserService` API
-
-The xref:refguide:applib:index/services/user/UserService.adoc[UserService] service exposes the following API:
-
-[source,java]
-----
-final UserMemento user = userService.getUser();
-final List<RoleMemento> roles = user.getRoles();
-for (RoleMemento role : roles) {
-    String roleName = role.getName();
-    ...
-}
-----
-
-Each role's `name` property encodes both the realm that provided the role, and the role identity itself.
-
-For example, in the simpleapp, if logging in as `dick` with the following entries for `realm1`:
-
-[source,ini]
-----
-dick = pass, user_role, analysis_role, self-install_role
-----
-
-then this corresponds to the roles "realm1:user_role", "realm1:self-install_role" and "realm1:analysis_role".
-
-If using the Wicket viewer, then note there will also be another role which is used internally (namely "org.apache.isis.viewer.wicket.roles.USER").
-
-
-
-
-
diff --git a/security/adoc/modules/ROOT/partials/module-nav.adoc b/security/adoc/modules/ROOT/partials/module-nav.adoc
index ce18fa5..a669520 100644
--- a/security/adoc/modules/ROOT/partials/module-nav.adoc
+++ b/security/adoc/modules/ROOT/partials/module-nav.adoc
@@ -1,6 +1,4 @@
 
-* xref:security:ROOT:domain-services-api-for-applications.adoc[Domain Services API]
-
 // usage by isis viewers is in module-nav-end.adoc
 
 
diff --git a/security/bypass/src/main/adoc/modules/bypass/images/security/security-apis-impl/configure-isis-to-use-bypass.PNG b/security/bypass/src/main/adoc/modules/bypass/images/security/security-apis-impl/configure-isis-to-use-bypass.PNG
deleted file mode 100644
index 387594b..0000000
Binary files a/security/bypass/src/main/adoc/modules/bypass/images/security/security-apis-impl/configure-isis-to-use-bypass.PNG and /dev/null differ
diff --git a/security/bypass/src/main/adoc/modules/bypass/pages/about.adoc b/security/bypass/src/main/adoc/modules/bypass/pages/about.adoc
index e0c5ac8..d2fb3f7 100644
--- a/security/bypass/src/main/adoc/modules/bypass/pages/about.adoc
+++ b/security/bypass/src/main/adoc/modules/bypass/pages/about.adoc
@@ -3,28 +3,35 @@
 :Notice: 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 ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 
 The bypass implementation, as its name suggests, allows both authentication and authorization to be bypassed.
-
 This is typically used for integration tests or for prototyping.
 
-== Configuring to use Bypass
 
-The bypass security component consists of an implementation of both the `AuthenticationManager` and `AuthorizationManager` APIs, and are intended for prototyping use only.
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
 
-The authentication manager allows access with any credentials (in a sense, "bypassing" authentication), while the authorization manager provides access to all class members (in a sense, "bypassing" authorization).
 
 
+== Update AppManifest
 
-To tell Apache Isis to bypass security, use the appropriate `IsisModuleSecurityBypass` in the xref:userguide:fun:modules.adoc[app manifest].
+In your application's `AppManifest` (top-level Spring `@Configuration` used to bootstrap the app), import the
 
-[source,ini]
+[source,java]
+.AppManifest.java
 ----
-isis.authentication=bypass
-isis.authorization=bypass
+@Configuration
+@Import({
+        ...
+        IsisModuleSecurityBypass.class,
+        ...
+})
+public class AppManifest {
+}
 ----
 
-This installs the appropriate no-op implementations for both authentication and authorization:
+Make sure that no other `IsisModuleSecurityXxx` module is imported.
+
+
+== In Use
 
-image::security/security-apis-impl/configure-isis-to-use-bypass.PNG[width="600px"]
+With bypass installed, you should be able to login with any credentials.
diff --git a/security/keycloak/src/main/adoc/modules/keycloak/pages/about.adoc b/security/keycloak/src/main/adoc/modules/keycloak/pages/about.adoc
index 7622592..df8d530 100644
--- a/security/keycloak/src/main/adoc/modules/keycloak/pages/about.adoc
+++ b/security/keycloak/src/main/adoc/modules/keycloak/pages/about.adoc
@@ -8,16 +8,38 @@ WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 This guide describes the configuration of the Keycloak implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
 
 
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
 
-== FAQ
 
-How do I switch from using Shiro to using Keycloak?::
-+
-* First, update the webapp's `pom.xml` to reference `org.apache.isis.security:isis-security-keycloak-impl` (instead of `o.a.i.security:isis-security-shiro-impl`)
+== Update AppManifest
+
+In your application's `AppManifest` (top-level Spring `@Configuration` used to bootstrap the app), import the
+
+[source,java]
+.AppManifest.java
+----
+@Configuration
+@Import({
+        ...
+        IsisModuleSecurityKeycloak.class,
+        ...
+})
+public class AppManifest {
+}
+----
+
+Make sure that no other `IsisModuleSecurityXxx` module is imported.
 
-* Then change the `AppManifest` class to reference `IsisModuleSecurityKeycloak` instead of IsisModuleSecurityShiro`
 
+== Design
+
+The module configures a filter that expects Keycloak to set three `X-Auth-Xxx` headers:
+
+* `X-Auth-Userid` - is used as the username
+* `X-Auth-Roles` - is a comma-separated set of roles.
 +
-This will result in the `KeycloakFilter` (link:https://github.com/apache/isis/blob/master/security/keycloak/src/main/java/org/apache/isis/security/keycloak/webmodule/KeycloakFilter.java[code here]) being configured. +
+The `org.apache.isis.viewer.wicket.roles.USER` role -- as required by xref:vw::about.adoc[Web UI (Wicket viewer)]  -- is automatically added to this list of roles.
+
+* `X-Auth-Subject` - is unused
 
-As you can see, it expects for Keycloak to set three `X-Auth-Xxx` headers, and it just blindly trusts them to create an appropriate `AuthenticationSession`.
+The user and roles are accessible programmatically from the xref:refguide:applib:index/services/user/UserMemento.adoc[UserMemento] obtained from xref:refguide:applib:index/services/user/UserService.adoc[UserService] domain service.
diff --git a/security/keycloak/src/main/adoc/modules/keycloak/partials/module-nav.adoc b/security/keycloak/src/main/adoc/modules/keycloak/partials/module-nav.adoc
index 952cf23..bb357c6 100644
--- a/security/keycloak/src/main/adoc/modules/keycloak/partials/module-nav.adoc
+++ b/security/keycloak/src/main/adoc/modules/keycloak/partials/module-nav.adoc
@@ -1,4 +1,3 @@
 
 
-
 * xref:security:keycloak:about.adoc[Keycloak Implementation]
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configure-isis-to-use-shiro.png b/security/shiro/src/main/adoc/modules/shiro/images/configuration/configure-isis-to-use-shiro.png
deleted file mode 100644
index 891d373..0000000
Binary files a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configure-isis-to-use-shiro.png and /dev/null differ
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/jdbc/configure-shiro-to-use-custom-jdbc-realm.png b/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/jdbc/configure-shiro-to-use-custom-jdbc-realm.png
deleted file mode 100644
index d64751a..0000000
Binary files a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/jdbc/configure-shiro-to-use-custom-jdbc-realm.png and /dev/null differ
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ini/configure-shiro-to-use-ini-realm.png b/security/shiro/src/main/adoc/modules/shiro/images/ini/configure-shiro-to-use-ini-realm.png
similarity index 100%
rename from security/shiro/src/main/adoc/modules/shiro/images/configuration/configuring-shiro/ini/configure-shiro-to-use-ini-realm.png
rename to security/shiro/src/main/adoc/modules/shiro/images/ini/configure-shiro-to-use-ini-realm.png
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/ini/shiro-ini-realm.drawio.svg b/security/shiro/src/main/adoc/modules/shiro/images/ini/shiro-ini-realm.drawio.svg
new file mode 100644
index 0000000..7a50e93
--- /dev/null
+++ b/security/shiro/src/main/adoc/modules/shiro/images/ini/shiro-ini-realm.drawio.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="411px" height="242px" viewBox="-0.5 -0.5 411 242" content="&lt;mxfile host=&quot;drawio-plugin&quot; modified=&quot;2021-04-07T06:19:59.781Z&quot; agent=&quot;5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36&quot; etag=&quot;J8eTNiuta2DSs0hM89os&quot; version=&quot;13.7.9&quot; type=&quot;embed&quot;&gt;&lt;diagram id=&quot;QRW- [...]
\ No newline at end of file
diff --git a/security/shiro/src/main/adoc/modules/shiro/images/shiro-design.drawio.svg b/security/shiro/src/main/adoc/modules/shiro/images/shiro-design.drawio.svg
new file mode 100644
index 0000000..81e6229
--- /dev/null
+++ b/security/shiro/src/main/adoc/modules/shiro/images/shiro-design.drawio.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="411px" height="240px" viewBox="-0.5 -0.5 411 240" content="&lt;mxfile host=&quot;drawio-plugin&quot; modified=&quot;2021-04-07T06:08:58.800Z&quot; agent=&quot;5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36&quot; etag=&quot;qN7hG62d_mdquBz4PUzy&quot; version=&quot;13.7.9&quot; type=&quot;embed&quot;&gt;&lt;diagram id=&quot;QRW- [...]
\ No newline at end of file
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about.adoc
index 44312fc..f6be470 100644
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about.adoc
+++ b/security/shiro/src/main/adoc/modules/shiro/pages/about.adoc
@@ -3,14 +3,525 @@
 :Notice: 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 ag [...]
 :page-partial:
 
-WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 
-This guide describes the configuration of the Shiro implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
+This guide describes the design and configuration of the Apache Shiro integration with Apache Isis.
+
+
+== Design
+
+The Shiro integration provides an implementation for both the
+xref:refguide:core:index/security/authentication/Authenticator.adoc[Authenticator] and xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] SPIs.
+These both delegate to Shiro's `SubjectUtils` class that in turn delegates to the `SecurityManager`.
+These are available as thread-locals (set up in a servlet filter):
+
+.High-level design of the Shiro integration
+image::shiro-design.drawio.svg[]
+
+Shiro's link:http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/subject/Subject.html[Subject] API defines the notion of a user, and uses the concept of a https://shiro.apache.org/static/1.7.1/apidocs/org/apache/shiro/realm/Realm.html[Realm] as the means to authenticate the ``Subject``s and optionally populate it with permissions.
+
+Shiro ships with a simple text-based realm -- the `IniRealm` -- which reads users (and password), user roles and role permissions from the `shiro.ini` file.
+Configuring this realm is described <<shiro-ini-realm,below>>
+
+TIP: The xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are both configured to use this realm.
+
+A more sophisticated option is the LDAP realm.
+Shiro has its own implementation which is extended in the  provides the xref:security:shiro-realm-ldap:about.adoc[LDAP realm]
+This realm also supports permissions.
+
+Permissions are ultimately represented as strings, and their interpretation of them is the responsibility of `AuthorizorShiro`.
+An enhanced "wildcard" syntax, described  <<enhanced-wildcard-permission,below>> in more detail, incorporates the notion of read and write permissions, and also of vetoing permissions (as well as the usual allow permissions).
+
+
+[[configuring-isis-to-use-shiro]]
+== Configuring to use Shiro
+
+Apache Isis' security mechanism is configurable, specifying an `Authenticator` and an `Authorizor` (non-public) APIs.
+The Shiro security mechanism is an integration with Apache Shiro that implements both interfaces.
+
+[TIP]
+====
+Both the xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are pre-configured to use Apache Shiro, so much of what follows may well have been set up already.
+====
+
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
+
+
+=== Update AppManifest
+
+In your application's `AppManifest` (top-level Spring `@Configuration` used to bootstrap the app), import the
+
+[source,java]
+.AppManifest.java
+----
+@Configuration
+@Import({
+        ...
+        IsisModuleSecurityShiro.class,
+        ...
+})
+public class AppManifest {
+}
+----
+
+Make sure that no other `IsisModuleSecurityXxx` module is imported.
+
+=== Configuration Properties
+
+The Shiro integration supports the following config properties:
+
+* xref:refguide:config:sections/isis.security.shiro.adoc#isis.security.shiro.auto-logout-if-already-authenticated[isis.security.shiro.auto-logout-if-already-authenticated]
+
+=== Shiro Realms and shiro.ini
+
+Shiro uses the concept of realms to define its own set of authenticated users and their roles.
+Either one or many realms can be configured.
+
+The `shiro.ini` file is used to define which realm are to be used.
+This resides in the default package (in other words, in `src/main/resources` in the webapp module).
+
+[source,ini]
+----
+securityManager.realms = $realmName
+----
+
+Shiro's ini file supports a "poor-man's" dependency injection (link:https://shiro.apache.org/configuration.html[their words]), and so `$realmName` in the above example is a reference to a realm defined elsewhere in `shiro.ini`.
+The subsequent sections describe the specifics for thevarious realm implementations available to you.
+
+It's also possible to configure Shiro to support multiple realms.
+
+[source,ini]
+----
+securityManager.realms = $realm1,$realm2
+----
+
+How to configure the text-based ini realm is explained <<shiro-ini-realm,below>>.
+Another option lternative is the xref:security:shiro-realm-ldap:about.adoc[LDAP realm].
+
+
+[#shiro-ini-realm]
+== Shiro Ini Realm
+
+The Shiro concept of a `Realm` allows different implementations of both the authentication and authorisation mechanism to be plugged in.
+
+The simplest realm to use is Shiro's built-in `IniRealm`, which reads from the (same) `shiro.ini` file.
+
+image::ini/shiro-ini-realm.drawio.svg[]
+
+This is suitable for prototyping, but isn't intended for production use, if only because user/password credentials are stored in plain text.
+Nevertheless, it's a good starting point.
+The app generated by both the xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are configured to use this realm.
+
+
+
+=== Shiro Configuration
+
+To use the built-in `IniRealm`, we add the following to `shiro.ini`:
+
+[source,ini]
+----
+securityManager.realms = $iniRealm
+----
+
+(Unlike other realms) there is no need to "define" `$iniRealm`; it is automatically available to us.
+
+Specifying `$iniRealm` means that the usernames/passwords, roles and permissions are read from the `shiro.ini` file itself.
+Specifically:
+
+* the users/passwords and their roles from the `[users]` sections;
+* the roles are mapped to permissions in the `[roles]` section.
+
+The format of these is described below.
+
+==== `[users]` section
+
+This section lists users, passwords and their roles.
+
+For example:
+
+[source,ini]
+----
+sven = pass, admin_role
+dick = pass, user_role, analysis_role, self-install_role
+bob  = pass, user_role, self-install_role
+----
+
+The first value is the password (eg "pass", the remaining values are the role(s).
+
+==== `[roles]` section
+
+This section lists roles and their corresponding permissions.
+
+For example:
+
+[source,ini]
+----
+user_role = *:ToDoItems:*:*,\
+            *:ToDoItem:*:*,\
+            *:TodoAppDashboard:*:*
+analysis_role = *:ToDoItemAnalysis:*:*,\
+            *:ToDoItemsByCategoryViewModel:*:*,\
+            *:ToDoItemsByDateRangeViewModel:*:*
+self-install_role = *:ToDoItemsFixturesService:install:*
+admin_role = *
+----
+
+The value is a comma-separated list of permissions for the role.
+The format is:
+
+[source,ini]
+----
+packageName:className:memberName:r,w
+----
+
+where:
+
+* `memberName` is the property, collection or action name.
+* `r` indicates that the member is visible
+* `w` indicates that the member is usable (editable or invokable)
+
+and where each of the parts of the permission string can be wildcarded using `*`.
+
+Because these are wildcards, a '*' can be used at any level.
+Additionally, missing levels assume wildcards.
+
+Thus:
+
+[source,ini]
+----
+com.mycompany.myapp:Customer:firstName:r,w   # view or edit customer's firstName
+com.mycompany.myapp:Customer:lastName:r      # view customer's lastName only
+com.mycompany.myapp:Customer:placeOrder:*    # view and invoke placeOrder action
+com.mycompany.myapp:Customer:placeOrder      # ditto
+com.mycompany.myapp:Customer:*:r             # view all customer class members
+com.mycompany.myapp:*:*:r                    # view-only access for all classes in myapp package
+com.mycompany.myapp:*:*:*                    # view/edit for all classes in myapp package
+com.mycompany.myapp:*:*                      # ditto
+com.mycompany.myapp:*                        # ditto
+com.mycompany.myapp                          # ditto
+*                                            # view/edit access to everything
+----
+
+[TIP]
+====
+The format of the permissions string is configurable in Shiro, and Apache Isis uses this to provide an extended wildcard format, described xref:security:shiro:about.adoc#enhanced-wildcard-permission[here].
+====
+
+=== Externalized IniRealm
+
+There's no requirement for all users/roles to be defined in the `shiro.ini` file.
+Instead, a realm can be defined that loads its users/roles from some other resource.
+
+For example:
+
+[source,ini]
+----
+$realm1=org.apache.shiro.realm.text.IniRealm # <1>
+realm1.resourcePath=classpath:webapp/realm1.ini # <2>
+----
+<1> happens to (coincidentally) be the link:http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/realm/text/IniRealm.html[same implementation] as Shiro's built-in $iniRealm
+<2> in this case load the users/roles from the `src/main/resources/webapp/realm1.ini` file.
+
+Note that a URL could be provided as the `resourcePath`, so a centralized config file could be used.
+Even so, the
+
+[NOTE]
+====
+If configured this way then the `[users]` and `[roles]` sections of `shiro.ini` become unused.
+Instead, the corresponding sections from for `realm1.ini` are used instead.
+====
+
+
+//== Shiro JDBC Realm
+//
+//There is nothing to stop you from using some other `Realm` implementation (or indeed writing one yourself).
+//For example, you could use Shiro's own JDBC realm that loads user/password details from a database.
+//
+//[WARNING]
+//====
+//If you are happy to use a database then we strongly recommend you use the xref:security:ROOT:about.adoc[SecMan extension] instead of a vanilla JDBC; it is far more sophisticated and moreover gives you the ability to administer the system from within your Apache Isis application.
+//====
+//
+//If you go down this route, then the architecture is as follows:
+//
+//image::configuration/configuring-shiro/jdbc/configure-shiro-to-use-custom-jdbc-realm.png[width="600px"]
+//
+//
+//
+//
+//There's quite a lot of configuration required (in `shiro.ini`) to set up a JDBC realm, so we'll break it out into sections.
+//
+//First, we need to set up the connection to JDBC:
+//
+//[source,ini]
+//----
+//jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm        # <.>
+//
+//jof = org.apache.shiro.jndi.JndiObjectFactory          # <.>
+//jof.resourceName = jdbc/postgres                       # <.>
+//jof.requiredType = javax.sql.DataSource
+//jof.resourceRef = true
+//
+//jdbcRealm.dataSource = $jof                            # <4>
+//----
+//<1> instantiate the JDBC realm
+//<2> instantiate factory object to lookup DataSource from servlet container
+//<3> name of the datasource (as configured in `web.xml`)
+//<4> instruct JDBC realm to obtain datasource from the JNDI
+//
+//
+//We next need to tell the realm how to query the database.Shiro supports any schema; what matters is the input search argument and the output results.
+//
+//[source,ini]
+//----
+//
+//jdbcRealm.authenticationQuery =         \              # <1>
+//        select password                 \
+//          from users                    \
+//         where username = ?
+//
+//jdbcRealm.userRolesQuery =              \              # <2>
+//        select r.label                  \
+//          from users_roles ur           \
+//    inner join roles r                  \
+//            on ur.role_id = r.id        \
+//         where user_id = (              \
+//            select id                   \
+//             from users                 \
+//            where username = ?);        \
+//
+//jdbcRealm.permissionsQuery=             \               # <3>
+//        select p.permission             \
+//          from roles_permissions rp     \
+//    inner join permissions p            \
+//            on rp.permission_id = p.id  \
+//         where rp.role_id = (           \
+//            select id                   \
+//             from roles                 \
+//            where label = ?);
+//
+//jdbcRealm.permissionsLookupEnabled=true                 # <4>
+//----
+//<1> query to find password for user
+//<2> query to find roles for user
+//<3> query to find permissions for role
+//<4> enable permissions lookup
+//
+//[WARNING]
+//====
+//The `permissionsLookupEnabled` is very important, otherwise Shiro just returns an empty list of permissions and your users will have no access to any features(!).
+//====
+//
+//We also should ensure that the passwords are not stored as plain-text:
+//
+//[source,ini]
+//----
+//dps = org.apache.shiro.authc.credential.DefaultPasswordService   # <1>
+//pm = org.apache.shiro.authc.credential.PasswordMatcher           # <2>
+//pm.passwordService = $dps
+//jdbcRealm.credentialsMatcher = $pm                               # <3>
+//----
+//<1> mechanism to encrypts password
+//<2> service to match passwords
+//<3> instruct JDBC realm to use password matching service when authenticating
+//
+//
+//And finally we need to tell Shiro to use the realm, in the usual fashion:
+//
+//[source,ini]
+//----
+//securityManager.realms = $jdbcRealm
+//----
+//
+//Using the above configuration you will also need to setup a `DataSource`.The details vary by servlet container, for example this is link:https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html[how to do the setup on Tomcat 8.0].
+//
+//[WARNING]
+//====
+//The name of the `DataSource` can also vary by servlet container; see for example link:http://stackoverflow.com/questions/17441019/how-to-configure-jdbcrealm-to-obtain-its-datasource-from-jndi/23784702#23784702[this StackOverflow answer].
+//====
+
+
+[#enhanced-wildcard-permission]
+== Enhanced Wildcard Permission
+
+If using the text-based xref:security:shiro:about.adoc#shiro-ini-realm[IniRealm] or xref:security:shiro-realm-ldap:about.adoc[Apache Isis' LDAP realm], then note that Shiro also allows the string representation of the permissions to be mapped (resolved) to alternative `Permission` instances.
+Apache Isis provides its own `IsisPermission` which introduces the concept of a "veto".
+
+A vetoing permission is one that prevents access to a feature, rather than grants it.
+This is useful in some situations where most users have access to most features, and only a small number of features are particularly sensitive.
+The configuration can therefore be set up to grant fairly broad-brush permissions and then veto permission for the sensitive features for those users that do not have access.
+
+The string representation of the `IsisPermission` uses the following format:
+
+[source,ini]
+----
+(?<vetoFlag>[!]?)(?:(?<permissionGroup>[^\/]+)[\/])?(?<permission>.+)
+----
+
+where:
+
+* the optional `!` prefix indicates this permission is a vetoing permission
+* the optional `xxx/` prefix is a permission group that scopes any vetoing permissions
+* the remainder of the string is the permission (possibly wild-carded, with :rw as optional suffix)
+
+TIP: Use an online regex tester, eg link:https://regex101.com/[] to get an idea of how this works.
+
+For example:
+
+[source,ini]
+----
+user_role   = !reg/org.estatio.api,\
+              !reg/org.estatio.webapp.services.admin,\
+              reg/* ; \
+api_role    = org.estatio.api ;\
+admin_role = adm/*
+----
+
+sets up:
+
+* the `user_role` with access to all permissions except those in `org.estatio.api` and `org.estatio.webapp.services.admin`
+* the `api_role` with access to all permissions in `org.estatio.api`
+* the `admin_role` with access to everything.
+
+The permission group concept is required to scope the applicability of any veto permission.
+This is probably best explained by an example.
+Suppose that a user has both `admin_role` and `user_role`; we would want the `admin_role` to trump the vetos of the `user_role`, in other words to give the user access to everything.
+
+Because of the permission groups, the two "+++!reg/...+""" vetos in user_role only veto out selected permissions granted by the "+++reg/*+++" permissions, but they do not veto the permissions granted by a different scope, namely "+++adm/*+++".
+
+The net effect is therefore what we would want: that a user with both `admin_role` and `user_role` would have access to everything, irrespective of those two veto permissions of the `user_role`.
+
+Finally, the Apache Isis permission resolver is specified in `shiro.ini` file:
+
+[source,ini]
+----
+permissionResolver = org.apache.isis.security.shiro.authorization.IsisPermissionResolver
+myRealm.permissionResolver = $permissionResolver  # <1>
+----
+<1> `myRealm` is the handle to the configured realm, eg `$iniRealm` or `$isisLdapRealm` etc.
+
+== Run-as
+
+This hint shows how to temporarily change the current user as reported by Shiro.
+This can be useful to support "Run As", for example.
+
+The heavy lifting is done in `ShiroService`:
+
+[source,java]
+----
+import org.springframework.stereotype.Service;
+
+@Service
+public class ShiroService {
+
+    public void runAs(String userName) {
+        SimplePrincipalCollection principals =
+            new SimplePrincipalCollection(userName, "jdbcRealm");                       // <1>
+        getSubject().runAs(principals);
+    }
+
+    public String releaseRunAs() {
+        final PrincipalCollection principals = getSubject().releaseRunAs();
+        String username = (String)principals.asList().get(0);
+        return username;
+    }
+
+    public String getUsername() {                                                       // <2>
+        String principalAsString = ((String)getSubject().getPrincipal());
+        return principalAsString.toLowerCase();
+    }
+
+    public String getRealUsername() {                                                   // <3>
+        return userService.getUser().getName().toLowerCase();
+    }
+
+    public boolean isRunAs() {
+        return getSubject().isRunAs();
+    }
+
+    private static Subject getSubject() {
+        return org.apache.shiro.SecurityUtils.getSubject();
+    }
+
+    @Inject
+    private UserService userService;
+}
+----
+<1> "jdbcRealm" is realm as configured in Shiro config (shiro.ini).
+<2> The username of the currently logged in user (by which permissions are determined).
+This could be the user name the real user is running as.
+<3> The username of the real currently logged in user.
+
+This could be exposed in the UI using a simple `RunAsService`, for example:
+
+[source,java]
+----
+@DomainService(nature = NatureOfService.VIEW)
+@DomainServiceLayout(menuBar = DomainServiceLayout.MenuBar.TERTIARY)
+public class RunAsService {
+
+    public Dashboard runAs(User user) {
+        shiroService.runAs(user.getUsername());
+        return dashboardService.openDashboard();                    // <1>
+    }
+    public List<User> choices0RunAs() {
+        return ...                                                  // <2>
+    }
+    public boolean hideRunAs() {
+        return shiroService.isRunAs();
+    }
+
+
+
+    public User releaseRunAs() {
+        String username = shiroService.releaseRunAs();
+        return usersRepository.findByUsername(username);
+    }
+    public boolean hideReleaseRunAs() {
+        return !shiroService.isRunAs();
+    }
+
+
+    @Inject
+    private ShiroService shiroService;
+    @Inject
+    private UsersRepository usersRepository;
+    @Inject
+    private DashboardService dashboardService;                      // <1>
+}
+----
+<1> go to the home page (application-specific)
+<2> return a list of users to run as
+
+
+Credits: adapted from link:https://gist.github.com/erikdehair/efa3005440ca982cca41ebe5347e82d8[this gist].
+
+== Caching
+
+To ensure that security operations does not impede performance, Shiro supports caching.
+For example, this sets up a simple memory-based cache manager:
+
+[source,ini]
+----
+memoryCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
+securityManager.cacheManager = $memoryCacheManager
+----
+
+Other implementations can be plugged in; see the Shiro link:http://shiro.apache.org/caching.html[documentation] for further details.
+
+== Further Reading
+
+Shiro provides many other features.
+Check out:
+
+* Shiro's documentation page can be found link:http://shiro.apache.org/documentation.html[here].
+
+* community-contributed articles can be found link:http://shiro.apache.org/articles.html[here]. +
++
+These include for instance link:http://meri-stuff.blogspot.co.uk/2011/04/apache-shiro-part-2-realms-database-and.html[this interesting article] describing how to perform certificate-based authentication (ie login using Google or Facebook credentials).
+
+
+
+
+
+
 
-include::about/configuring-isis-to-use-shiro.adoc[leveloffset=+1]
-include::about/ini-realm.adoc[leveloffset=+1]
-include::about/jdbc-realm.adoc[leveloffset=+1]
-include::about/ldap-realm.adoc[leveloffset=+1]
-include::about/enhanced-wildcard-permission.adoc[leveloffset=+1]
-include::about/run-as.adoc[leveloffset=+1]
-include::about/shiro-caching.adoc[leveloffset=+1]
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/configuring-isis-to-use-shiro.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/configuring-isis-to-use-shiro.adoc
deleted file mode 100644
index e3290ff..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/configuring-isis-to-use-shiro.adoc
+++ /dev/null
@@ -1,113 +0,0 @@
-[[configuring-isis-to-use-shiro]]
-= Configuring to use Shiro
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-Apache Isis' security mechanism is configurable, specifying an `Authenticator` and an `Authorizor` (non-public) APIs.
-The Shiro security mechanism is an integration wih Apache Shiro that implements both interfaces.
-
-[TIP]
-====
-Both the xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are pre-configured to use Apache Shiro, so much of what follows may well have been set up already.
-====
-
-
-== Telling Apache Isis to use Shiro
-
-
-To tell Apache Isis to use Shiro, include `IsisModuleSecurityShiro` module in the top-level "app manifest".
-
-For example, the xref:docs:starters:simpleapp.adoc[SimpleApp] starter app bootstraps using:
-
-[source,java]
-----
-@Configuration
-@Import({
-        // ...
-        IsisModuleSecurityShiro.class,  // <.>
-        // ...
-})
-// ...
-public class AppManifest {
-}
-----
-<.> configures Shiro.
-
-This installs the appropriate implementation (the `ShiroAuthenticatorOrAuthorizor` class) that use Shiro's APIs to perform authentication and authorization:
-
-image::configuration/configure-isis-to-use-shiro.png[width="600px"]
-
-The figure above doesn't tell the whole story; we haven't yet seen how Shiro itself is configured to use realms.
-The `ShiroAuthenticatorOrAuthorizor` is in essence the glue between the Apache Isis runtime and Shiro.
-
-
-== Configuring Shiro Authenticator
-
-The `ShiroAuthenticatorOrAuthorizor` class itself supports a single optional property.
-This can be configured in `authentication_shiro.properties` file:
-
-[source,ini]
-----
-isis.security.shiro.autoLogoutIfAlreadyAuthenticated=false
-----
-
-This configuration property only comes into effect for the xref:vro:ROOT:about.adoc[REST API (Restful Objects viewer)]; if set then the Shiro subject - if found to be still authenticated - will be logged out anyway and then re-authenticated.
-
-[WARNING]
-====
-There should generally be no need to change this property from its default (`false`).
-Setting it to `true` may cause a race condition resulting in exceptions being logged.
-====
-
-
-
-== Bootstrapping Shiro
-
-//TODO: v2: this configuration is no longer required in `web.xml`, instead is configured programmatically by the framework (`WebModule_Shiro`).
-
-
-The Shiro environment (in essence, thread-locals holding the security credentials) needs to be bootstrapped using the following settings in the `WEB-INF/web.xml` file:
-
-[source,xml]
-----
-<listener>
-    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
-</listener>
-<filter>
-    <filter-name>ShiroFilter</filter-name>
-    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
-</filter>
-<filter-mapping>
-    <filter-name>ShiroFilter</filter-name>
-    <url-pattern>/*</url-pattern>
-</filter-mapping>
-----
-
-Based on this Shiro will then read `shiro.ini` file to configure its Realm definitions for authentication and authorization.
-
-
-
-== `shiro.ini`
-
-The `shiro.ini` file is used to specify the realm(s) that Shiro will delegate to:
-
-[source,ini]
-----
-securityManager.realms = $realmName
-----
-
-Shiro's ini file supports a "poor-man's" dependency injection (link:https://shiro.apache.org/configuration.html[their words]), and so `$realmName` in the above example is a reference to a realm defined elsewhere in `shiro.ini`.
-The subsequent sections describe the specifics for thevarious realm implementations available to you.
-
-
-It's also possible to configure Shiro to support multiple realms.
-
-[source,ini]
-----
-securityManager.realms = $realm1,$realm2
-----
-
-You can learn more about Shiro realms in the link:http://shiro.apache.org/realm.html[Shiro documentation].
-
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/enhanced-wildcard-permission.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/enhanced-wildcard-permission.adoc
deleted file mode 100644
index e0e5a91..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/enhanced-wildcard-permission.adoc
+++ /dev/null
@@ -1,65 +0,0 @@
-= Enhanced Wildcard Permission
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-If using the text-based xref:security:shiro:about/ini-realm.adoc[IniRealm] or xref:security:shiro-realm-ldap:about.adoc[Apache Isis' LDAP realm], then note that Shiro also allows the string representation of the permissions to be mapped (resolved) to alternative `Permission` instances.
-Apache Isis provides its own `IsisPermission` which introduces the concept of a "veto".
-
-A vetoing permission is one that prevents access to a feature, rather than grants it.
-This is useful in some situations where most users have access to most features, and only a small number of features are particularly sensitive.
-The configuration can therefore be set up to grant fairly broad-brush permissions and then veto permission for the sensitive features for those users that do not have access.
-
-The string representation of the `IsisPermission` uses the following format:
-
-[source,ini]
-----
-([!]?)([^/]+)[/](.+)
-----
-
-where:
-
-* the optional `!` prefix indicates this permission is a vetoing permission
-* the optional `xxx/` prefix is a permission group that scopes any vetoing permissions
-* the remainder of the string is the permission (possibly wild-carded, with :rw as optional suffix)
-
-
-For example:
-
-[source,ini]
-----
-user_role   = !reg/org.estatio.api,\
-              !reg/org.estatio.webapp.services.admin,\
-              reg/* ; \
-api_role    = org.estatio.api ;\
-admin_role = adm/*
-----
-
-sets up:
-
-* the `user_role` with access to all permissions except those in `org.estatio.api` and `org.estatio.webapp.services.admin`
-* the `api_role` with access to all permissions in `org.estatio.api`
-* the `admin_role` with access to everything.
-
-The permission group concept is required to scope the applicability of any veto permission.
-This is probably best explained by an example.
-Suppose that a user has both `admin_role` and `user_role`; we would want the `admin_role` to trump the vetos of the `user_role`, in other words to give the user access to everything.
-
-
-Because of the permission groups, the two "+++!reg/...+""" vetos in user_role only veto out selected permissions granted by the "+++reg/*+++" permissions, but they do not veto the permissions granted by a different scope, namely "+++adm/*+++".
-
-The net effect is therefore what we would want: that a user with both `admin_role` and `user_role` would have access to everything, irrespective of those two veto permissions of the `user_role`.
-
-
-
-Finally, the Apache Isis permission resolver is specified in `shiro.ini` file:
-
-[source,ini]
-----
-permissionResolver = org.apache.isis.security.shiro.authorization.IsisPermissionResolver
-myRealm.permissionResolver = $permissionResolver  # <1>
-----
-<1> `myRealm` is the handle to the configured realm, eg `$iniRealm` or `$isisLdapRealm` etc.
-
-
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/ini-realm.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/ini-realm.adoc
deleted file mode 100644
index f311cf2..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/ini-realm.adoc
+++ /dev/null
@@ -1,141 +0,0 @@
-= Shiro Ini Realm
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-The Shiro concept of a `Realm` allows different implementations of both the authentication and authorisation mechanism to be plugged in.
-
-Probably the simplest realm to use is Shiro's built-in `IniRealm`, which reads from the (same) `shiro.ini` file.
-
-This is suitable for prototyping, but isn't intended for production use, if only because user/password credentials are stored in plain text.
-Nevertheless, it's a good starting point.
-The app generated by both the xref:docs:starters:helloworld.adoc[HelloWorld] and xref:docs:starters:simpleapp.adoc[SimpleApp] starter apps are configured to use this realm.
-
-The diagram below shows the Isis and components involved:
-
-image::configuration/configuring-shiro/ini/configure-shiro-to-use-ini-realm.PNG[width="600px"]
-
-The realm is responsible for validating the user credentials, and then creates a Shiro link:http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/subject/Subject.html[Subject] which represents the user (for the current request).
-Apache Isis `Authenticator` component then interacts with the `Subject` in order to check permissions.
-
-
-
-
-== Shiro Configuration
-
-To use the built-in `IniRealm`, we add the following to `shiro.ini`:
-
-[source,ini]
-----
-securityManager.realms = $iniRealm
-----
-
-(Unlike other realms) there is no need to "define" `$iniRealm`; it is automatically available to us.
-
-Specifying `$iniRealm` means that the usernames/passwords, roles and permissions are read from the `shiro.ini` file itself.
-Specifically:
-
-* the users/passwords and their roles from the `[users]` sections;
-* the roles are mapped to permissions in the `[roles]` section.
-
-The format of these is described below.
-
-=== `[users]` section
-
-This section lists users, passwords and their roles.
-
-For example:
-
-[source,ini]
-----
-sven = pass, admin_role
-dick = pass, user_role, analysis_role, self-install_role
-bob  = pass, user_role, self-install_role
-----
-The first value is the password (eg "pass", the remaining values are the role(s).
-
-
-=== `[roles]` section
-
-This section lists roles and their corresponding permissions.
-
-For example:
-
-[source,ini]
-----
-user_role = *:ToDoItems:*:*,\
-            *:ToDoItem:*:*,\
-            *:TodoAppDashboard:*:*
-analysis_role = *:ToDoItemAnalysis:*:*,\
-            *:ToDoItemsByCategoryViewModel:*:*,\
-            *:ToDoItemsByDateRangeViewModel:*:*
-self-install_role = *:ToDoItemsFixturesService:install:*
-admin_role = *
-----
-
-The value is a comma-separated list of permissions for the role.  The format is:
-
-[source,ini]
-----
-packageName:className:memberName:r,w
-----
-
-where:
-
-* `memberName` is the property, collection or action name.
-* `r` indicates that the member is visible
-* `w` indicates that the member is usable (editable or invokable)
-
-and where each of the parts of the permission string can be wildcarded using `*`.
-
-Because these are wildcards, a '*' can be used at any level. Additionally, missing levels assume wildcards.
-
-Thus:
-
-[source,ini]
-----
-com.mycompany.myapp:Customer:firstName:r,w   # view or edit customer's firstName
-com.mycompany.myapp:Customer:lastName:r      # view customer's lastName only
-com.mycompany.myapp:Customer:placeOrder:*    # view and invoke placeOrder action
-com.mycompany.myapp:Customer:placeOrder      # ditto
-com.mycompany.myapp:Customer:*:r             # view all customer class members
-com.mycompany.myapp:*:*:r                    # view-only access for all classes in myapp package
-com.mycompany.myapp:*:*:*                    # view/edit for all classes in myapp package
-com.mycompany.myapp:*:*                      # ditto
-com.mycompany.myapp:*                        # ditto
-com.mycompany.myapp                          # ditto
-*                                            # view/edit access to everything
-----
-
-[TIP]
-====
-The format of the permissions string is configurable in Shiro, and Apache Isis uses this to provide an extended wildcard format, described xref:security:shiro:about/enhanced-wildcard-permission.adoc[here].
-====
-
-
-
-
-== Externalized IniRealm
-
-There's no requirement for all users/roles to be defined in the `shiro.ini` file.
-Instead, a realm can be defined that loads its users/roles from some other resource.
-
-For example:
-
-[source,ini]
-----
-$realm1=org.apache.shiro.realm.text.IniRealm # <1>
-realm1.resourcePath=classpath:webapp/realm1.ini # <2>
-----
-<1> happens to (coincidentally) be the link:http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/realm/text/IniRealm.html[same implementation] as Shiro's built-in $iniRealm
-<2> in this case load the users/roles from the `src/main/resources/webapp/realm1.ini` file.
-
-Note that a URL could be provided as the `resourcePath`, so a centralized config file could be used.
-Even so, the
-
-[NOTE]
-====
-If configured this way then the `[users]` and `[roles]` sections of `shiro.ini` become unused.
-Instead, the corresponding sections from for `realm1.ini` are used instead.
-====
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/jdbc-realm.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/jdbc-realm.adoc
deleted file mode 100644
index 5a55d7e..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/jdbc-realm.adoc
+++ /dev/null
@@ -1,111 +0,0 @@
-= Shiro JDBC Realm
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-There is nothing to stop you from using some other `Realm` implementation (or indeed writing one yourself).  For example, you could use Shiro's own JDBC realm that loads user/password details from a database.
-
-[WARNING]
-====
-If you are happy to use a database then we strongly recommend you use the xref:security:ROOT:about.adoc[SecMan extension] instead of a vanilla JDBC; it is far more sophisticated and moreover gives you the ability to administer the system from within your Apache Isis application.
-====
-
-If you go down this route, then the architecture is as follows:
-
-image::configuration/configuring-shiro/jdbc/configure-shiro-to-use-custom-jdbc-realm.png[width="600px"]
-
-
-
-
-There's quite a lot of configuration required (in `shiro.ini`) to set up a JDBC realm, so we'll break it out into sections.
-
-First, we need to set up the connection to JDBC:
-
-[source,ini]
-----
-jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm        # <.>
-
-jof = org.apache.shiro.jndi.JndiObjectFactory          # <.>
-jof.resourceName = jdbc/postgres                       # <.>
-jof.requiredType = javax.sql.DataSource
-jof.resourceRef = true
-
-jdbcRealm.dataSource = $jof                            # <4>
-----
-<1> instantiate the JDBC realm
-<2> instantiate factory object to lookup DataSource from servlet container
-<3> name of the datasource (as configured in `web.xml`)
-<4> instruct JDBC realm to obtain datasource from the JNDI
-
-
-We next need to tell the realm how to query the database.  Shiro supports any schema; what matters is the input search argument and the output results.
-
-[source,ini]
-----
-
-jdbcRealm.authenticationQuery =         \              # <1>
-        select password                 \
-          from users                    \
-         where username = ?
-
-jdbcRealm.userRolesQuery =              \              # <2>
-        select r.label                  \
-          from users_roles ur           \
-    inner join roles r                  \
-            on ur.role_id = r.id        \
-         where user_id = (              \
-            select id                   \
-             from users                 \
-            where username = ?);        \
-
-jdbcRealm.permissionsQuery=             \               # <3>
-        select p.permission             \
-          from roles_permissions rp     \
-    inner join permissions p            \
-            on rp.permission_id = p.id  \
-         where rp.role_id = (           \
-            select id                   \
-             from roles                 \
-            where label = ?);
-
-jdbcRealm.permissionsLookupEnabled=true                 # <4>
-----
-<1> query to find password for user
-<2> query to find roles for user
-<3> query to find permissions for role
-<4> enable permissions lookup
-
-[WARNING]
-====
-The `permissionsLookupEnabled` is very important, otherwise Shiro just returns an empty list of permissions and your users will have no access to any features(!).
-====
-
-We also should ensure that the passwords are not stored as plain-text:
-
-[source,ini]
-----
-dps = org.apache.shiro.authc.credential.DefaultPasswordService   # <1>
-pm = org.apache.shiro.authc.credential.PasswordMatcher           # <2>
-pm.passwordService = $dps
-jdbcRealm.credentialsMatcher = $pm                               # <3>
-----
-<1> mechanism to encrypts password
-<2> service to match passwords
-<3> instruct JDBC realm to use password matching service when authenticating
-
-
-And finally we need to tell Shiro to use the realm, in the usual fashion:
-
-[source,ini]
-----
-securityManager.realms = $jdbcRealm
-----
-
-Using the above configuration you will also need to setup a `DataSource`.  The details vary by servlet container, for example this is link:https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html[how to do the setup on Tomcat 8.0].
-
-[WARNING]
-====
-The name of the `DataSource` can also vary by servlet container; see for example link:http://stackoverflow.com/questions/17441019/how-to-configure-jdbcrealm-to-obtain-its-datasource-from-jndi/23784702#23784702[this StackOverflow answer].
-====
-
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/run-as.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/run-as.adoc
deleted file mode 100644
index 3e3b014..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/run-as.adoc
+++ /dev/null
@@ -1,101 +0,0 @@
-= Run-as
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-This hint shows how to temporarily change the current user as reported by Shiro.
-This can be useful to support "Run As", for example.
-
-The heavy lifting is done in `ShiroService`:
-
-[source,java]
-----
-import org.springframework.stereotype.Service;
-
-@Service
-public class ShiroService {
-
-    public void runAs(String userName) {
-        SimplePrincipalCollection principals =
-            new SimplePrincipalCollection(userName, "jdbcRealm");                       // <1>
-        getSubject().runAs(principals);
-    }
-
-    public String releaseRunAs() {
-        final PrincipalCollection principals = getSubject().releaseRunAs();
-        String username = (String)principals.asList().get(0);
-        return username;
-    }
-
-    public String getUsername() {                                                       // <2>
-        String principalAsString = ((String)getSubject().getPrincipal());
-        return principalAsString.toLowerCase();
-    }
-
-    public String getRealUsername() {                                                   // <3>
-        return userService.getUser().getName().toLowerCase();
-    }
-
-    public boolean isRunAs() {
-        return getSubject().isRunAs();
-    }
-
-    private static Subject getSubject() {
-        return org.apache.shiro.SecurityUtils.getSubject();
-    }
-
-    @Inject
-    private UserService userService;
-}
-----
-<1> "jdbcRealm" is realm as configured in Shiro config (shiro.ini).
-<2> The username of the currently logged in user (by which permissions are determined).
-This could be the user name the real user is running as.
-<3> The username of the real currently logged in user.
-
-
-This could be exposed in the UI using a simple `RunAsService`, for example:
-
-
-[source,java]
-----
-@DomainService(nature = NatureOfService.VIEW)
-@DomainServiceLayout(menuBar = DomainServiceLayout.MenuBar.TERTIARY)
-public class RunAsService {
-
-    public Dashboard runAs(User user) {
-        shiroService.runAs(user.getUsername());
-        return dashboardService.openDashboard();                    // <1>
-    }
-    public List<User> choices0RunAs() {
-        return ...                                                  // <2>
-    }
-    public boolean hideRunAs() {
-        return shiroService.isRunAs();
-    }
-
-
-
-    public User releaseRunAs() {
-        String username = shiroService.releaseRunAs();
-        return usersRepository.findByUsername(username);
-    }
-    public boolean hideReleaseRunAs() {
-        return !shiroService.isRunAs();
-    }
-
-
-    @Inject
-    private ShiroService shiroService;
-    @Inject
-    private UsersRepository usersRepository;
-    @Inject
-    private DashboardService dashboardService;                      // <1>
-}
-----
-<1> go to the home page (application-specific)
-<2> return a list of users to run as
-
-
-Credits: adapted from link:https://gist.github.com/erikdehair/efa3005440ca982cca41ebe5347e82d8[this gist].
diff --git a/security/shiro/src/main/adoc/modules/shiro/pages/about/shiro-caching.adoc b/security/shiro/src/main/adoc/modules/shiro/pages/about/shiro-caching.adoc
deleted file mode 100644
index 94000bc..0000000
--- a/security/shiro/src/main/adoc/modules/shiro/pages/about/shiro-caching.adoc
+++ /dev/null
@@ -1,40 +0,0 @@
-= Caching and other Shiro Features
-
-:Notice: 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 ag [...]
-:page-partial:
-
-
-We don't want to repeat the entire link:http://shiro.apache.org/documentation.html[Shiro documentation set] here, but we should flag a number of other features that are worth checking out.
-
-
-
-
-== Caching
-
-To ensure that security operations does not impede performance, Shiro supports caching.  For example, this sets up a simple memory-based cache manager:
-
-[source,ini]
-----
-memoryCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
-securityManager.cacheManager = $memoryCacheManager
-----
-
-Other implementations can be plugged in; see the Shiro link:http://shiro.apache.org/caching.html[documentation] for further details.
-
-
-
-
-== Further Reading
-
-
-* Shiro's documentation page can be found link:http://shiro.apache.org/documentation.html[here].
-
-* community-contributed articles can be found link:http://shiro.apache.org/articles.html[here]. +
-+
-These include for instance link:http://meri-stuff.blogspot.co.uk/2011/04/apache-shiro-part-2-realms-database-and.html[this interesting article] describing how to perform certificate-based authentication (ie login using Google or Facebook credentials).
-
-
-
-
-
-
diff --git a/security/shiro/src/main/adoc/modules/shiro/partials/module-nav.adoc b/security/shiro/src/main/adoc/modules/shiro/partials/module-nav.adoc
index 40248c1..9e32f29 100644
--- a/security/shiro/src/main/adoc/modules/shiro/partials/module-nav.adoc
+++ b/security/shiro/src/main/adoc/modules/shiro/partials/module-nav.adoc
@@ -1,5 +1,4 @@
 
 
-
 * xref:security:shiro:about.adoc[Shiro Implementation]
 
diff --git a/security/spring/src/main/adoc/modules/spring/pages/about.adoc b/security/spring/src/main/adoc/modules/spring/pages/about.adoc
index b168dc9..625fc8a 100644
--- a/security/spring/src/main/adoc/modules/spring/pages/about.adoc
+++ b/security/spring/src/main/adoc/modules/spring/pages/about.adoc
@@ -8,3 +8,24 @@ WARNING: TODO: this content has not yet been reviewed/updated for v2.0
 This guide describes the configuration of the Spring implementation of Apache Isis' `Authenticator and `Authorizor` APIs.
 
 
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
+
+
+== Update AppManifest
+
+In your application's `AppManifest` (top-level Spring `@Configuration` used to bootstrap the app), import the
+
+[source,java]
+.AppManifest.java
+----
+@Configuration
+@Import({
+        ...
+        IsisModuleSecuritySpring.class,
+        ...
+})
+public class AppManifest {
+}
+----
+
+Make sure that no other `IsisModuleSecurityXxx` module is imported.
diff --git a/viewers/restfulobjects/adoc/modules/ROOT/pages/setup-and-configuration.adoc b/viewers/restfulobjects/adoc/modules/ROOT/pages/setup-and-configuration.adoc
index a65572e..db0e140 100644
--- a/viewers/restfulobjects/adoc/modules/ROOT/pages/setup-and-configuration.adoc
+++ b/viewers/restfulobjects/adoc/modules/ROOT/pages/setup-and-configuration.adoc
@@ -6,59 +6,7 @@
 This section describes how to include the Restful Objects viewer's module and set its configuration properties.
 
 
-== Maven pom.xml
-
-=== Dependency Management
-
-If your application inherits from the Apache Isis starter app (`org.apache.isis.app:isis-app-starter-parent` then that will define the version automatically:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<parent>
-    <groupId>org.apache.isis.app</groupId>
-    <artifactId>isis-app-starter-parent</artifactId>
-    <version>{page-isisrel}</version>
-    <relativePath/>
-</parent>
-----
-
-Alternatively, import the core BOM.
-This is usually done in the top-level parent pom of your application:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<dependencyManagement>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core</artifactId>
-            <version>{page-isisrel}</version>
-            <version>2.0.0-SNAPSHOT</version>
-            <scope>import</scope>
-            <type>pom</type>
-        </dependency>
-    </dependencies>
-</dependencyManagement>
-----
-
-
-=== Dependency
-
-In the webapp module of your application, add the following dependency:
-
-[source,xml]
-.pom.xml
-----
-<dependencies>
-    <dependency>
-        <groupId>org.apache.isis.mavendeps</groupId>
-        <artifactId>isis-mavendeps-webapp</artifactId>
-        <type>pom</type>
-    </dependency>
-</dependencies>
-----
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
 
 
 == Update AppManifest
diff --git a/viewers/wicket/adoc/modules/ROOT/pages/setup-and-configuration.adoc b/viewers/wicket/adoc/modules/ROOT/pages/setup-and-configuration.adoc
index aca56a6..213ea58 100644
--- a/viewers/wicket/adoc/modules/ROOT/pages/setup-and-configuration.adoc
+++ b/viewers/wicket/adoc/modules/ROOT/pages/setup-and-configuration.adoc
@@ -6,59 +6,7 @@
 This section describes how to include the Wicket viewer's module and set its configuration properties.
 
 
-== Maven pom.xml
-
-=== Dependency Management
-
-If your application inherits from the Apache Isis starter app (`org.apache.isis.app:isis-app-starter-parent` then that will define the version automatically:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<parent>
-    <groupId>org.apache.isis.app</groupId>
-    <artifactId>isis-app-starter-parent</artifactId>
-    <version>{page-isisrel}</version>
-    <relativePath/>
-</parent>
-----
-
-Alternatively, import the core BOM.
-This is usually done in the top-level parent pom of your application:
-
-[source,xml,subs="attributes+"]
-.pom.xml
-----
-<dependencyManagement>
-    <dependencies>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-core</artifactId>
-            <version>{page-isisrel}</version>
-            <version>2.0.0-SNAPSHOT</version>
-            <scope>import</scope>
-            <type>pom</type>
-        </dependency>
-    </dependencies>
-</dependencyManagement>
-----
-
-
-=== Dependency
-
-In the webapp module of your application, add the following dependency:
-
-[source,xml]
-.pom.xml
-----
-<dependencies>
-    <dependency>
-        <groupId>org.apache.isis.mavendeps</groupId>
-        <artifactId>isis-mavendeps-webapp</artifactId>
-        <type>pom</type>
-    </dependency>
-</dependencies>
-----
+include::docs:mavendeps:partial$setup-and-configure-mavendeps-webapp.adoc[leveloffset=+1]
 
 
 == Update AppManifest