http://git-wip-us.apache.org/repos/asf/isis-site/blob/6ad91949/content/guides/ugsec/ugsec.html ---------------------------------------------------------------------- diff --git a/content/guides/ugsec/ugsec.html b/content/guides/ugsec/ugsec.html index 586504a..6ff1b70 100644 --- a/content/guides/ugsec/ugsec.html +++ b/content/guides/ugsec/ugsec.html @@ -439,7 +439,7 @@ <p>Isis provides an API for both authentication and authorization, and provides an implementation that integrates with <a href="http://shiro.apache.org">Apache Shiro</a>. Shiro in turn uses the concept of a <em>realm</em> as a source for both authentication and optionally authorization.</p> </div> <div class="paragraph"> - <p>Shiro ships with a simple text-based realmâââthe <code>IniRealm</code>âââwhich reads users (and password), user roles and role permissions from the <code>WEB-INF/shiro.ini</code> file. The <a href="ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is configured to use this realm.</p> + <p>Shiro ships with a simple text-based realmâââthe <code>IniRealm</code>âââwhich reads users (and password), user roles and role permissions from the <code>WEB-INF/shiro.ini</code> file. The <a href="../ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is configured to use this realm.</p> </div> <div class="paragraph"> <p>Shiro also ships with an implementation of an LDAP-based realm; LDAP is often used to manage user/passwords and corresponding user groups. Apache Isis in turn extends this with its <code>IsisLdapRealm</code>, which provides more flexibility for both group/role and role/permissions management.</p> @@ -463,10 +463,10 @@ <p>A further aspect of security is auditing: recording what data was modified by which user.</p> </div> <div class="paragraph"> - <p>Apache Isis provides the <a href="rgsvc.html#_rgsvc_api_InteractionContext"><code>InteractionContext</code></a> can be used to track the actions being invoked, and the <a href="rgsvc.html#_rgsvc_spi_AuditerService"><code>AuditerService</code></a> captures what data was modified as a result (auditing). When <code>Interaction</code>s are persisted (eg by way of (non-ASF) <a href="http://github.com/isisaddons/isis-module-publishmq">Isis addons' publishmq</a> module) this provides excellent traceability. The (non-ASF) <a href="http://github.com/isisaddons/isis-module-audit">Isis addons' audit</a> module provides an implementation of the <code>AuditerService</code>.</p> + <p>Apache Isis provides the <a href="../rgsvc/rgsvc.html#_rgsvc_api_InteractionContext"><code>InteractionContext</code></a> can be used to track the actions being invoked, and the <a href="../rgsvc/rgsvc.html#_rgsvc_spi_AuditerService"><code>AuditerService</code></a> captures what data was modified as a result (auditing). When <code>Interaction</code>s are persisted (eg by way of (non-ASF) <a href="http://github.com/isisaddons/isis-module-publishmq">Isis addons' publishmq</a> module) this provides excellent traceability. The (non-ASF) <a href="http://github.com/isisaddons/isis-module-audit">Isis addons' audit</a> module provides an implementation of the <code>AuditerService</code>.</p> </div> <div class="paragraph"> - <p>For earlier versions of the framework the <a href="rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a> can be used to capture actions, while the (deprecated) <a href="rgsvc.html#_rgsvc_spi_AuditingService"><code>AuditingService</code></a> used to capture data modified.</p> + <p>For earlier versions of the framework the <a href="../rgsvc/rgsvc.html#_rgsvc_spi_CommandService"><code>CommandService</code></a> can be used to capture actions, while the (deprecated) <a href="../rgsvc/rgsvc.html#_rgsvc_spi_AuditingService"><code>AuditingService</code></a> used to capture data modified.</p> </div> </td> </tr> </tbody> @@ -476,7 +476,7 @@ </div> </div> <div class="sect1"> - <h2 id="_ugsec_configuring-isis-to-use-shiro">2. Configuring Apache Isis to use Shiro</h2> + <h2 id="_ugsec_configuring-isis-to-use-shiro">2. Configuring to use Shiro</h2> <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_configuring-isis-to-use-shiro.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> <div class="paragraph"> @@ -489,7 +489,7 @@ <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> - <p>The <a href="ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is pre-configured to use Apache Shiro, so much of what follows is set up already.</p> + <p>The <a href="../ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is pre-configured to use Apache Shiro, so much of what follows is set up already.</p> </div> </td> </tr> </tbody> @@ -519,7 +519,7 @@ isis.authorization=shiro</code></pre> </div> </div> <div class="sect2"> - <h3 id="_configuring_isis_shiro_authenticator">2.2. Configuring Isis' Shiro Authenticator</h3> + <h3 id="_configuring_shiro_authenticator">2.2. Configuring Shiro Authenticator</h3> <div class="paragraph"> <p>The <code>ShiroAuthenticatorOrAuthorizor</code> class itself supports a single optional property. This can be configured in <code>authentication_shiro.properties</code> file:</p> </div> @@ -529,7 +529,7 @@ isis.authorization=shiro</code></pre> </div> </div> <div class="paragraph"> - <p>This configuration property only comes into effect for the <a href="ugvro.html">Restful Objects viewer</a>; if set then the Shiro subject - if found to be still authenticated - will be logged out anyway and then re-authenticated.</p> + <p>This configuration property only comes into effect for the <a href="../ugvro/ugvro.html">Restful Objects viewer</a>; if set then the Shiro subject - if found to be still authenticated - will be logged out anyway and then re-authenticated.</p> </div> <div class="admonitionblock warning"> <table> @@ -597,81 +597,84 @@ isis.authorization=shiro</code></pre> </div> </div> <div class="sect1"> - <h2 id="_ugsec_shiro-ini-realm">3. Shiro Ini Realm</h2> - <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-ini-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> + <h2 id="_ugsec_shiro-realm-implementations">3. Shiro Realm Implementations</h2> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-realm-implementations.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> - <div class="paragraph"> - <p>Probably the simplest realm to use is Shiroâs built-in <code>IniRealm</code>, which reads from the (same) <code>WEB-INF/shiro.ini</code> file.</p> - </div> - <div class="paragraph"> - <p>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 the <a href="ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is configured to use this realm.</p> - </div> - <div class="paragraph"> - <p>The diagram below shows the Isis and components involved:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-shiro-to-use-ini-realm.PNG" alt="configure shiro to use ini realm" width="600px"> - </div> - </div> - <div class="paragraph"> - <p>The realm is responsible for validating the user credentials, and then creates a Shiro <a href="http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/subject/Subject.html"><code>Subject</code></a> which represents the user (for the current request). Apache Isis <code>Authenticator</code> component then interacts with the <code>Subject</code> in order to check permissions.</p> - </div> <div class="sect2"> - <h3 id="_shiro_configuration">3.1. Shiro Configuration</h3> + <h3 id="_ugsec_shiro-realm-implementations_ini-realm">3.1. Shiro Ini Realm</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-realm-implementations_ini-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="paragraph"> - <p>To use the built-in <code>IniRealm</code>, we add the following to <code>WEB-INF/shiro.ini</code>:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">securityManager.realms = $iniRealm</code></pre> - </div> + <p>Probably the simplest realm to use is Shiroâs built-in <code>IniRealm</code>, which reads from the (same) <code>WEB-INF/shiro.ini</code> file.</p> </div> <div class="paragraph"> - <p>(Unlike other realms) there is no need to "define" <code>$iniRealm</code>; it is automatically available to us.</p> + <p>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 the <a href="../ugfun/ugfun.html#_ugfun_getting-started_simpleapp-archetype">SimpleApp archetype</a> is configured to use this realm.</p> </div> <div class="paragraph"> - <p>Specifying <code>$iniRealm</code> means that the usernames/passwords, roles and permissions are read from the <code>shiro.ini</code> file itself. Specifically:</p> + <p>The diagram below shows the Isis and components involved:</p> </div> - <div class="ulist"> - <ul> - <li> <p>the users/passwords and their roles from the <code>[users]</code> sections;</p> </li> - <li> <p>the roles are mapped to permissions in the <code>[roles]</code> section.</p> </li> - </ul> + <div class="imageblock"> + <div class="content"> + <img src="images/security/security-apis-impl/configure-shiro-to-use-ini-realm.PNG" alt="configure shiro to use ini realm" width="600px"> + </div> </div> <div class="paragraph"> - <p>The format of these is described below.</p> + <p>The realm is responsible for validating the user credentials, and then creates a Shiro <a href="http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/subject/Subject.html"><code>Subject</code></a> which represents the user (for the current request). Apache Isis <code>Authenticator</code> component then interacts with the <code>Subject</code> in order to check permissions.</p> </div> <div class="sect3"> - <h4 id="__code_users_code_section">3.1.1. <code>[users]</code> section</h4> + <h4 id="_shiro_configuration">3.1.1. Shiro Configuration</h4> <div class="paragraph"> - <p>This section lists users, passwords and their roles.</p> - </div> - <div class="paragraph"> - <p>For example:</p> + <p>To use the built-in <code>IniRealm</code>, we add the following to <code>WEB-INF/shiro.ini</code>:</p> </div> <div class="listingblock"> <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">sven = pass, admin_role -dick = pass, user_role, analysis_role, self-install_role -bob = pass, user_role, self-install_role</code></pre> + <pre class="CodeRay highlight"><code data-lang="ini">securityManager.realms = $iniRealm</code></pre> </div> </div> <div class="paragraph"> - <p>The first value is the password (eg "pass", the remaining values are the role(s).</p> + <p>(Unlike other realms) there is no need to "define" <code>$iniRealm</code>; it is automatically available to us.</p> </div> - </div> - <div class="sect3"> - <h4 id="__code_roles_code_section">3.1.2. <code>[roles]</code> section</h4> <div class="paragraph"> - <p>This section lists roles and their corresponding permissions.</p> + <p>Specifying <code>$iniRealm</code> means that the usernames/passwords, roles and permissions are read from the <code>shiro.ini</code> file itself. Specifically:</p> + </div> + <div class="ulist"> + <ul> + <li> <p>the users/passwords and their roles from the <code>[users]</code> sections;</p> </li> + <li> <p>the roles are mapped to permissions in the <code>[roles]</code> section.</p> </li> + </ul> </div> <div class="paragraph"> - <p>For example:</p> + <p>The format of these is described below.</p> </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">user_role = *:ToDoItems:*:*,\ + <div class="sect4"> + <h5 id="__code_users_code_section"><code>[users]</code> section</h5> + <div class="paragraph"> + <p>This section lists users, passwords and their roles.</p> + </div> + <div class="paragraph"> + <p>For example:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">sven = pass, admin_role +dick = pass, user_role, analysis_role, self-install_role +bob = pass, user_role, self-install_role</code></pre> + </div> + </div> + <div class="paragraph"> + <p>The first value is the password (eg "pass", the remaining values are the role(s).</p> + </div> + </div> + <div class="sect4"> + <h5 id="__code_roles_code_section"><code>[roles]</code> section</h5> + <div class="paragraph"> + <p>This section lists roles and their corresponding permissions.</p> + </div> + <div class="paragraph"> + <p>For example:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">user_role = *:ToDoItems:*:*,\ *:ToDoItem:*:*,\ *:ToDoAppDashboard:*:* analysis_role = *:ToDoItemAnalysis:*:*,\ @@ -679,38 +682,38 @@ analysis_role = *:ToDoItemAnalysis:*:*,\ *:ToDoItemsByDateRangeViewModel:*:* self-install_role = *:ToDoItemsFixturesService:install:* admin_role = *</code></pre> + </div> </div> - </div> - <div class="paragraph"> - <p>The value is a comma-separated list of permissions for the role. The format is:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">packageName:className:memberName:r,w</code></pre> + <div class="paragraph"> + <p>The value is a comma-separated list of permissions for the role. The format is:</p> </div> - </div> - <div class="paragraph"> - <p>where:</p> - </div> - <div class="ulist"> - <ul> - <li> <p><code>memberName</code> is the property, collection or action name.</p> </li> - <li> <p><code>r</code> indicates that the member is visible</p> </li> - <li> <p><code>w</code> indicates that the member is usable (editable or invokable)</p> </li> - </ul> - </div> - <div class="paragraph"> - <p>and where each of the parts of the permission string can be wildcarded using <code>*</code>.</p> - </div> - <div class="paragraph"> - <p>Because these are wildcards, a '*' can be used at any level. Additionally, missing levels assume wildcards.</p> - </div> - <div class="paragraph"> - <p>Thus:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">com.mycompany.myapp:Customer:firstName:r,w # view or edit customer's firstName + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">packageName:className:memberName:r,w</code></pre> + </div> + </div> + <div class="paragraph"> + <p>where:</p> + </div> + <div class="ulist"> + <ul> + <li> <p><code>memberName</code> is the property, collection or action name.</p> </li> + <li> <p><code>r</code> indicates that the member is visible</p> </li> + <li> <p><code>w</code> indicates that the member is usable (editable or invokable)</p> </li> + </ul> + </div> + <div class="paragraph"> + <p>and where each of the parts of the permission string can be wildcarded using <code>*</code>.</p> + </div> + <div class="paragraph"> + <p>Because these are wildcards, a '*' can be used at any level. Additionally, missing levels assume wildcards.</p> + </div> + <div class="paragraph"> + <p>Thus:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="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 @@ -721,16 +724,62 @@ com.mycompany.myapp:*:* # ditto com.mycompany.myapp:* # ditto com.mycompany.myapp # ditto * # view/edit access to everything</code></pre> + </div> + </div> + <div class="admonitionblock tip"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> + <td class="content"> + <div class="paragraph"> + <p>The format of the permissions string is configurable in Shiro, and Apache Isis uses this to provide an extended wildcard format, described <a href="../ugsec/ugsec.html#_ugsec_shiro-isis-enhanced-wildcard-permission">here</a>.</p> + </div> </td> + </tr> + </tbody> + </table> </div> </div> - <div class="admonitionblock tip"> + </div> + <div class="sect3"> + <h4 id="_externalized_inirealm">3.1.2. Externalized IniRealm</h4> + <div class="paragraph"> + <p>Thereâs no requirement for all users/roles to be defined in the <code>shiro.ini</code> file. Instead, a realm can be defined that loads its users/roles from some other resource.</p> + </div> + <div class="paragraph"> + <p>For example:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">$realm1=org.apache.shiro.realm.text.IniRealm <i class="conum" data-value="1"></i><b>(1)</b> +realm1.resourcePath=classpath:webapp/realm1.ini <i class="conum" data-value="2"></i><b>(2)</b></code></pre> + </div> + </div> + <div class="colist arabic"> <table> <tbody> <tr> - <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> + <td><i class="conum" data-value="1"></i><b>1</b></td> + <td>happens to (coincidentally) be the <a href="http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/realm/text/IniRealm.html">same implementation</a> as Shiroâs built-in $iniRealm</td> + </tr> + <tr> + <td><i class="conum" data-value="2"></i><b>2</b></td> + <td>in this case load the users/roles from the <code>src/main/resources/webapp/realm1.ini</code> file.</td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>Note that a URL could be provided as the <code>resourcePath</code>, so a centralized config file could be used. Even so, the</p> + </div> + <div class="admonitionblock note"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> <td class="content"> <div class="paragraph"> - <p>The format of the permissions string is configurable in Shiro, and Apache Isis uses this to provide an extended wildcard format, described <a href="#_ugsec_shiro-isis-enhanced-wildcard-permission">here</a>.</p> + <p>If configured this way then the <code>[users]</code> and <code>[roles]</code> sections of <code>shiro.ini</code> become unused. Instead, the corresponding sections from for <code>realm1.ini</code> are used instead.</p> </div> </td> </tr> </tbody> @@ -739,75 +788,27 @@ com.mycompany.myapp # ditto </div> </div> <div class="sect2"> - <h3 id="_externalized_inirealm">3.2. Externalized IniRealm</h3> + <h3 id="_ugsec_shiro-realm-implementations_isis-ldap-realm">3.2. Isis Ldap Realm</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-realm-implementations_isis-ldap-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="paragraph"> - <p>Thereâs no requirement for all users/roles to be defined in the <code>shiro.ini</code> file. Instead, a realm can be defined that loads its users/roles from some other resource.</p> + <p>Isis ships with an implementation of <a href="http://shiro.apache.org">Apache Shiro</a>'s <code>Realm</code> class that allows user authentication and authorization to be performed against an LDAP server.</p> </div> - <div class="paragraph"> - <p>For example:</p> - </div> - <div class="listingblock"> + <div class="imageblock"> <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">$realm1=org.apache.shiro.realm.text.IniRealm <i class="conum" data-value="1"></i><b>(1)</b> -realm1.resourcePath=classpath:webapp/realm1.ini <i class="conum" data-value="2"></i><b>(2)</b></code></pre> + <img src="images/security/security-apis-impl/configure-shiro-to-use-isis-ldap-realm.PNG" alt="configure shiro to use isis ldap realm" width="600px"> </div> </div> - <div class="colist arabic"> - <table> - <tbody> - <tr> - <td><i class="conum" data-value="1"></i><b>1</b></td> - <td>happens to (coincidentally) be the <a href="http://shiro.apache.org/static/latest/apidocs/org/apache/shiro/realm/text/IniRealm.html">same implementation</a> as Shiroâs built-in $iniRealm</td> - </tr> - <tr> - <td><i class="conum" data-value="2"></i><b>2</b></td> - <td>in this case load the users/roles from the <code>src/main/resources/webapp/realm1.ini</code> file.</td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>Note that a URL could be provided as the <code>resourcePath</code>, so a centralized config file could be used. Even so, the</p> - </div> - <div class="admonitionblock note"> - <table> - <tbody> - <tr> - <td class="icon"> <i class="fa icon-note" title="Note"></i> </td> - <td class="content"> - <div class="paragraph"> - <p>If configured this way then the <code>[users]</code> and <code>[roles]</code> sections of <code>shiro.ini</code> become unused. Instead, the corresponding sections from for <code>realm1.ini</code> are used instead.</p> - </div> </td> - </tr> - </tbody> - </table> - </div> - </div> - </div> - </div> - <div class="sect1"> - <h2 id="_ugsec_shiro-isis-ldap-realm">4. Isis Ldap Realm</h2> - <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-isis-ldap-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> - <div class="sectionbody"> - <div class="paragraph"> - <p>Isis ships with an implementation of <a href="http://shiro.apache.org">Apache Shiro</a>'s <code>Realm</code> class that allows user authentication and authorization to be performed against an LDAP server.</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-shiro-to-use-isis-ldap-realm.PNG" alt="configure shiro to use isis ldap realm" width="600px"> - </div> - </div> - <div class="paragraph"> - <p>The LDAP database stores the user/passwords and user groups, while the <code>shiro.ini</code> file is used to map the LDAP groups to roles, and to map the roles to permissions.</p> - </div> - <div class="sect2"> - <h3 id="_shiro_configuration_2">4.1. Shiro Configuration</h3> <div class="paragraph"> - <p>To use LDAP involves telling Shiro how to instantiate the realm. This bootstrapping info lives in the <code>WEB-INF/shiro.ini</code>:</p> + <p>The LDAP database stores the user/passwords and user groups, while the <code>shiro.ini</code> file is used to map the LDAP groups to roles, and to map the roles to permissions.</p> </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">contextFactory = org.apache.isis.security.shiro.IsisLdapContextFactory + <div class="sect3"> + <h4 id="_shiro_configuration_2">3.2.1. Shiro Configuration</h4> + <div class="paragraph"> + <p>To use LDAP involves telling Shiro how to instantiate the realm. This bootstrapping info lives in the <code>WEB-INF/shiro.ini</code>:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">contextFactory = org.apache.isis.security.shiro.IsisLdapContextFactory contextFactory.url = ldap://localhost:10389 contextFactory.systemUsername = uid=admin,ou=system <i class="conum" data-value="1"></i><b>(1)</b> contextFactory.systemPassword = secret @@ -837,245 +838,241 @@ ldapRealm.permissionsByRole=\ <i class="conum" data admin_role = * securityManager.realms = $ldapRealm</code></pre> + </div> </div> - </div> - <div class="colist arabic"> - <table> - <tbody> - <tr> - <td><i class="conum" data-value="1"></i><b>1</b></td> - <td>user accounts are searched using a dedicated service account</td> - </tr> - <tr> - <td><i class="conum" data-value="2"></i><b>2</b></td> - <td>SASL (CRAM-MD5) authentication is used for this authentication</td> - </tr> - <tr> - <td><i class="conum" data-value="3"></i><b>3</b></td> - <td>Apache Isis' implementation of the LDAP realm.</td> - </tr> - <tr> - <td><i class="conum" data-value="4"></i><b>4</b></td> - <td>groups are searched under <code>ou=groups,o=mojo</code> (where <code>mojo</code> is the company name)</td> - </tr> - <tr> - <td><i class="conum" data-value="5"></i><b>5</b></td> - <td>each group has an LDAP objectClass of <code>groupOfUniqueNames</code></td> - </tr> - <tr> - <td><i class="conum" data-value="6"></i><b>6</b></td> - <td>each group has a vector attribute of <code>uniqueMember</code></td> - </tr> - <tr> - <td><i class="conum" data-value="7"></i><b>7</b></td> - <td>groups looked up from LDAP can optionally be mapped to logical roles; otherwise groups are used as role names directly</td> - </tr> - <tr> - <td><i class="conum" data-value="8"></i><b>8</b></td> - <td>roles are mapped in turn to permissions</td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>The value of <code>uniqueMember</code> is in the form <code>uid=xxx</code>, with <code>xxx</code> being the uid of the user * users searched under <code>ou=system</code> * users have, at minimum, a <code>uid</code> attribute and a password * the users credentials are used to verify their user/password</p> - </div> - <div class="paragraph"> - <p>The above configuration has been tested against <a href="http://directory.apache.org/apacheds/">ApacheDS</a>, v1.5.7. This can be administered using <a href="http://directory.apache.org/studio/">Apache Directory Studio</a>, v1.5.3.</p> - </div> - <div class="admonitionblock tip"> - <table> - <tbody> - <tr> - <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> - <td class="content"> - <div class="title"> - Shiro Realm Mappings - </div> - <div class="paragraph"> - <p>When configuring role based permission mapping, there can only be one of these entries per realm:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">realm.groupToRolesMappings = ...</code></pre> + <div class="colist arabic"> + <table> + <tbody> + <tr> + <td><i class="conum" data-value="1"></i><b>1</b></td> + <td>user accounts are searched using a dedicated service account</td> + </tr> + <tr> + <td><i class="conum" data-value="2"></i><b>2</b></td> + <td>SASL (CRAM-MD5) authentication is used for this authentication</td> + </tr> + <tr> + <td><i class="conum" data-value="3"></i><b>3</b></td> + <td>Apache Isis' implementation of the LDAP realm.</td> + </tr> + <tr> + <td><i class="conum" data-value="4"></i><b>4</b></td> + <td>groups are searched under <code>ou=groups,o=mojo</code> (where <code>mojo</code> is the company name)</td> + </tr> + <tr> + <td><i class="conum" data-value="5"></i><b>5</b></td> + <td>each group has an LDAP objectClass of <code>groupOfUniqueNames</code></td> + </tr> + <tr> + <td><i class="conum" data-value="6"></i><b>6</b></td> + <td>each group has a vector attribute of <code>uniqueMember</code></td> + </tr> + <tr> + <td><i class="conum" data-value="7"></i><b>7</b></td> + <td>groups looked up from LDAP can optionally be mapped to logical roles; otherwise groups are used as role names directly</td> + </tr> + <tr> + <td><i class="conum" data-value="8"></i><b>8</b></td> + <td>roles are mapped in turn to permissions</td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>The value of <code>uniqueMember</code> is in the form <code>uid=xxx</code>, with <code>xxx</code> being the uid of the user * users searched under <code>ou=system</code> * users have, at minimum, a <code>uid</code> attribute and a password * the users credentials are used to verify their user/password</p> + </div> + <div class="paragraph"> + <p>The above configuration has been tested against <a href="http://directory.apache.org/apacheds/">ApacheDS</a>, v1.5.7. This can be administered using <a href="http://directory.apache.org/studio/">Apache Directory Studio</a>, v1.5.3.</p> + </div> + <div class="admonitionblock tip"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> + <td class="content"> + <div class="title"> + Shiro Realm Mappings </div> - </div> - <div class="paragraph"> - <p>and</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">realm.roleToPermissionsMappings = ...</code></pre> + <div class="paragraph"> + <p>When configuring role based permission mapping, there can only be one of these entries per realm:</p> </div> - </div> - <div class="paragraph"> - <p>This forces you to put everything on one line for each of the above. This is, unfortunately, a Shiro "feature". And if you repeat the entries above then itâs "last one wins".)</p> - </div> - <div class="paragraph"> - <p>To make the configuration maintainable, use "\" to separate the mappings onto separate lines in the file. Use this technique for both group to roles mapping and role to permission mapping. If you use the '' after the "," that separates the key:value pairs it is more readable.</p> - </div> </td> - </tr> - </tbody> - </table> - </div> - </div> - <div class="sect2"> - <h3 id="_externalizing_role_perms">4.2. Externalizing role perms</h3> - <div class="paragraph"> - <p>As an alternative to injecting the <code>permissionsByRole</code> property, the role/permission mapping can alternatively be specified by injecting a resource path:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">ldapRealm.resourcePath=classpath:webapp/myroles.ini</code></pre> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">realm.groupToRolesMappings = ...</code></pre> + </div> + </div> + <div class="paragraph"> + <p>and</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">realm.roleToPermissionsMappings = ...</code></pre> + </div> + </div> + <div class="paragraph"> + <p>This forces you to put everything on one line for each of the above. This is, unfortunately, a Shiro "feature". And if you repeat the entries above then itâs "last one wins".)</p> + </div> + <div class="paragraph"> + <p>To make the configuration maintainable, use "\" to separate the mappings onto separate lines in the file. Use this technique for both group to roles mapping and role to permission mapping. If you use the '' after the "," that separates the key:value pairs it is more readable.</p> + </div> </td> + </tr> + </tbody> + </table> </div> </div> - <div class="paragraph"> - <p>where <code>myroles.ini</code> is in <code>src/main/resources/webapp</code>, and takes the form:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">[roles] + <div class="sect3"> + <h4 id="_externalizing_role_perms">3.2.2. Externalizing role perms</h4> + <div class="paragraph"> + <p>As an alternative to injecting the <code>permissionsByRole</code> property, the role/permission mapping can alternatively be specified by injecting a resource path:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">ldapRealm.resourcePath=classpath:webapp/myroles.ini</code></pre> + </div> + </div> + <div class="paragraph"> + <p>where <code>myroles.ini</code> is in <code>src/main/resources/webapp</code>, and takes the form:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">[roles] user_role = *:ToDoItemsJdo:*:*,\ *:ToDoItem:*:* self-install_role = *:ToDoItemsFixturesService:install:* admin_role = *</code></pre> + </div> + </div> + <div class="paragraph"> + <p>This separation of the role/mapping can be useful if Shiro is configured to support multiple realms (eg an LdapRealm based one and also an TextRealm)</p> </div> </div> - <div class="paragraph"> - <p>This separation of the role/mapping can be useful if Shiro is configured to support multiple realms (eg an LdapRealm based one and also an TextRealm)</p> + <div class="sect3"> + <h4 id="_active_ds_ldap_tutorial">3.2.3. Active DS LDAP tutorial</h4> + <div class="paragraph"> + <p>The screenshots below show how to setup LDAP accounts in ApacheDS using the Apache Directory Studio.</p> + </div> + <div class="paragraph"> + <p>The setup here was initially based on <a href="http://krams915.blogspot.co.uk/2011/01/ldap-apache-directory-studio-basic.html">this tutorial</a>, however we have moved the user accounts so that they are defined in a separate LDAP node.</p> + </div> + <div class="paragraph"> + <p>To start, create a partition in order to hold the mojo node (holding the groups):</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-mojo-partition.png" alt="ActiveDS LDAP Users"> + </div> + </div> + <div class="paragraph"> + <p>Create the <code>ou=groups,o=mojo</code> hierarchy:</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-mojo-root-dse.png" alt="ActiveDS LDAP Users"> + </div> + </div> + <div class="paragraph"> + <p>Configure SASL authentication. This means that the checking of user/password is done implicitly by virtue of Apache Isis connecting to LDAP using these credentials:</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-sasl-authentication.png" alt="ActiveDS LDAP Users"> + </div> + </div> + <div class="paragraph"> + <p>In order for SASL to work, it seems to be necessary to put users under <code>o=system</code>. (This is why the setup is slightly different than the tutorial mentioned above):</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-users.png" alt="ActiveDS LDAP Users"> + </div> + </div> + <div class="paragraph"> + <p>Configure the users into the groups:</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-groups.png" alt="ActiveDS LDAP Users"> + </div> + </div> </div> </div> <div class="sect2"> - <h3 id="_active_ds_ldap_tutorial">4.3. Active DS LDAP tutorial</h3> + <h3 id="_ugsec_shiro-realm-implementations_isisaddons-security-module-realm">3.3. Security Module Realm</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-realm-implementations_isisaddons-security-module-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="paragraph"> - <p>The screenshots below show how to setup LDAP accounts in ApacheDS using the Apache Directory Studio.</p> + <p>The <a href="https://github.com/isisaddons/isis-module-security">Isis Addons' security module</a> (not ASF) provides a complete security subdomain for users, roles, permissions; all are persisted as domain entities.</p> </div> <div class="paragraph"> - <p>The setup here was initially based on <a href="http://krams915.blogspot.co.uk/2011/01/ldap-apache-directory-studio-basic.html">this tutorial</a>, however we have moved the user accounts so that they are defined in a separate LDAP node.</p> + <p>What that means, of course, that they can also be administered through your Isis application. Moreover, the set of permissions (to features) is derived completely from your applicationâs metamodel; in essence the permissions are "type-safe".</p> </div> <div class="paragraph"> - <p>To start, create a partition in order to hold the mojo node (holding the groups):</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-mojo-partition.png" alt="ActiveDS LDAP Users"> - </div> + <p>In order to play along, the module includes a Shiro realm, which fits in as follows:</p> </div> <div class="paragraph"> - <p>Create the <code>ou=groups,o=mojo</code> hierarchy:</p> + <p>The general configuration is as follows:</p> </div> <div class="imageblock"> <div class="content"> - <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-mojo-root-dse.png" alt="ActiveDS LDAP Users"> + <img src="images/security/security-apis-impl/configure-shiro-to-use-isisaddons-security-module-realm.PNG" alt="configure shiro to use isisaddons security module realm" width="600px"> </div> </div> <div class="paragraph"> - <p>Configure SASL authentication. This means that the checking of user/password is done implicitly by virtue of Apache Isis connecting to LDAP using these credentials:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-sasl-authentication.png" alt="ActiveDS LDAP Users"> - </div> + <p>where the <code>IsisModuleSecurityRealm</code> realm is the implementation provided by the module.</p> </div> <div class="paragraph"> - <p>In order for SASL to work, it seems to be necessary to put users under <code>o=system</code>. (This is why the setup is slightly different than the tutorial mentioned above):</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-users.png" alt="ActiveDS LDAP Users"> - </div> + <p>In the configuration above user passwords are stored in the database. The module uses <a href="http://www.mindrot.org/projects/jBCrypt/">jBCrypt</a> so that passwords are only stored in a (one-way) encrypted form in the database.</p> </div> <div class="paragraph"> - <p>Configure the users into the groups:</p> + <p>The security module also supports a slightly more sophisticated configuration. Most organizations use LDAP for user credentials, and maintaining two separate user accounts would be less than ideal. The <code>IsisModuleSecurityRealm</code> can therefore be configured with a subsidiary "delegate" realm that is responsible for performing the primary authentication of the user; if that passes then a user is created (as a domain entity) automatically. In most cases this delegate realm will be the LDAP realm, and so the architecture becomes:</p> </div> <div class="imageblock"> <div class="content"> - <img src="images//configuration/configuring-shiro/ldap/activeds-ldap-groups.png" alt="ActiveDS LDAP Users"> + <img src="images/security/security-apis-impl/configure-shiro-to-use-isisaddons-security-module-realm-with-delegate-realm.PNG" alt="configure shiro to use isisaddons security module realm with delegate realm" width="600px"> </div> </div> - </div> - </div> - </div> - <div class="sect1"> - <h2 id="_ugsec_shiro-isisaddons-security-module-realm">5. Security Module Realm</h2> - <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-isisaddons-security-module-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> - <div class="sectionbody"> - <div class="paragraph"> - <p>The <a href="https://github.com/isisaddons/isis-module-security">Isis Addons' security module</a> (not ASF) provides a complete security subdomain for users, roles, permissions; all are persisted as domain entities.</p> - </div> - <div class="paragraph"> - <p>What that means, of course, that they can also be administered through your Isis application. Moreover, the set of permissions (to features) is derived completely from your applicationâs metamodel; in essence the permissions are "type-safe".</p> - </div> - <div class="paragraph"> - <p>In order to play along, the module includes a Shiro realm, which fits in as follows:</p> - </div> - <div class="paragraph"> - <p>The general configuration is as follows:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-shiro-to-use-isisaddons-security-module-realm.PNG" alt="configure shiro to use isisaddons security module realm" width="600px"> - </div> - </div> - <div class="paragraph"> - <p>where the <code>IsisModuleSecurityRealm</code> realm is the implementation provided by the module.</p> - </div> - <div class="paragraph"> - <p>In the configuration above user passwords are stored in the database. The module uses <a href="http://www.mindrot.org/projects/jBCrypt/">jBCrypt</a> so that passwords are only stored in a (one-way) encrypted form in the database.</p> - </div> - <div class="paragraph"> - <p>The security module also supports a slightly more sophisticated configuration. Most organizations use LDAP for user credentials, and maintaining two separate user accounts would be less than ideal. The <code>IsisModuleSecurityRealm</code> can therefore be configured with a subsidiary "delegate" realm that is responsible for performing the primary authentication of the user; if that passes then a user is created (as a domain entity) automatically. In most cases this delegate realm will be the LDAP realm, and so the architecture becomes:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-shiro-to-use-isisaddons-security-module-realm-with-delegate-realm.PNG" alt="configure shiro to use isisaddons security module realm with delegate realm" width="600px"> + <div class="paragraph"> + <p>The security module has many more features than are described here, all of which are described in the moduleâs <a href="https://github.com/isisaddons/isis-module-security">README</a>. The README also explains in detail how to configure an existing app to use this module.</p> </div> - </div> - <div class="paragraph"> - <p>The security module has many more features than are described here, all of which are described in the moduleâs <a href="https://github.com/isisaddons/isis-module-security">README</a>. The README also explains in detail how to configure an existing app to use this module.</p> - </div> - <div class="paragraph"> - <p>You can also look at the Isisaddons <a href="https://github.com/isisaddons/isis-app-todoapp">todoapp example</a> (not ASF), which is preconfigured to use the security module.</p> - </div> - </div> - </div> - <div class="sect1"> - <h2 id="_ugsec_shiro-jdbc-realm">6. Shiro JDBC Realm</h2> - <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-jdbc-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> - <div class="sectionbody"> - <div class="paragraph"> - <p>There is nothing to stop you from using some other <code>Realm</code> implementation (or indeed writing one yourself). For example, you could use Shiroâs own JDBC realm that loads user/password details from a database.</p> - </div> - <div class="admonitionblock warning"> - <table> - <tbody> - <tr> - <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> - <td class="content"> - <div class="paragraph"> - <p>If you are happy to use a database then we strongly recommend you use the <a href="http://github.com/isisaddons/isis-module-security">Isis addons' security</a> module instead of a vanilla JDBC; it is far more sophisticated and moreover gives you the ability to administer the system from within your Isis application.</p> - </div> </td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>If you go down this route, then the architecture is as follows:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-shiro-to-use-custom-jdbc-realm.png" alt="configure shiro to use custom jdbc realm" width="600px"> + <div class="paragraph"> + <p>You can also look at the Isisaddons <a href="https://github.com/isisaddons/isis-app-todoapp">todoapp example</a> (not ASF), which is preconfigured to use the security module.</p> </div> </div> - <div class="paragraph"> - <p>Thereâs quite a lot of configuration required (in <code>WEB-INF/shiro.ini</code>) to set up a JDBC realm, so weâll break it out into sections.</p> - </div> - <div class="paragraph"> - <p>First, we need to set up the connection to JDBC:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm <i class="conum" data-value="1"></i><b>(1)</b> + <div class="sect2"> + <h3 id="_ugsec_shiro-realm-implementations_jdbc-realm">3.4. Shiro JDBC Realm</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-realm-implementations_jdbc-realm.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> + <div class="paragraph"> + <p>There is nothing to stop you from using some other <code>Realm</code> implementation (or indeed writing one yourself). For example, you could use Shiroâs own JDBC realm that loads user/password details from a database.</p> + </div> + <div class="admonitionblock warning"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> + <td class="content"> + <div class="paragraph"> + <p>If you are happy to use a database then we strongly recommend you use the <a href="http://github.com/isisaddons/isis-module-security">Isis addons' security</a> module instead of a vanilla JDBC; it is far more sophisticated and moreover gives you the ability to administer the system from within your Isis application.</p> + </div> </td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>If you go down this route, then the architecture is as follows:</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images/security/security-apis-impl/configure-shiro-to-use-custom-jdbc-realm.png" alt="configure shiro to use custom jdbc realm" width="600px"> + </div> + </div> + <div class="paragraph"> + <p>Thereâs quite a lot of configuration required (in <code>WEB-INF/shiro.ini</code>) to set up a JDBC realm, so weâll break it out into sections.</p> + </div> + <div class="paragraph"> + <p>First, we need to set up the connection to JDBC:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm <i class="conum" data-value="1"></i><b>(1)</b> jof = org.apache.shiro.jndi.JndiObjectFactory <i class="conum" data-value="2"></i><b>(2)</b> jof.resourceName = jdbc/postgres <i class="conum" data-value="3"></i><b>(3)</b> @@ -1083,36 +1080,36 @@ jof.requiredType = javax.sql.DataSource jof.resourceRef = true jdbcRealm.dataSource = $jof <i class="conum" data-value="4"></i><b>(4)</b></code></pre> + </div> </div> - </div> - <div class="colist arabic"> - <table> - <tbody> - <tr> - <td><i class="conum" data-value="1"></i><b>1</b></td> - <td>instantiate the JDBC realm</td> - </tr> - <tr> - <td><i class="conum" data-value="2"></i><b>2</b></td> - <td>instantiate factory object to lookup DataSource from servlet container</td> - </tr> - <tr> - <td><i class="conum" data-value="3"></i><b>3</b></td> - <td>name of the datasource (as configured in <code>web.xml</code>)</td> - </tr> - <tr> - <td><i class="conum" data-value="4"></i><b>4</b></td> - <td>instruct JDBC realm to obtain datasource from the JNDI</td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>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.</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">jdbcRealm.authenticationQuery = \ <i class="conum" data-value="1"></i><b>(1)</b> + <div class="colist arabic"> + <table> + <tbody> + <tr> + <td><i class="conum" data-value="1"></i><b>1</b></td> + <td>instantiate the JDBC realm</td> + </tr> + <tr> + <td><i class="conum" data-value="2"></i><b>2</b></td> + <td>instantiate factory object to lookup DataSource from servlet container</td> + </tr> + <tr> + <td><i class="conum" data-value="3"></i><b>3</b></td> + <td>name of the datasource (as configured in <code>web.xml</code>)</td> + </tr> + <tr> + <td><i class="conum" data-value="4"></i><b>4</b></td> + <td>instruct JDBC realm to obtain datasource from the JNDI</td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>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.</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">jdbcRealm.authenticationQuery = \ <i class="conum" data-value="1"></i><b>(1)</b> select password \ from users \ where username = ? @@ -1138,104 +1135,105 @@ jdbcRealm.permissionsQuery= \ <i class="conum" data-va where label = ?); jdbcRealm.permissionsLookupEnabled=true <i class="conum" data-value="4"></i><b>(4)</b></code></pre> + </div> </div> - </div> - <div class="colist arabic"> - <table> - <tbody> - <tr> - <td><i class="conum" data-value="1"></i><b>1</b></td> - <td>query to find password for user</td> - </tr> - <tr> - <td><i class="conum" data-value="2"></i><b>2</b></td> - <td>query to find roles for user</td> - </tr> - <tr> - <td><i class="conum" data-value="3"></i><b>3</b></td> - <td>query to find permissions for role</td> - </tr> - <tr> - <td><i class="conum" data-value="4"></i><b>4</b></td> - <td>enable permissions lookup</td> - </tr> - </tbody> - </table> - </div> - <div class="admonitionblock warning"> - <table> - <tbody> - <tr> - <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> - <td class="content"> - <div class="paragraph"> - <p>The <code>permissionsLookupEnabled</code> is very important, otherwise Shiro just returns an empty list of permissions and your users will have no access to any features(!).</p> - </div> </td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>We also should ensure that the passwords are not stored as plain-text:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">dps = org.apache.shiro.authc.credential.DefaultPasswordService <i class="conum" data-value="1"></i><b>(1)</b> + <div class="colist arabic"> + <table> + <tbody> + <tr> + <td><i class="conum" data-value="1"></i><b>1</b></td> + <td>query to find password for user</td> + </tr> + <tr> + <td><i class="conum" data-value="2"></i><b>2</b></td> + <td>query to find roles for user</td> + </tr> + <tr> + <td><i class="conum" data-value="3"></i><b>3</b></td> + <td>query to find permissions for role</td> + </tr> + <tr> + <td><i class="conum" data-value="4"></i><b>4</b></td> + <td>enable permissions lookup</td> + </tr> + </tbody> + </table> + </div> + <div class="admonitionblock warning"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> + <td class="content"> + <div class="paragraph"> + <p>The <code>permissionsLookupEnabled</code> is very important, otherwise Shiro just returns an empty list of permissions and your users will have no access to any features(!).</p> + </div> </td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>We also should ensure that the passwords are not stored as plain-text:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">dps = org.apache.shiro.authc.credential.DefaultPasswordService <i class="conum" data-value="1"></i><b>(1)</b> pm = org.apache.shiro.authc.credential.PasswordMatcher <i class="conum" data-value="2"></i><b>(2)</b> pm.passwordService = $dps jdbcRealm.credentialsMatcher = $pm <i class="conum" data-value="3"></i><b>(3)</b></code></pre> + </div> </div> - </div> - <div class="colist arabic"> - <table> - <tbody> - <tr> - <td><i class="conum" data-value="1"></i><b>1</b></td> - <td>mechanism to encrypts password</td> - </tr> - <tr> - <td><i class="conum" data-value="2"></i><b>2</b></td> - <td>service to match passwords</td> - </tr> - <tr> - <td><i class="conum" data-value="3"></i><b>3</b></td> - <td>instruct JDBC realm to use password matching service when authenticating</td> - </tr> - </tbody> - </table> - </div> - <div class="paragraph"> - <p>And finally we need to tell Shiro to use the realm, in the usual fashion:</p> - </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">securityManager.realms = $jdbcRealm</code></pre> + <div class="colist arabic"> + <table> + <tbody> + <tr> + <td><i class="conum" data-value="1"></i><b>1</b></td> + <td>mechanism to encrypts password</td> + </tr> + <tr> + <td><i class="conum" data-value="2"></i><b>2</b></td> + <td>service to match passwords</td> + </tr> + <tr> + <td><i class="conum" data-value="3"></i><b>3</b></td> + <td>instruct JDBC realm to use password matching service when authenticating</td> + </tr> + </tbody> + </table> + </div> + <div class="paragraph"> + <p>And finally we need to tell Shiro to use the realm, in the usual fashion:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">securityManager.realms = $jdbcRealm</code></pre> + </div> + </div> + <div class="paragraph"> + <p>Using the above configuration you will also need to setup a <code>DataSource</code>. The details vary by servlet container, for example this is <a href="https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html">how to do the setup on Tomcat 8.0</a>.</p> + </div> + <div class="admonitionblock warning"> + <table> + <tbody> + <tr> + <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> + <td class="content"> + <div class="paragraph"> + <p>The name of the <code>DataSource</code> can also vary by servlet container; see for example <a href="http://stackoverflow.com/questions/17441019/how-to-configure-jdbcrealm-to-obtain-its-datasource-from-jndi/23784702#23784702">this StackOverflow answer</a>.</p> + </div> </td> + </tr> + </tbody> + </table> </div> - </div> - <div class="paragraph"> - <p>Using the above configuration you will also need to setup a <code>DataSource</code>. The details vary by servlet container, for example this is <a href="https://tomcat.apache.org/tomcat-8.0-doc/jndi-datasource-examples-howto.html">how to do the setup on Tomcat 8.0</a>.</p> - </div> - <div class="admonitionblock warning"> - <table> - <tbody> - <tr> - <td class="icon"> <i class="fa icon-warning" title="Warning"></i> </td> - <td class="content"> - <div class="paragraph"> - <p>The name of the <code>DataSource</code> can also vary by servlet container; see for example <a href="http://stackoverflow.com/questions/17441019/how-to-configure-jdbcrealm-to-obtain-its-datasource-from-jndi/23784702#23784702">this StackOverflow answer</a>.</p> - </div> </td> - </tr> - </tbody> - </table> </div> </div> </div> <div class="sect1"> - <h2 id="_ugsec_shiro-isis-enhanced-wildcard-permission">7. Enhanced Wildcard Permission</h2> + <h2 id="_ugsec_shiro-isis-enhanced-wildcard-permission">4. Enhanced Wildcard Permission</h2> <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_shiro-isis-enhanced-wildcard-permission.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> <div class="paragraph"> - <p>If using the text-based <a href="#_ugsec_shiro-ini-realm"><code>IniRealm</code></a> or <a href="#_ugsec_shiro-isis-ldap-realm">Isis' LDAP realm</a>, then note that Shiro also allows the string representation of the permissions to be mapped (resolved) to alternative <code>Permission</code> instances. Apache Isis provides its own <code>IsisPermission</code> which introduces the concept of a "veto".</p> + <p>If using the text-based <a href="../ugsec/ugsec.html#_ugsec_shiro-realm-implementations_ini-realm"><code>IniRealm</code></a> or <a href="../ugsec/ugsec.html#_ugsec_shiro-realm-implementations_isis-ldap-realm">Isis' LDAP realm</a>, then note that Shiro also allows the string representation of the permissions to be mapped (resolved) to alternative <code>Permission</code> instances. Apache Isis provides its own <code>IsisPermission</code> which introduces the concept of a "veto".</p> </div> <div class="paragraph"> <p>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.</p> @@ -1311,36 +1309,90 @@ myRealm.permissionResolver = $permissionResolver <i class="conum" data-value="1 </div> </div> <div class="sect1"> - <h2 id="_ugsec_configuring-isis-to-use-bypass">8. Bypassing security</h2> - <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_configuring-isis-to-use-bypass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> + <h2 id="_ugsec_hints-and-tips">5. Hints and Tips</h2> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_hints-and-tips.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> <div class="paragraph"> - <p>The bypass security component consists of an implementation of both the <code>AuthenticationManager</code> and <code>AuthorizationManager</code> APIs, and are intended for prototyping use only.</p> + <p>This chapter provides some solutions for problems weâve encountered ourselves or have been raised on the Apache Isis mailing lists.</p> </div> <div class="paragraph"> - <p>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).</p> + <p>See also hints-n-tips chapters in the:</p> </div> - <div class="paragraph"> - <p>To tell Apache Isis to bypass security, just update the <code>WEB-INF/isis.properties</code> file:</p> + <div class="ulist"> + <ul> + <li> <p>the <a href="../dg/dg.html#_dg_hints-and-tips">Developers'</a> guide</p> </li> + <li> <p>the <a href="../ugvw/ugvw.html#_ugvw_hints-and-tips">Wicket viewer</a> guide</p> </li> + <li> <p>the <a href="../ugvro/ugvro.html#_ugvro_hints-and-tips">Restful Objects viewer</a> guide</p> </li> + <li> <p>the <a href="../ugodn/ugodn.html#_ugodn_hints-and-tips">Datanucleus ObjectStore</a> guide</p> </li> + <li> <p>the <a href="../ugsec/ugsec.html#_ugsec_hints-and-tips">Security</a> guide (this chapter)</p> </li> + <li> <p>the <a href="../ugbtb/ugbtb.html#_ugbtb_hints-and-tips">Beyond the Basics</a> guide.</p> </li> + </ul> </div> - <div class="listingblock"> - <div class="content"> - <pre class="CodeRay highlight"><code data-lang="ini">isis.authentication=bypass + <div class="sect2"> + <h3 id="_ugsec_hints-and-tips_configuring-isis-to-use-bypass">5.1. Bypassing security</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_hints-and-tips_configuring-isis-to-use-bypass.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> + <div class="paragraph"> + <p>The bypass security component consists of an implementation of both the <code>AuthenticationManager</code> and <code>AuthorizationManager</code> APIs, and are intended for prototyping use only.</p> + </div> + <div class="paragraph"> + <p>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).</p> + </div> + <div class="paragraph"> + <p>To tell Apache Isis to bypass security, just update the <code>WEB-INF/isis.properties</code> file:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">isis.authentication=bypass isis.authorization=bypass</code></pre> + </div> + </div> + <div class="paragraph"> + <p>This installs the appropriate no-op implementations for both authentication and authorization:</p> + </div> + <div class="imageblock"> + <div class="content"> + <img src="images/security/security-apis-impl/configure-isis-to-use-bypass.PNG" alt="configure isis to use bypass" width="600px"> + </div> </div> </div> - <div class="paragraph"> - <p>This installs the appropriate no-op implementations for both authentication and authorization:</p> - </div> - <div class="imageblock"> - <div class="content"> - <img src="images/security/security-apis-impl/configure-isis-to-use-bypass.PNG" alt="configure isis to use bypass" width="600px"> + <div class="sect2"> + <h3 id="_ugsec_hints-and-tips_shiro-caching">5.2. Caching and other Shiro Features</h3> + <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_hints-and-tips_shiro-caching.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> + <div class="paragraph"> + <p>We donât want to repeat the entire <a href="http://shiro.apache.org/documentation.html">Shiro documentation set</a> here, but we should flag a number of otherof other features that are worth checking out.</p> + </div> + <div class="sect3"> + <h4 id="_caching">5.2.1. Caching</h4> + <div class="paragraph"> + <p>To ensure that security operations does not impede performance, Shiro supports caching. For example, this sets up a simple memory-based cache manager:</p> + </div> + <div class="listingblock"> + <div class="content"> + <pre class="CodeRay highlight"><code data-lang="ini">memoryCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager +securityManager.cacheManager = $memoryCacheManager</code></pre> + </div> + </div> + <div class="paragraph"> + <p>Other implementations can be plugged in; see the Shiro <a href="http://shiro.apache.org/caching.html">documentation</a> for further details.</p> + </div> + </div> + <div class="sect3"> + <h4 id="_further_reading">5.2.2. Further Reading</h4> + <div class="ulist"> + <ul> + <li> <p>Shiroâs documentation page can be found <a href="http://shiro.apache.org/documentation.html">here</a>.</p> </li> + <li> <p>community-contributed articles can be found <a href="http://shiro.apache.org/articles.html">here</a>.<br></p> + <div class="paragraph"> + <p>These include for instance <a href="http://meri-stuff.blogspot.co.uk/2011/04/apache-shiro-part-2-realms-database-and.html">this interesting article</a> describing how to perform certificate-based authentication (ie login using Google or Facebook credentials).</p> + </div> </li> + </ul> + </div> </div> </div> </div> </div> <div class="sect1"> - <h2 id="_ugsec_api-for-applications">9. API for Applications</h2> + <h2 id="_ugsec_api-for-applications">6. API for Applications</h2> <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_api-for-applications.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> <div class="paragraph"> @@ -1350,9 +1402,9 @@ isis.authorization=bypass</code></pre> <p>Still, on very rare occasion you may have a need, in which case you can either use Apache Isis' <code>DomainObjectContainer</code> API or you can reach further down the stack and use the JEE Servlet API.</p> </div> <div class="sect2"> - <h3 id="__code_domainobjectcontainer_code_api">9.1. <code>DomainObjectContainer</code> API</h3> + <h3 id="__code_domainobjectcontainer_code_api">6.1. <code>DomainObjectContainer</code> API</h3> <div class="paragraph"> - <p>The <a href="rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a> service exposes the following API:</p> + <p>The <a href="../rgsvc/rgsvc.html#_rgsvc_api_DomainObjectContainer"><code>DomainObjectContainer</code></a> service exposes the following API:</p> </div> <div class="listingblock"> <div class="content"> @@ -1383,7 +1435,7 @@ isis.authorization=bypass</code></pre> </div> </div> <div class="sect2"> - <h3 id="_servlet_api">9.2. Servlet API</h3> + <h3 id="_servlet_api">6.2. Servlet API</h3> <div class="paragraph"> <p>On occasion you may find it necessary to reach below Isis and to the underlying servlet API. For example, the <a href="http://github.com/isisaddons/isis-module-togglz">Isis addons' togglz</a> module (non-ASF) has a requirement to do this in order to expose its embedded togglz web console. (</p> </div> @@ -1417,19 +1469,19 @@ isis.authorization=bypass</code></pre> </div> </div> <div class="sect1"> - <h2 id="_ugsec_usage-by-isis-viewers">10. Usage by Apache Isis' Viewers</h2> + <h2 id="_ugsec_usage-by-isis-viewers">7. Usage by Apache Isis' Viewers</h2> <button type="button" class="button secondary" onclick="window.location.href="https://github.com/apache/isis/edit/master/adocs/documentation/src/main/asciidoc/guides/ugsec/_ugsec_usage-by-isis-viewers.adoc"" style="float: right; font-size: small; padding: 6px; margin-top: -55px; "><i class="fa fa-pencil-square-o"></i> Edit</button> <div class="sectionbody"> <div class="paragraph"> - <p>By and large the security mechanisms within Isis are transparent to the rest of the framework (the <a href="ugvw.html">Wicket Viewer</a> and <a href="ugvro.html">Restful Objects viewer</a>, and the overall <a href="rgcfg.html#_rgcfg">runtime</a>).</p> + <p>By and large the security mechanisms within Isis are transparent to the rest of the framework (the <a href="../ugvw/ugvw.html">Wicket Viewer</a> and <a href="../ugvro/ugvro.html">Restful Objects viewer</a>, and the overall <a href="../rgcfg/rgcfg.html#_rgcfg">runtime</a>).</p> </div> <div class="paragraph"> <p>That said, it is the responsibility of the viewers to ensure that there is a viewers to ensure that for each request there is a valid user session present. The sections below explain how this works.</p> </div> <div class="sect2"> - <h3 id="_wicket_viewer">10.1. Wicket Viewer</h3> + <h3 id="_wicket_viewer">7.1. Wicket Viewer</h3> <div class="paragraph"> - <p>The <a href="ugvw.html">Wicket viewer</a> defines a relatively small number of pages (by which we mean subclasses of <a href="http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/markup/html/WebPage.html"><code>org.apache.wicket.markup.html.WebPage</code></a>):</p> + <p>The <a href="../ugvw/ugvw.html">Wicket viewer</a> defines a relatively small number of pages (by which we mean subclasses of <a href="http://ci.apache.org/projects/wicket/apidocs/6.0.x/org/apache/wicket/markup/html/WebPage.html"><code>org.apache.wicket.markup.html.WebPage</code></a>):</p> </div> <div class="ulist"> <ul> @@ -1461,7 +1513,7 @@ isis.authorization=bypass</code></pre> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> - <p>The sign-in page to render is pluggable; see <a href="ugvw.html#_ugvw_extending_custom-pages">extensions chapter</a> for details.</p> + <p>The sign-in page to render is pluggable; see <a href="../ugvw/ugvw.html#_ugvw_extending_custom-pages">extensions chapter</a> for details.</p> </div> </td> </tr> </tbody> @@ -1477,9 +1529,9 @@ isis.authorization=bypass</code></pre> <p>Similarly, for those object members that <em>are</em> visible, the viewer also checks if they are enabled or disabled. Again, an object member will be disabled if the user does not have (write) permission, or it could be disabled because of domain object logic (eg a <code>disableXxx()</code> method).</p> </div> <div class="sect3"> - <h4 id="_user_registration">10.1.1. User-registration</h4> + <h4 id="_user_registration">7.1.1. User-registration</h4> <div class="paragraph"> - <p>As well as providing a sign-in screen, the Wicket viewer also provides the ability for <a href="#_user_registration">users to self-register</a>. By and large this operates outside of Apache Isis' security mechanisms; indeed the various pages (sign-up, sign-up verification, password reset) are all rendered <em>without</em> there being any current user session. These pages all "reach inside" Apache Isis framework using a mechanism similar to <a href="ugbtb.html#_ugbtb_headless-access">Headless access</a> in order to actually do their stuff.</p> + <p>As well as providing a sign-in screen, the Wicket viewer also provides the ability for users to self-register. By and large this operates outside of Apache Isis' security mechanisms; indeed the various pages (sign-up, sign-up verification, password reset) are all rendered <em>without</em> there being any current user session. These pages all "reach inside" Apache Isis framework using a mechanism similar to <a href="../ugbtb/ugbtb.html#_ugbtb_headless-access">Headless access</a> in order to actually do their stuff.</p> </div> <div class="admonitionblock tip"> <table> @@ -1488,14 +1540,14 @@ isis.authorization=bypass</code></pre> <td class="icon"> <i class="fa icon-tip" title="Tip"></i> </td> <td class="content"> <div class="paragraph"> - <p>The sign-in verification page to render is pluggable; see <a href="ugvw.html#_ugvw_extending_custom-pages">extensions chapter</a> for details.</p> + <p>The sign-in verification page to render is pluggable; see <a href="../ugvw/ugvw.html#_ugvw_extending_custom-pages">extensions chapter</a> for details.</p> </div> </td> </tr> </tbody> </table> </div> <div class="paragraph"> - <p>User registration is only available if the <a href="rgsvc.html#_rgsvc_spi_UserRegistrationService"><code>UserRegistrationService</code></a> is configured; this is used by the framework to actually create new instances of the user as accessed by the corresponding (Shiro) realm.</p> + <p>User registration is only available if the <a href="../rgsvc/rgsvc.html#_rgsvc_spi_UserRegistrationService"><code>UserRegistrationService</code></a> is configured; this is used by the framework to actually create new instances of the user as accessed by the corresponding (Shiro) realm.</p> </div> <div class="paragraph"> <p>Because Shiro realms are pluggable, the Apache Isis framework does not provide default implementations of this service. However, if you are using the <a href="http://github.com/isisaddons/isis-module-security">Isis addons' security</a> module (non-ASF), then this module <em>does</em> provide an implementation (that, as you might expect, creates new "user" domain entities).</p> @@ -1506,9 +1558,9 @@ isis.authorization=bypass</code></pre> </div> </div> <div class="sect2"> - <h3 id="_restful_objects_viewer">10.2. Restful Objects Viewer</h3> + <h3 id="_restful_objects_viewer">7.2. Restful Objects Viewer</h3> <div class="paragraph"> - <p>Unlike the Wicket viewer, the <a href="ugvro.html">Restful Objects viewer</a> does <strong>not</strong> provide any sort of login page; rather it provides a pluggable authentication strategy, delegated to by the <code>IsisSessionFilter</code> filter defined in <code>web.xml</code>. The authentication strategy is responsible for ensuring that a session is available for the REST resource.</p> + <p>Unlike the Wicket viewer, the <a href="../ugvro/ugvro.html">Restful Objects viewer</a> does <strong>not</strong> provide any sort of login page; rather it provides a pluggable authentication strategy, delegated to by the <code>IsisSessionFilter</code> filter defined in <code>web.xml</code>. The authentication strategy is responsible for ensuring that a session is available for the REST resource.</p> </div> <div class="paragraph"> <p>The API of <code>AuthenticationSessionStrategy</code> is simply:</p> @@ -1631,7 +1683,7 @@ public <span class="type">interface</span> <span class="class">AuthenticationSes </table> </div> <div class="sect3"> - <h4 id="_user_registration_2">10.2.1. User-registration</h4> + <h4 id="_user_registration_2">7.2.1. User-registration</h4> <div class="paragraph"> <p>Isis currently does not have any out-of-the-box support for user-registration for applications using only the Restful viewer. However, in principal the pieces do exist to put together a solution.</p> </div> @@ -1730,46 +1782,57 @@ userRegistrationService.registerUser(userDetails);</code></pre> <li><a href="#_other_guides">1.1. Other Guides</a></li> <li><a href="#_terminology">1.2. Terminology</a></li> </ul> </li> - <li><a href="#_ugsec_configuring-isis-to-use-shiro">2. Configuring Apache Isis to use Shiro</a> + <li><a href="#_ugsec_configuring-isis-to-use-shiro">2. Configuring to use Shiro</a> <ul class="sectlevel2"> <li><a href="#_telling_apache_isis_to_use_shiro">2.1. Telling Apache Isis to use Shiro</a></li> - <li><a href="#_configuring_isis_shiro_authenticator">2.2. Configuring Isis' Shiro Authenticator</a></li> + <li><a href="#_configuring_shiro_authenticator">2.2. Configuring Shiro Authenticator</a></li> <li><a href="#_bootstrapping_shiro">2.3. Bootstrapping Shiro</a></li> <li><a href="#__code_web_inf_shiro_ini_code">2.4. <code>WEB-INF/shiro.ini</code></a></li> </ul> </li> - <li><a href="#_ugsec_shiro-ini-realm">3. Shiro Ini Realm</a> + <li><a href="#_ugsec_shiro-realm-implementations">3. Shiro Realm Implementations</a> <ul class="sectlevel2"> - <li><a href="#_shiro_configuration">3.1. Shiro Configuration</a> + <li><a href="#_ugsec_shiro-realm-implementations_ini-
<TRUNCATED>