This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3866 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit e8399e4689dc3a0b60b21c6bcb2074449aca3595 Author: Dan Haywood <[email protected]> AuthorDate: Sat Oct 18 17:58:59 2025 +0100 CAUSEWAY-3866: removes references to shiro --- README.adoc | 6 +- .../causeway-in-pictures.adoc | 4 +- .../CausewayModuleExtSecmanDelegatedShiro.adoc | 12 - .../realm/CausewayModuleExtSecmanShiroRealm.adoc | 27 - .../secman/delegated/shiro/util/ShiroUtils.adoc | 15 - .../modules/ROOT/pages/2024/3.0.0/mignotes.adoc | 2 +- .../modules/ROOT/pages/2024/3.0.0/relnotes.adoc | 40 +- .../ROOT/partials/2024/2.0.0/_relnotes.adoc | 11 +- .../ROOT/partials/2024/2.1.0/_relnotes.adoc | 2 +- causeway-tooling.yml | 2 +- core/config/generateConfigDocs.groovy | 7 - .../adoc/modules/config/pages/sections/_nav.adoc | 1 - .../pages/sections/causeway.security.shiro.adoc | 29 - .../main/adoc/modules/webapp/pages/webmodules.adoc | 10 +- .../main/adoc/modules/webapp/pages/webmodules.html | 851 +++++++++++++++++++++ .../images/secman-shiro-architecture.drawio.svg | 4 - .../secman-shiro-delegate-architecture.drawio.svg | 4 - .../secman/adoc/modules/secman/pages/about.adoc | 5 - .../adoc/modules/secman/pages/setting-up.adoc | 9 +- .../secman/applib/user/dom/AccountType.java | 12 +- .../secman/applib/user/dom/ApplicationUser.java | 7 +- .../integration/authorizor/AuthorizorSecman.java | 11 - .../adoc/modules/spring-oauth2/pages/about.adoc | 92 ++- regressiontests/incubating/pom.xml | 12 - .../test/resources/shiro-secman-ldap-cached.ini | 55 -- .../src/test/resources/shiro-secman-ldap.ini | 51 -- .../incubating/src/test/resources/shiro-secman.ini | 31 - .../incubating/src/test/resources/shiro-simple.ini | 58 -- security/adoc/modules/ROOT/pages/about.adoc | 1 - .../adoc/modules/ROOT/partials/component-nav.adoc | 1 - valuetypes/vega/adoc/modules/vega/pages/about.adoc | 2 +- .../auth/AuthenticationStrategyBasicAuth.java | 7 - 32 files changed, 971 insertions(+), 410 deletions(-) diff --git a/README.adoc b/README.adoc index 54227d55886..1722560ae83 100644 --- a/README.adoc +++ b/README.adoc @@ -25,8 +25,10 @@ Apache Causeway automatically generates the UI from the domain classes. === Sign-in -Apache Causeway integrates with http://shiro.apache.org[Apache Shiro] as well as link:https://spring.io/projects/spring-security[Spring Security] and link:https://www.keycloak.org/[Keycloak]. -When using Shiro, the core framework supports file-based realms, while the __SecMan__ extension provides a well-featured subdomain of users, roles and permissions against features derived from the Apache Causeway metamodel. +Apache Causeway integrates with link:https://spring.io/projects/spring-security[Spring Security] and link:https://www.keycloak.org/[Keycloak] for authentication concerns, typically in combination with OAuth2. +These are usually combined with the __SecMan__ module, which provides a set of domain entities that model an authenticaiton model: users, roles and permissions against features derived from the Apache Causeway metamodel. +The SecMan user is mapped to the authentical principle provided by Spring or Keycloak. +Alternatively, SecMan can perform its own local authentication. image::https://raw.githubusercontent.com/apache/causeway/main/antora/components/docs/modules/ROOT/images/what-is-apache-causeway/causeway-in-pictures/010-login.png[link="https://raw.githubusercontent.com/apache/causeway/main/antora/components/docs/modules/ROOT/images/what-is-apache-causeway/causeway-in-pictures/010-login.png"] diff --git a/antora/components/docs/modules/ROOT/pages/what-is-apache-causeway/causeway-in-pictures.adoc b/antora/components/docs/modules/ROOT/pages/what-is-apache-causeway/causeway-in-pictures.adoc index 6f9ba6c1276..84248d8cd1b 100644 --- a/antora/components/docs/modules/ROOT/pages/what-is-apache-causeway/causeway-in-pictures.adoc +++ b/antora/components/docs/modules/ROOT/pages/what-is-apache-causeway/causeway-in-pictures.adoc @@ -16,9 +16,9 @@ Let's start with the basics... === Sign-in -Apache Causeway integrates with a variety of authentication mechanisms, including link:http://shiro.apache.org[Apache Shiro], link:https://spring.io/projects/spring-security[Spring Security] and link:https://www.keycloak.org/[Keycloak]. +Apache Causeway integrates with a variety of authentication mechanisms, including link:https://spring.io/projects/spring-security[Spring Security] and link:https://www.keycloak.org/[Keycloak]. -The xref:security:ROOT:about.adoc[SecMan extension] provides a well-features subdomain of users, roles and permissions against features derived from the Apache Causeway metamodel. +The xref:security:ROOT:about.adoc[SecMan extension] provides a well-featured subdomain of users, roles and permissions against features derived from the Apache Causeway metamodel. diff --git a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/CausewayModuleExtSecmanDelegatedShiro.adoc b/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/CausewayModuleExtSecmanDelegatedShiro.adoc deleted file mode 100644 index 20fc2f3d263..00000000000 --- a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/CausewayModuleExtSecmanDelegatedShiro.adoc +++ /dev/null @@ -1,12 +0,0 @@ -= CausewayModuleExtSecmanDelegatedShiro -: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 [...] - -== API - -[source,java] -.CausewayModuleExtSecmanDelegatedShiro.java ----- -class CausewayModuleExtSecmanDelegatedShiro { -} ----- - diff --git a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/realm/CausewayModuleExtSecmanShiroRealm.adoc b/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/realm/CausewayModuleExtSecmanShiroRealm.adoc deleted file mode 100644 index 17c0b2b02c0..00000000000 --- a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/realm/CausewayModuleExtSecmanShiroRealm.adoc +++ /dev/null @@ -1,27 +0,0 @@ -= CausewayModuleExtSecmanShiroRealm -: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 [...] - -== API - -[source,java] -.CausewayModuleExtSecmanShiroRealm.java ----- -class CausewayModuleExtSecmanShiroRealm { - CausewayModuleExtSecmanShiroRealm() // <.> - V execute(Supplier<V> closure) - V doExecute(Supplier<V> closure) -} ----- - -<.> xref:#CausewayModuleExtSecmanShiroRealm_[CausewayModuleExtSecmanShiroRealm()] -+ --- -Configures a _org.apache.shiro.authz.permission.PermissionResolver_ that knows how to process the permission strings that are provided by Causeway' xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] for Shiro. --- - -== Members - -[#CausewayModuleExtSecmanShiroRealm_] -=== CausewayModuleExtSecmanShiroRealm() - -Configures a _org.apache.shiro.authz.permission.PermissionResolver_ that knows how to process the permission strings that are provided by Causeway' xref:refguide:core:index/security/authorization/Authorizor.adoc[Authorizor] for Shiro. diff --git a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/util/ShiroUtils.adoc b/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/util/ShiroUtils.adoc deleted file mode 100644 index e315d34ade6..00000000000 --- a/antora/components/refguide-index/modules/extensions/pages/index/secman/delegated/shiro/util/ShiroUtils.adoc +++ /dev/null @@ -1,15 +0,0 @@ -= ShiroUtils -: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 [...] - -== API - -[source,java] -.ShiroUtils.java ----- -class ShiroUtils { - RealmSecurityManager getSecurityManager() - CausewayModuleExtSecmanShiroRealm getCausewayModuleSecurityRealm() - boolean isSingleRealm() -} ----- - diff --git a/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/mignotes.adoc b/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/mignotes.adoc index 34063197469..04e560d142f 100644 --- a/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/mignotes.adoc +++ b/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/mignotes.adoc @@ -8,7 +8,7 @@ To upgrade from v2.0 to v3.0: * move up to Java 17 (minimum) * update namespaces from `javax` to `jakarta` -* if you are using the xref:security:shiro:about.adoc[Shiro security] module, this will need to choose a different security implementation. +* if you have been using the _Shiro security_ module, this will need to choose a different security implementation. This last point is discussed xref:#simple-security-replacement-for-shiro[below]. diff --git a/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/relnotes.adoc b/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/relnotes.adoc index 80bd027f70f..26df38c9fe9 100644 --- a/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/relnotes.adoc +++ b/antora/components/relnotes/modules/ROOT/pages/2024/3.0.0/relnotes.adoc @@ -5,26 +5,26 @@ :page-partial: -After almost six years effort (!), v2.0.0 and v3.0.0 are the first official releases of Apache Causeway, now re-platformed to run on Spring Boot. -The two versions are being released at the same time. - - -The v3.0.0 release is broadly equivalent to the v2.0.0 release. -As such, see the xref:2024/2.0.0/relnotes.adoc[2.0.0] release notes for full details of the features available in this release. - -However, 3.0.0: - -* targets Spring Boot 3.x (instead of Spring Boot 2.x) -* targets Java 17 (instead of Java 11) - -It also uses the `jakarta` namespace rather than `javax`. - - -There is one functional change, namely that support for xref:security:shiro:about.adoc[Shiro security] module has been dropped (for now). -See the xref:relnotes:ROOT:2024/3.0.0/mignotes.adoc#simple-security-replacement-for-shiro[migration notes] for options. - - -include::partial$2024/2.0.0/_relnotes.adoc[] +// After almost six years effort (!), v2.0.0 and v3.0.0 are the first official releases of Apache Causeway, now re-platformed to run on Spring Boot. +// The two versions are being released at the same time. +// +// +// The v3.0.0 release is broadly equivalent to the v2.0.0 release. +// As such, see the xref:2024/2.0.0/relnotes.adoc[2.0.0] release notes for full details of the features available in this release. +// +// However, 3.0.0: +// +// * targets Spring Boot 3.x (instead of Spring Boot 2.x) +// * targets Java 17 (instead of Java 11) +// +// It also uses the `jakarta` namespace rather than `javax`. +// +// +// There is one functional change, namely that support for _Shiro security_ module has been dropped. +// See the xref:relnotes:ROOT:2024/3.0.0/mignotes.adoc#simple-security-replacement-for-shiro[migration notes] for options. +// +// +// include::partial$2024/2.0.0/_relnotes.adoc[] diff --git a/antora/components/relnotes/modules/ROOT/partials/2024/2.0.0/_relnotes.adoc b/antora/components/relnotes/modules/ROOT/partials/2024/2.0.0/_relnotes.adoc index 7718e747a7c..9b61ba332f0 100644 --- a/antora/components/relnotes/modules/ROOT/partials/2024/2.0.0/_relnotes.adoc +++ b/antora/components/relnotes/modules/ROOT/partials/2024/2.0.0/_relnotes.adoc @@ -59,7 +59,7 @@ Other highlights * xref:pjpa:ROOT:about.adoc[Persistence using JPA] has been added through an integration of EclipseLink. + -Persistence using JDO continues to be supported through the integration with DataNucleus. +Persistence using JDO continues to be supported through the integration with _DataNucleus_. + [NOTE] ==== @@ -85,8 +85,13 @@ In particular, "encapsulated" mode mean that the properties and collections of e ** supported custom scalar value types and composite types + -This includes xref:valuetypes:asciidoc:about.adoc[AsciiDoc], xref:valuetypes:markdown:about.adoc[Markdown], xref:valuetypes:jodatime:about.adoc[Jodatime] and xref:valuetypes:vega:about.adoc[Vega] -(link:https://vega.github.io/vega-lite/[Vega-lite], "a grammar of interactive graphics"). +This includes xref:valuetypes:asciidoc:about.adoc[AsciiDoc] +, xref:valuetypes:markdown:about.adoc[Markdown], +_Jodatime_ and _Vega_ +//// +xref:valuetypes:vega:about.adoc[Vega] +//// + (link:https://vega.github.io/vega-lite/[Vega-lite], "a grammar of interactive graphics"). ** mixin classes annotated as `@Action`, `@Property` or `@Collection` diff --git a/antora/components/relnotes/modules/ROOT/partials/2024/2.1.0/_relnotes.adoc b/antora/components/relnotes/modules/ROOT/partials/2024/2.1.0/_relnotes.adoc index 90d9133d54f..90dd6e2a4f3 100644 --- a/antora/components/relnotes/modules/ROOT/partials/2024/2.1.0/_relnotes.adoc +++ b/antora/components/relnotes/modules/ROOT/partials/2024/2.1.0/_relnotes.adoc @@ -56,7 +56,7 @@ | Shiro | 1.13.0 a| (dropped) -| xref:security:shiro:about.adoc[] +| |=== diff --git a/causeway-tooling.yml b/causeway-tooling.yml index 584096ffd33..a9fec618bc8 100644 --- a/causeway-tooling.yml +++ b/causeway-tooling.yml @@ -40,7 +40,7 @@ commands: Security: org.apache.causeway.security Bypass: "org.apache.causeway.security:causeway-security-bypass.*" Keycloak: "org.apache.causeway.security:causeway-security-keycloak.*" - Shiro: "org.apache.causeway.security:causeway-security-shiro.*" + Simple: "org.apache.causeway.security:causeway-security-simple.*" Spring: "org.apache.causeway.security:causeway-security-spring.*" Viewer: org.apache.causeway.viewer diff --git a/core/config/generateConfigDocs.groovy b/core/config/generateConfigDocs.groovy index d452bb411cc..b7f53803733 100644 --- a/core/config/generateConfigDocs.groovy +++ b/core/config/generateConfigDocs.groovy @@ -138,13 +138,6 @@ groups+= new PropertyGroup() {{ searchOrder = 200 }} -groups+= new PropertyGroup() {{ - prefix = "causeway.security.shiro" - name = "Shiro Security Implementation" - properties: [] - searchOrder = 501 -}} - groups+= new PropertyGroup() {{ prefix = "causeway.security.keycloak" name = "Keycloak Security Implementation" diff --git a/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc b/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc index 818efac76a1..7efd132672d 100644 --- a/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc +++ b/core/config/src/main/adoc/modules/config/pages/sections/_nav.adoc @@ -8,7 +8,6 @@ ** xref:refguide:config:sections/causeway.persistence.schema.adoc[Core Persistence Schema] ** xref:refguide:config:sections/causeway.persistence.commons.adoc[Core Persistence Commons] ** xref:refguide:config:sections/causeway.prototyping.adoc[Prototyping] -** xref:refguide:config:sections/causeway.security.shiro.adoc[Shiro Security Implementation] ** xref:refguide:config:sections/causeway.security.keycloak.adoc[Keycloak Security Implementation] ** xref:refguide:config:sections/causeway.security.spring.adoc[Spring Security Implementation] ** xref:refguide:config:sections/causeway.viewer.common.adoc[Common Config for Viewers] diff --git a/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.shiro.adoc b/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.shiro.adoc deleted file mode 100644 index ecc0ff0cf10..00000000000 --- a/core/config/src/main/adoc/modules/config/pages/sections/causeway.security.shiro.adoc +++ /dev/null @@ -1,29 +0,0 @@ -= Shiro Security Implementation -:page-role: -toc -narrow - - -: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 [...] - -include::../section-hooks/causeway.security.shiro~pre.adoc[] - -[cols="3a,2a,5a", options="header"] -|=== -|Property -|Default -|Description -| -[[causeway.security.shiro.auto-logout-if-already-authenticated]] -causeway.security.shiro. + -auto-logout-if-already- + -authenticated - -| -| If the Shiro subject is found to be still authenticated, then will be logged out anyway and then re-authenticated. - -Applies only to the Restful Objects viewer. - - - -|=== - -include::../section-hooks/causeway.security.shiro~post.adoc[] diff --git a/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.adoc b/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.adoc index d73fdae1790..656387b93fb 100644 --- a/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.adoc +++ b/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.adoc @@ -18,21 +18,13 @@ The `@jakarta.annotation.Priority` annotation is used to ensure that the request |servlet? |Notes -|WebModule + -Shiro -|FIRST + 100 -|Yes -|/* -| -|Either this or spring - |WebModule + SpringSecurity |FIRST + 100 |Yes |/* | -|Either this or shiro +| |WebModule + LogOnExceptionLogger diff --git a/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.html b/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.html new file mode 100644 index 00000000000..ec0e60ee571 --- /dev/null +++ b/core/webapp/src/main/adoc/modules/webapp/pages/webmodules.html @@ -0,0 +1,851 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="UTF-8"> +<meta http-equiv="X-UA-Compatible" content="IE=edge"> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta name="generator" content="Asciidoctor 2.0.23"> +<title>WebModule interface</title> +<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> +<style> +/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ +/* Uncomment the following line when using as a custom stylesheet */ +/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */ +html{font-family:sans-serif;-webkit-text-size-adjust:100%} +a{background:none} +a:focus{outline:thin dotted} +a:active,a:hover{outline:0} +h1{font-size:2em;margin:.67em 0} +b,strong{font-weight:bold} +abbr{font-size:.9em} +abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none} +dfn{font-style:italic} +hr{height:0} +mark{background:#ff0;color:#000} +code,kbd,pre,samp{font-family:monospace;font-size:1em} +pre{white-space:pre-wrap} +q{quotes:"\201C" "\201D" "\2018" "\2019"} +small{font-size:80%} +sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} +sup{top:-.5em} +sub{bottom:-.25em} +img{border:0} +svg:not(:root){overflow:hidden} +figure{margin:0} +audio,video{display:inline-block} +audio:not([controls]){display:none;height:0} +fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} +legend{border:0;padding:0} +button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} +button,input{line-height:normal} +button,select{text-transform:none} +button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default} +input[type=checkbox],input[type=radio]{padding:0} +button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} +textarea{overflow:auto;vertical-align:top} +table{border-collapse:collapse;border-spacing:0} +*,::before,::after{box-sizing:border-box} +html,body{font-size:100%} +body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} +a:hover{cursor:pointer} +img,object,embed{max-width:100%;height:auto} +object,embed{height:100%} +img{-ms-interpolation-mode:bicubic} +.left{float:left!important} +.right{float:right!important} +.text-left{text-align:left!important} +.text-right{text-align:right!important} +.text-center{text-align:center!important} +.text-justify{text-align:justify!important} +.hide{display:none} +img,object,svg{display:inline-block;vertical-align:middle} +textarea{height:auto;min-height:50px} +select{width:100%} +.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} +div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0} +a{color:#2156a5;text-decoration:underline;line-height:inherit} +a:hover,a:focus{color:#1d4b8f} +a img{border:0} +p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} +p aside{font-size:.875em;line-height:1.35;font-style:italic} +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} +h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} +h1{font-size:2.125em} +h2{font-size:1.6875em} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} +h4,h5{font-size:1.125em} +h6{font-size:1em} +hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em} +em,i{font-style:italic;line-height:inherit} +strong,b{font-weight:bold;line-height:inherit} +small{font-size:60%;line-height:inherit} +code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} +ul,ol{margin-left:1.5em} +ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0} +ul.circle{list-style-type:circle} +ul.disc{list-style-type:disc} +ul.square{list-style-type:square} +ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit} +ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} +dl dt{margin-bottom:.3125em;font-weight:bold} +dl dd{margin-bottom:1.25em} +blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} +blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} +@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} +h1{font-size:2.75em} +h2{font-size:2.3125em} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} +h4{font-size:1.4375em}} +table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal} +table thead,table tfoot{background:#f7f8f7} +table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} +table tr.even,table tr.alt{background:#f8f8f7} +table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6} +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} +h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} +.center{margin-left:auto;margin-right:auto} +.stretch{width:100%} +.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} +.clearfix::after,.float-group::after{clear:both} +:not(pre).nobreak{word-wrap:normal} +:not(pre).nowrap{white-space:nowrap} +:not(pre).pre-wrap{white-space:pre-wrap} +:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} +pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} +pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} +pre>code{display:block} +pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} +em em{font-style:normal} +strong strong{font-weight:400} +.keyseq{color:rgba(51,51,51,.8)} +kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} +.keyseq kbd:first-child{margin-left:0} +.keyseq kbd:last-child{margin-right:0} +.menuseq,.menuref{color:#000} +.menuseq b:not(.caret),.menuref{font-weight:inherit} +.menuseq{word-spacing:-.02em} +.menuseq b.caret{font-size:1.25em;line-height:.8} +.menuseq i.caret{font-weight:bold;text-align:center;width:.45em} +b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} +b.button::before{content:"[";padding:0 3px 0 2px} +b.button::after{content:"]";padding:0 2px 0 3px} +p a>code:hover{color:rgba(0,0,0,.9)} +#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} +#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} +#header::after,#content::after,#footnotes::after,#footer::after{clear:both} +#content{margin-top:1.25em} +#content::before{content:none} +#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} +#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} +#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px} +#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap} +#header .details span:first-child{margin-left:-.125em} +#header .details span.email a{color:rgba(0,0,0,.85)} +#header .details br{display:none} +#header .details br+span::before{content:"\00a0\2013\00a0"} +#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} +#header .details br+span#revremark::before{content:"\00a0|\00a0"} +#header #revnumber{text-transform:capitalize} +#header #revnumber::after{content:"\00a0"} +#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} +#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} +#toc>ul{margin-left:.125em} +#toc ul.sectlevel0>li>a{font-style:italic} +#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} +#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} +#toc li{line-height:1.3334;margin-top:.3334em} +#toc a{text-decoration:none} +#toc a:active{text-decoration:underline} +#toctitle{color:#7a2518;font-size:1.2em} +@media screen and (min-width:768px){#toctitle{font-size:1.375em} +body.toc2{padding-left:15em;padding-right:0} +body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} +#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} +#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} +#toc.toc2>ul{font-size:.9em;margin-bottom:0} +#toc.toc2 ul ul{margin-left:0;padding-left:1em} +#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} +body.toc2.toc-right{padding-left:0;padding-right:15em} +body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} +@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} +#toc.toc2{width:20em} +#toc.toc2 #toctitle{font-size:1.375em} +#toc.toc2>ul{font-size:.95em} +#toc.toc2 ul ul{padding-left:1.25em} +body.toc2.toc-right{padding-left:0;padding-right:20em}} +#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px} +#content #toc>:first-child{margin-top:0} +#content #toc>:last-child{margin-bottom:0} +#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em} +#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44} +#content{margin-bottom:.625em} +.sect1{padding-bottom:.625em} +@media screen and (min-width:768px){#content{margin-bottom:1.25em} +.sect1{padding-bottom:1.25em}} +.sect1:last-child{padding-bottom:0} +.sect1+.sect1{border-top:1px solid #e7e7e9} +#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} +#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} +#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} +#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} +#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} +details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} +details{margin-left:1.25rem} +details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent} +details>summary::-webkit-details-marker{display:none} +details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)} +details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)} +details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem} +.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} +table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} +.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} +.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} +.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:none} +.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} +.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} +.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} +.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px} +.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px} +.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} +.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0} +.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol> [...] +.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} +@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} +@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} +.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} +.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} +.listingblock>.content{position:relative} +.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} +.listingblock:hover code[data-lang]::before{display:block} +.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} +.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} +.listingblock pre.highlightjs{padding:0} +.listingblock pre.highlightjs>code{padding:1em;border-radius:4px} +.listingblock pre.prettyprint{border-width:0} +.prettyprint{background:#f7f7f8} +pre.prettyprint .linenums{line-height:1.45;margin-left:2em} +pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0} +pre.prettyprint li code[data-lang]::before{opacity:1} +pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none} +table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none} +table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal} +table.linenotable td.code{padding-left:.75em} +table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} +pre.pygments span.linenos{display:inline-block;margin-right:.75em} +.quoteblock{margin:0 1em 1.25em 1.5em;display:table} +.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em} +.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} +.quoteblock blockquote{margin:0;padding:0;border:0} +.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} +.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} +.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} +.verseblock{margin:0 1em 1.25em} +.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400} +.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} +.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} +.quoteblock .attribution br,.verseblock .attribution br{display:none} +.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} +.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} +.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0} +.quoteblock.abstract{margin:0 1em 1.25em;display:block} +.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} +.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf} +.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0} +.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} +.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0} +p.tableblock:last-child{margin-bottom:0} +td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere} +td.tableblock>.content>:last-child{margin-bottom:-1.25em} +table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} +table.grid-all>*>tr>*{border-width:1px} +table.grid-cols>*>tr>*{border-width:0 1px} +table.grid-rows>*>tr>*{border-width:1px 0} +table.frame-all{border-width:1px} +table.frame-ends{border-width:1px 0} +table.frame-sides{border-width:0 1px} +table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0} +table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0} +table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0} +table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0} +table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7} +th.halign-left,td.halign-left{text-align:left} +th.halign-right,td.halign-right{text-align:right} +th.halign-center,td.halign-center{text-align:center} +th.valign-top,td.valign-top{vertical-align:top} +th.valign-bottom,td.valign-bottom{vertical-align:bottom} +th.valign-middle,td.valign-middle{vertical-align:middle} +table thead th,table tfoot th{font-weight:bold} +tbody tr th{background:#f7f8f7} +tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} +p.tableblock>code:only-child{background:none;padding:0} +p.tableblock{font-size:1em} +ol{margin-left:1.75em} +ul li ol{margin-left:1.5em} +dl dd{margin-left:1.125em} +dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} +li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} +ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} +ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} +ul.unstyled,ol.unstyled{margin-left:0} +li>p:empty:only-child::before{content:"";display:inline-block} +ul.checklist>li>p:first-child{margin-left:-1em} +ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} +ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em} +ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} +ul.inline>li{margin-left:1.25em} +.unstyled dl dt{font-weight:400;font-style:normal} +ol.arabic{list-style-type:decimal} +ol.decimal{list-style-type:decimal-leading-zero} +ol.loweralpha{list-style-type:lower-alpha} +ol.upperalpha{list-style-type:upper-alpha} +ol.lowerroman{list-style-type:lower-roman} +ol.upperroman{list-style-type:upper-roman} +ol.lowergreek{list-style-type:lower-greek} +.hdlist>table,.colist>table{border:0;background:none} +.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} +td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} +td.hdlist1{font-weight:bold;padding-bottom:1.25em} +td.hdlist2{word-wrap:anywhere} +.literalblock+.colist,.listingblock+.colist{margin-top:-.5em} +.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} +.colist td:not([class]):first-child img{max-width:none} +.colist td:not([class]):last-child{padding:.25em 0} +.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd} +.imageblock.left{margin:.25em .625em 1.25em 0} +.imageblock.right{margin:.25em 0 1.25em .625em} +.imageblock>.title{margin-bottom:0} +.imageblock.thumb,.imageblock.th{border-width:6px} +.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} +.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} +.image.left{margin-right:.625em} +.image.right{margin-left:.625em} +a.image{text-decoration:none;display:inline-block} +a.image object{pointer-events:none} +sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} +sup.footnote a,sup.footnoteref a{text-decoration:none} +sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline} +#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} +#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} +#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} +#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} +#footnotes .footnote:last-of-type{margin-bottom:0} +#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} +div.unbreakable{page-break-inside:avoid} +.big{font-size:larger} +.small{font-size:smaller} +.underline{text-decoration:underline} +.overline{text-decoration:overline} +.line-through{text-decoration:line-through} +.aqua{color:#00bfbf} +.aqua-background{background:#00fafa} +.black{color:#000} +.black-background{background:#000} +.blue{color:#0000bf} +.blue-background{background:#0000fa} +.fuchsia{color:#bf00bf} +.fuchsia-background{background:#fa00fa} +.gray{color:#606060} +.gray-background{background:#7d7d7d} +.green{color:#006000} +.green-background{background:#007d00} +.lime{color:#00bf00} +.lime-background{background:#00fa00} +.maroon{color:#600000} +.maroon-background{background:#7d0000} +.navy{color:#000060} +.navy-background{background:#00007d} +.olive{color:#606000} +.olive-background{background:#7d7d00} +.purple{color:#600060} +.purple-background{background:#7d007d} +.red{color:#bf0000} +.red-background{background:#fa0000} +.silver{color:#909090} +.silver-background{background:#bcbcbc} +.teal{color:#006060} +.teal-background{background:#007d7d} +.white{color:#bfbfbf} +.white-background{background:#fafafa} +.yellow{color:#bfbf00} +.yellow-background{background:#fafa00} +span.icon>.fa{cursor:default} +a span.icon>.fa{cursor:inherit} +.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} +.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} +.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} +.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} +.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} +.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} +.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} +.conum[data-value] *{color:#fff!important} +.conum[data-value]+b{display:none} +.conum[data-value]::after{content:attr(data-value)} +pre .conum[data-value]{position:relative;top:-.125em} +b.conum *{color:inherit!important} +.conum:not([data-value]):empty{display:none} +dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} +h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em} +p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} +p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem} +p{margin-bottom:1.25rem} +.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} +.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc} +.print-only{display:none!important} +@page{margin:1.25cm .75cm} +@media print{*{box-shadow:none!important;text-shadow:none!important} +html{font-size:80%} +a{color:inherit!important;text-decoration:underline!important} +a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} +a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} +abbr[title]{border-bottom:1px dotted} +abbr[title]::after{content:" (" attr(title) ")"} +pre,blockquote,tr,img,object,svg{page-break-inside:avoid} +thead{display:table-header-group} +svg{max-width:100%} +p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} +h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} +#header,#content,#footnotes,#footer{max-width:none} +#toc,.sidebarblock,.exampleblock>.content{background:none!important} +#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} +body.book #header{text-align:center} +body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} +body.book #header .details{border:0!important;display:block;padding:0!important} +body.book #header .details span:first-child{margin-left:0!important} +body.book #header .details br{display:block} +body.book #header .details br+span::before{content:none!important} +body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} +body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} +.listingblock code[data-lang]::before{display:block} +#footer{padding:0 .9375em} +.hide-on-print{display:none!important} +.print-only{display:block!important} +.hide-for-print{display:none!important} +.show-for-print{display:inherit!important}} +@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem} +.sect1{padding:0!important} +.sect1+.sect1{border:0} +#footer{background:none} +#footer-text{color:rgba(0,0,0,.6);font-size:.9em}} +@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} +</style> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/styles/github.min.css"> +<style> +/*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */ +.tabs { + margin-bottom: 1.25em; +} + +.tablist > ul { + display: flex; + flex-wrap: wrap; + list-style: none; + margin: 0; + padding: 0; +} + +.tablist > ul li { + align-items: center; + background-color: #fff; + cursor: pointer; + display: flex; + font-weight: bold; + line-height: 1.5; + padding: 0.25em 1em; + position: relative; +} + +.tablist > ul li:focus-visible { + outline: none; +} + +.tablist.ulist, +.tablist.ulist > ul li { + margin: 0; +} + +.tablist.ulist > ul li + li { + margin-left: 0.25em; +} + +.tabs .tablist li::after { + content: ""; + display: block; + height: 1px; + position: absolute; + bottom: -1px; + left: 0; + right: 0; +} + +.tabs.is-loading .tablist li:not(:first-child), +.tabs:not(.is-loading) .tablist li:not(.is-selected) { + background-color: #f5f5f5; +} + +.tabs.is-loading .tablist li:first-child::after, +.tabs:not(.is-loading) .tablist li.is-selected::after { + background-color: #fff; +} + +/* +.tabs:not(.is-loading) .tablist li, +.tabs:not(.is-loading) .tablist li::after { + transition: background-color 200ms ease-in-out; +} +*/ + +.tablist > ul p { + line-height: inherit; + margin: 0; +} + +.tabpanel { + background-color: #fff; + padding: 1.25em; +} + +.tablist > ul li, +.tabpanel { + border: 1px solid #dcdcdc; +} + +.tablist > ul li { + border-bottom: 0; +} + +.tabs.is-loading .tabpanel + .tabpanel, +.tabs:not(.is-loading) .tabpanel.is-hidden { + display: none; +} + +.tabpanel > :first-child { + margin-top: 0; +} + +/* #content is a signature of the Asciidoctor standalone HTML output */ +#content .tabpanel > :last-child, +#content .tabpanel > :last-child > :last-child, +#content .tabpanel > :last-child > :last-child > li:last-child > :last-child { + margin-bottom: 0; +} + +.tablecontainer { + overflow-x: auto; +} + +#content .tablecontainer { + margin-bottom: 1.25em; +} + +#content .tablecontainer > table.tableblock { + margin-bottom: 0; +} +</style> +</head> +<body id="webmodule-interface" class="article"> +<div id="header"> +<h1><code>WebModule</code> interface</h1> +</div> +<div id="content"> +<div class="paragraph"> +<p>The <code>WebModule</code> interface allows modules to dynamically configure <code>Filter</code>s, <code>Servlet</code>s and <code>ServletContextListener</code>s. +The <code>@jakarta.annotation.Priority</code> annotation is used to ensure that the request chain is sequenced correctly.</p> +</div> +<table class="tableblock frame-all grid-all stretch"> +<caption class="title">Table 1. WebModules (priority determines filter sequence, earliest first)</caption> +<colgroup> +<col style="width: 23.0769%;"> +<col style="width: 15.3846%;"> +<col style="width: 7.6923%;"> +<col style="width: 11.5384%;"> +<col style="width: 11.5384%;"> +<col style="width: 30.7694%;"> +</colgroup> +<thead> +<tr> +<th class="tableblock halign-left valign-top">Web module</th> +<th class="tableblock halign-center valign-top"><code>@Priority</code></th> +<th class="tableblock halign-center valign-top">listener?</th> +<th class="tableblock halign-center valign-top">filter?</th> +<th class="tableblock halign-center valign-top">servlet?</th> +<th class="tableblock halign-left valign-top">Notes</th> +</tr> +</thead> +<tbody> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +Shiro</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>FIRST + 100</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>Yes</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/*</code></p></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>Either this or spring</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +SpringSecurity</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>FIRST + 100</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>Yes</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/*</code></p></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>Either this or shiro</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +LogOnExceptionLogger</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>EARLY - 100</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/wicket<br> +/restful</code></p></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>Filter is passthru, with no side-effects.<br> +Mapping depends on which viewers configured.</p> +</div> +<div class="paragraph"> +<p>Although priority is relatively early, the filter is registered to be last in pipeline.</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +Cors</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>EARLY</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/wicket<br> +/restful</code></p></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>Mapping depends on which viewers configured.</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +TemplateResources</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>MIDPOINT - 100</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>*.thtml</code></p></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>*.thtml</code></p></td> +<td class="tableblock halign-left valign-top"><div class="content"></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +JaxrsResteasy4</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>MIDPOINT - 80</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>Yes</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/restful</code></p></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/restful</code></p></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>Filters mapped to servlet</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +Wicket</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>MIDPOINT - 80</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/wicket</code></p></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-left valign-top"><div class="content"></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +ServerSentEvents</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>MIDPOINT</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/sse</code></p></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>servlet only, so priority doesn’t really matter.</p> +</div></div></td> +</tr> +<tr> +<td class="tableblock halign-left valign-top"><p class="tableblock"><code>WebModule<br> +H2Console</code></p></td> +<td class="tableblock halign-center valign-top"><div class="content"><div class="paragraph"> +<p>MIDPOINT</p> +</div></div></td> +<td class="tableblock halign-center valign-top"><div class="content"></div></td> +<td class="tableblock halign-center valign-top"></td> +<td class="tableblock halign-center valign-top"><p class="tableblock"><code>/db/*</code></p></td> +<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph"> +<p>servlet only, so priority doesn’t really matter.</p> +</div></div></td> +</tr> +</tbody> +</table> +</div> +<div id="footer"> +<div id="footer-text"> +Last updated 2025-10-18 09:04:11 +0100 +</div> +</div> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script> +<script> +if (!hljs.initHighlighting.called) { + hljs.initHighlighting.called = true + ;[].slice.call(document.querySelectorAll('pre.highlight > code[data-lang]')).forEach(function (el) { hljs.highlightBlock(el) }) +} +</script> +<script> +;(function () { /*! Asciidoctor Tabs | Copyright (c) 2018-present Dan Allen | MIT License */ + 'use strict' + + var config = (document.currentScript || {}).dataset || {} + var forEach = Array.prototype.forEach + + init(document.querySelectorAll('.tabs')) + + function init (tabsBlocks) { + if (!tabsBlocks.length) return + forEach.call(tabsBlocks, function (tabs) { + var syncIds = tabs.classList.contains('is-sync') ? {} : undefined + var tablist = tabs.querySelector('.tablist ul') + tablist.setAttribute('role', 'tablist') + var start + forEach.call(tablist.querySelectorAll('li'), function (tab, idx) { + tab.tabIndex = -1 + tab.setAttribute('role', tab.classList.add('tab') || 'tab') + var id, anchor, syncId + if (!(id = tab.id) && (anchor = tab.querySelector('a[id]'))) { + id = tab.id = anchor.parentNode.removeChild(anchor).id + } + var panel = id && tabs.querySelector('.tabpanel[aria-labelledby~="' + id + '"]') + if (!panel) return idx ? undefined : toggleSelected(tab, true) // invalid state + syncIds && (((syncId = tab.textContent.trim()) in syncIds) ? (syncId = undefined) : true) && + (syncIds[(tab.dataset.syncId = syncId)] = tab) + idx || (syncIds && (start = { tab: tab, panel: panel })) ? toggleHidden(panel, true) : toggleSelected(tab, true) + tab.setAttribute('aria-controls', panel.id) + panel.setAttribute('role', 'tabpanel') + var onClick = syncId === undefined ? activateTab : activateTabSync + tab.addEventListener('click', onClick.bind({ tabs: tabs, tab: tab, panel: panel })) + }) + if (!tabs.closest('.tabpanel')) { + forEach.call(tabs.querySelectorAll('.tabpanel table.tableblock'), function (table) { + var container = Object.assign(document.createElement('div'), { className: 'tablecontainer' }) + table.parentNode.insertBefore(container, table).appendChild(table) + }) + } + if (start) { + var syncGroupId + for (var i = 0, lst = tabs.classList, len = lst.length, className; i !== len; i++) { + if (!(className = lst.item(i)).startsWith('data-sync-group-id=')) continue + tabs.dataset.syncGroupId = syncGroupId = lst.remove(className) || className.slice(19).replace(/\u00a0/g, ' ') + break + } + if (syncGroupId === undefined) tabs.dataset.syncGroupId = syncGroupId = Object.keys(syncIds).sort().join('|') + var preferredSyncId = 'syncStorageKey' in config && + window[(config.syncStorageScope || 'local') + 'Storage'].getItem(config.syncStorageKey + '-' + syncGroupId) + var tab = preferredSyncId && syncIds[preferredSyncId] + tab && Object.assign(start, { tab: tab, panel: document.getElementById(tab.getAttribute('aria-controls')) }) + toggleSelected(start.tab, true) || toggleHidden(start.panel, false) + } + }) + onHashChange() + toggleClassOnEach(tabsBlocks, 'is-loading', 'remove') + window.setTimeout(toggleClassOnEach.bind(null, tabsBlocks, 'is-loaded', 'add'), 0) + window.addEventListener('hashchange', onHashChange) + } + + function activateTab (e) { + var tab = this.tab + var tabs = this.tabs || (this.tabs = tab.closest('.tabs')) + var panel = this.panel || (this.panel = document.getElementById(tab.getAttribute('aria-controls'))) + querySelectorWithSiblings(tabs, '.tablist .tab', 'tab').forEach(function (el) { + toggleSelected(el, el === tab) + }) + querySelectorWithSiblings(tabs, '.tabpanel', 'tabpanel').forEach(function (el) { + toggleHidden(el, el !== panel) + }) + if (!this.isSync && 'syncStorageKey' in config && 'syncGroupId' in tabs.dataset) { + var storageKey = config.syncStorageKey + '-' + tabs.dataset.syncGroupId + window[(config.syncStorageScope || 'local') + 'Storage'].setItem(storageKey, tab.dataset.syncId) + } + if (!e) return + var loc = window.location + var hashIdx = loc.hash ? loc.href.indexOf('#') : -1 + if (~hashIdx) window.history.replaceState(null, '', loc.href.slice(0, hashIdx)) + e.preventDefault() + } + + function activateTabSync (e) { + activateTab.call(this, e) + var thisTabs = this.tabs + var thisTab = this.tab + var initialY = thisTabs.getBoundingClientRect().y + forEach.call(document.querySelectorAll('.tabs'), function (tabs) { + if (tabs === thisTabs || tabs.dataset.syncGroupId !== thisTabs.dataset.syncGroupId) return + querySelectorWithSiblings(tabs, '.tablist .tab', 'tab').forEach(function (tab) { + if (tab.dataset.syncId === thisTab.dataset.syncId) activateTab.call({ tabs: tabs, tab: tab, isSync: true }) + }) + }) + var shiftedBy = thisTabs.getBoundingClientRect().y - initialY + if (shiftedBy && (shiftedBy = Math.round(shiftedBy))) window.scrollBy({ top: shiftedBy, behavior: 'instant' }) + } + + function querySelectorWithSiblings (scope, selector, siblingClass) { + var el = scope.querySelector(selector) + if (!el) return [] + var result = [el] + while ((el = el.nextElementSibling) && el.classList.contains(siblingClass)) result.push(el) + return result + } + + function toggleClassOnEach (elements, className, method) { + forEach.call(elements, function (el) { + el.classList[method](className) + }) + } + + function toggleHidden (el, state) { + el.classList[(el.hidden = state) ? 'add' : 'remove']('is-hidden') + } + + function toggleSelected (el, state) { + el.setAttribute('aria-selected', '' + state) + el.classList[state ? 'add' : 'remove']('is-selected') + el.tabIndex = state ? 0 : -1 + } + + function onHashChange () { + var id = window.location.hash.slice(1) + if (!id) return + var tab = document.getElementById(~id.indexOf('%') ? decodeURIComponent(id) : id) + if (!(tab && tab.classList.contains('tab'))) return + 'syncId' in tab.dataset ? activateTabSync.call({ tab: tab }) : activateTab.call({ tab: tab }) + } +})() +</script> +</body> +</html> \ No newline at end of file diff --git a/extensions/security/secman/adoc/modules/secman/images/secman-shiro-architecture.drawio.svg b/extensions/security/secman/adoc/modules/secman/images/secman-shiro-architecture.drawio.svg deleted file mode 100644 index 075789aafa5..00000000000 --- a/extensions/security/secman/adoc/modules/secman/images/secman-shiro-architecture.drawio.svg +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Do not edit this file with editors other than diagrams.net --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="561px" height="501px" viewBox="-0.5 -0.5 561 501" content="<mxfile host="drawio-plugin" modified="2023-03-12T12:17:36.085Z" agent="5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36" etag="ICZ1pFXdRWcyuA63m1Up" version="20.5.3" type="embed"><diagram id="Y7d [...] \ No newline at end of file diff --git a/extensions/security/secman/adoc/modules/secman/images/secman-shiro-delegate-architecture.drawio.svg b/extensions/security/secman/adoc/modules/secman/images/secman-shiro-delegate-architecture.drawio.svg deleted file mode 100644 index 296eb55387a..00000000000 --- a/extensions/security/secman/adoc/modules/secman/images/secman-shiro-delegate-architecture.drawio.svg +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Do not edit this file with editors other than diagrams.net --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="626px" height="301px" viewBox="-0.5 -0.5 626 301" content="<mxfile host="drawio-plugin" modified="2023-03-12T12:34:27.216Z" agent="5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36" etag="uTJLy7pY6FNuKWcGzEC7" version="20.5.3" type="embed"><diagram id="Y7d [...] \ No newline at end of file diff --git a/extensions/security/secman/adoc/modules/secman/pages/about.adoc b/extensions/security/secman/adoc/modules/secman/pages/about.adoc index 7c70267540d..59f21d927a0 100644 --- a/extensions/security/secman/adoc/modules/secman/pages/about.adoc +++ b/extensions/security/secman/adoc/modules/secman/pages/about.adoc @@ -17,7 +17,6 @@ Permissions can be defined at different scopes, and can either allow or veto acc The set of permissions (to features) is derived completely from your application's metamodel; in essence the permissions are "type-safe". SecMan can be used just for authorization, or it can be used in conjunction with any of the other xref:refguide:core:index/security/authentication/Authenticator.adoc[Authenticator] implementations, for example xref:security:spring:about.adoc[Spring] or xref:security:keycloak:about.adoc[Keycloak]. -This integration is discussed in more detail <<shiro-integration,below>>. == Users, Roles and Permissions @@ -218,7 +217,6 @@ Secman leverages Spring's `org.springframework.security.crypto.password.Password The `encryption-jbcrypt` module provides an implementation using the link:https://www.mindrot.org/projects/jBCrypt/[jBCrypt] library. -[#shiro-integration] == Using other Authenticators While SecMan does provide an implementation of the xref:refguide:core:index/security/authentication/Authenticator.adoc[] SPI, it's also possible to use an alternative `Authenticator` implementation; for example as provided by: @@ -231,7 +229,6 @@ for more details, see xref:setting-up-with-spring-oauth2.adoc[] + for more details, see xref:setting-up-with-keycloak.adoc[] - Secman is still responsible for authorization. == SecMan's structure @@ -246,7 +243,5 @@ As you might expect, they are intended for use with xref:pjpa:ROOT:about.adoc[JP * the Model module (`causeway-extensions-secman-model`) defines view models to represent the feature application features, and also contains business logic as mixins to the API (and therefore contributed to the appropriate concrete entity). -* the Shiro realm module (`causeway-extensions-secman-shiro-realm`) provides the Shiro realm interface that delegates to the Secman database (see discussion <<shiro-integration,above>>) - * the jbcrypt encryption module (`causeway-extensions-secman-encryption-jbcrypt`) provides an implementation of Spring's `org.springframework.security.crypto.password.PasswordEncoder` SPI so that passwords are persisted securely using link:https://www.mindrot.org/projects/jBCrypt/[jBCrypt]. diff --git a/extensions/security/secman/adoc/modules/secman/pages/setting-up.adoc b/extensions/security/secman/adoc/modules/secman/pages/setting-up.adoc index 2c460e7ac56..50eb219d1e6 100644 --- a/extensions/security/secman/adoc/modules/secman/pages/setting-up.adoc +++ b/extensions/security/secman/adoc/modules/secman/pages/setting-up.adoc @@ -79,13 +79,6 @@ public class AppManifest { <.> use Jbcrypt to encrypt passwords <.> fixture script support -In addition, you will probably want to *remove* the `CausewayModuleSecurityShiro.class` dependency so that SecMan can take care of both authentication _and_ authorisation. - -[NOTE] -==== -It also possible to use SecMan in conjunction with Shiro, as described xref:setting-up-with-shiro.adoc[here]. -The primary use case is to support delegated users that Shiro authenticates externally using LDAP, for example. -==== [#configure-properties] == Configuration Properties @@ -368,7 +361,7 @@ public class UserToRole__bob_allRoles extends AbstractUserAndRolesFixtureScript The password is encrypted, not stored in plain text. <.> email address <.> application tenancy -<.> local account (rather than delegated, see xref:setting-up-with-shiro.adoc[]) +<.> local account (rather than delegated, see xref:setting-up-with-spring-oauth2.adoc[] or xref:setting-up-with-keycloak.adoc[]). <.> application-specific roles <.> regular user access (always required). *Note* that this expects that the default regular user role has been left as its default value. diff --git a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/AccountType.java b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/AccountType.java index 4ef17ffb503..3f897e98b89 100644 --- a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/AccountType.java +++ b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/AccountType.java @@ -21,14 +21,20 @@ import org.apache.causeway.commons.internal.base._Strings; /** - * Whether the user's account is local enabled (user/password) or - * delegated (eg LDAP), as per - * {@code org.apache.causeway.extensions.secman.shiro.CausewayModuleExtSecmanShiroRealm#setDelegateAuthenticationRealm(org.apache.shiro.realm.AuthenticatingRealm)}. + * Whether the user's account is defined by locally (Secman itself is the authenticator) or instead if there's a + * different security module that has responsibility for authentication (for example Spring Security with OAuth2). + * This is the delegate model. * * @since 2.0 {@index} */ public enum AccountType { + /** + * Secman itself is the authenticator. + */ LOCAL, + /** + * Another security module performs the primary authentication, for example Spring Security with OAuth2. + */ DELEGATED; public boolean isLocal() { diff --git a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/ApplicationUser.java b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/ApplicationUser.java index ca9bca6c637..a7680326adb 100644 --- a/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/ApplicationUser.java +++ b/extensions/security/secman/applib/src/main/java/org/apache/causeway/extensions/secman/applib/user/dom/ApplicationUser.java @@ -633,10 +633,9 @@ class Persistence { for (final RoleMemento role : currentUser.roles()) { final String roleName = role.name(); if(adminRoleName.equals(roleName)) return true; - - // format could also be realmName:roleName, eg. with Shiro - // since we don't know what the realm's name is (depends on its configuration in shiro.ini), - // simply check that the last part matches the role name. + // format might also be realmName:roleName + // since we don't know what the realm's name, + // we simply check that the last part matches the role name. if(roleName.endsWith(adminRoleSuffix)) return true; } return false; diff --git a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/authorizor/AuthorizorSecman.java b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/authorizor/AuthorizorSecman.java index 6e76deee697..294e38b29c5 100644 --- a/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/authorizor/AuthorizorSecman.java +++ b/extensions/security/secman/integration/src/main/java/org/apache/causeway/extensions/secman/integration/authorizor/AuthorizorSecman.java @@ -50,17 +50,6 @@ import org.jspecify.annotations.NonNull; /** - * <p> - * Note that this service has an earlier precedence than <code>AuthorizorShiro</code>. - * Conversely, <code>AuthenticatorShiro</code> overrides - * {@link org.apache.causeway.extensions.secman.integration.authenticator.AuthenticatorSecman}. - * </p> - * - * <p> - * Therefore if both shiro and secman are configured, then shiro will be used for authentication, while secman will be - * used for authorization. - * </p> - * * @since 2.0 {@index} */ @Service diff --git a/extensions/security/spring-oauth2/src/main/adoc/modules/spring-oauth2/pages/about.adoc b/extensions/security/spring-oauth2/src/main/adoc/modules/spring-oauth2/pages/about.adoc index 17854602a10..529fa854ade 100644 --- a/extensions/security/spring-oauth2/src/main/adoc/modules/spring-oauth2/pages/about.adoc +++ b/extensions/security/spring-oauth2/src/main/adoc/modules/spring-oauth2/pages/about.adoc @@ -5,7 +5,9 @@ This guide describes the integration of Spring security's OAuth2 client. -Authentication is done via OAuth2 and authorization via either Shiro or Secman. +Authentication is done via OAuth2 and authorization can be done using another implementation, typically using xref:security:secman:about.adoc[Secman security] module (with roles/permissions defined as domain entities). +But if the roles/permissions are static then using the xref:security:simple:about.adoc[Simple security] module is another alternative. +We show both integrations on this page. include::docs:mavendeps:partial$setup-and-configure-dependencyManagement.adoc[leveloffset=+1] @@ -37,7 +39,7 @@ Using this, it provides an implementation of the xref:security:spring:about.adoc [#walk-through-oauth2] -== Walk-through (Oauth with Github and Shiro authorizor) +== Walk-through (Oauth with Github and Simple authorizor) Using Spring Security we can configure your app with various authentication providers. In this section we describe how to modify the xref:docs:starters:helloworld.adoc[HelloWorld] starter app to use link:https://github.com[github] as an OAuth2 provider. @@ -55,32 +57,66 @@ In your application's xref:userguide::modules.adoc#appmanifest[App Manifest], im @Import({ ... CausewayModuleExtSpringSecurityOAuth2.class, // <.> - AuthorizorShiro.class, // <.> + SimpleAuthorizor.class, // <.> ... }) public class AppManifest { } ---- <.> The `CausewayModuleExtSpringSecurityOAuth2` module brings in a transitive dependency on `CausewayModuleSecuritySpring`. -<.> An implementation of `Authorizor` is also required. -For the purpose of this walkthrough, we'll use the implementation provided by xref:security:shiro:about.adoc[Shiro], namely `AuthorizorShiro`. +Add in the corresponding Maven dependency: + +[source,xml,subs="attributes+"] +.pom.xml +---- +<dependencies> + ... + <dependency> + <groupId>org.apache.causeway.extensions</groupId> + <artifactId>causeway-extensions-spring-security-oauth2</artifactId> + + <version>{page-causewayreleaseversion}</version> + </dependency> + ... +</dependencies> +---- + +To use the Simple authorizor, add in a reference to its authorizor: + +[source,java] +.AppManifest.java +---- +@Configuration +@Import({ + ... + CausewayModuleExtSpringSecurityOAuth2.class, + SimpleAuthorizor.class, // <.> + ... +}) +public class AppManifest { +} +---- +<.> reference `SimpleAuthorizor` directly. ++ [IMPORTANT] ==== -Make sure that no other `CausewayModuleSecurityXxx` module is imported, either directly or indirectly. +We do _not_ reference all of `CausewayModuleSecuritySimple` module, as that would bring in the `SimpleAuthenticator` service, which we don't require. ==== -To use the Shiro authorizor, also add in the corresponding dependency: +We also need to add a dependency in Maven: [source,xml,subs="attributes+"] .pom.xml ---- <dependencies> + ... <dependency> <groupId>org.apache.causeway.security</groupId> - <artifactId>causeway-security-shiro</artifactId> + <artifactId>causeway-security-simple</artifactId> <version>{page-causewayreleaseversion}</version> </dependency> + ... </dependencies> ---- @@ -135,31 +171,39 @@ Next, add in `LoginController` to the `AppManifest`. @Import({ ... CausewayModuleExtSpringSecurityOAuth2.class, - AuthorizorShiro.class, + SimpleAuthorizor.class, LoginController.class, ... }) public class AppManifest { + } ---- -Next configure authenticationStrategy and permissionResolver for realms, and add the userId: +=== Configure permissions -[source,ini] -.shiro.ini +With xref:security:simple:about.adoc[Simple] security module, roles and permissions are provided by a `SimpleRealm` service. +This can be created for example as a bean within `AppManifest`: + +[source,java] +.AppManifest.java ---- -[main] -authenticationStrategy=org.apache.causeway.extensions.secman.delegated.shiro.realm.AuthenticationStrategyForSecMan -securityManager.authenticator.authenticationStrategy = $authenticationStrategy -securityManager.realms = $iniRealm -permissionResolver = org.apache.causeway.security.shiro.authorization.CausewayPermissionResolver -iniRealm.permissionResolver = $permissionResolver -... -[users] -... -your.id = ,admin_role -... +// ... +public class AppManifest { + + @Bean + public SimpleRealm realm() { // <.> + String unusedPassword = null; + return new SimpleRealm() + .addRole("admin_role", id->Grant.CHANGE) + .addUser("[email protected]", unusedPassword, List.of("admin_role")) +; + } +} ---- +<.> return a realm of required roles and permissions + +Consult the xref:security:simple:about.adoc[Simple] security module documentation for further details on creating a `SimpleRealm`. Lastly (and optionally), the swagger/REST API is not configured for oauth2, so we replace the `index.html` page with one to redirect straight to the xref:vw::about.adoc[Wicket Viewer]: @@ -269,7 +313,7 @@ public class AppManifest { // ... } ---- -<.> Using secman for permissions (rather than Shiro, as was described in the xref:#walk-through-oauth2[github walkthrough] above) +<.> Using secman for permissions <.> We'll use Spring APIs to configure the authentication flows For the purpose of this walkthrough, we'll use the implementation provided by xref:security:secman:setting-up-with-spring-oauth2.adoc[SecMan]. diff --git a/regressiontests/incubating/pom.xml b/regressiontests/incubating/pom.xml index a742c1b3e9e..e646c23af3d 100644 --- a/regressiontests/incubating/pom.xml +++ b/regressiontests/incubating/pom.xml @@ -64,12 +64,6 @@ <scope>test</scope> </dependency> - <dependency> - <groupId>org.apache.causeway.security</groupId> - <artifactId>causeway-security-shiro</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.apache.causeway.extensions</groupId> <artifactId>causeway-extensions-secman-integration</artifactId> @@ -94,12 +88,6 @@ <scope>test</scope> </dependency> - <dependency> - <groupId>org.apache.causeway.extensions</groupId> - <artifactId>causeway-extensions-secman-delegated-shiro</artifactId> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-test-framework</artifactId> diff --git a/regressiontests/incubating/src/test/resources/shiro-secman-ldap-cached.ini b/regressiontests/incubating/src/test/resources/shiro-secman-ldap-cached.ini deleted file mode 100644 index da9f9ddbf3b..00000000000 --- a/regressiontests/incubating/src/test/resources/shiro-secman-ldap-cached.ini +++ /dev/null @@ -1,55 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -[main] - -contextFactory = org.apache.causeway.extensions.shirorealmldap.realm.impl.CausewayLdapContextFactory -contextFactory.url = ldap://localhost:10389 -contextFactory.authenticationMechanism = simple -contextFactory.systemAuthenticationMechanism = simple -contextFactory.systemUsername = uid=admin,ou=system -contextFactory.systemPassword = secret - -ldapRealm = org.apache.causeway.extensions.shirorealmldap.realm.impl.CausewayLdapRealm -ldapRealm.contextFactory = $contextFactory -ldapRealm.searchBase = ou=groups,o=mojo -ldapRealm.groupObjectClass = groupOfUniqueNames -ldapRealm.uniqueMemberAttribute = uniqueMember -ldapRealm.uniqueMemberAttributeValueTemplate = uid={0} - -authenticationStrategy=org.apache.causeway.extensions.secman.delegated.shiro.realm.AuthenticationStrategyForSecMan -causewayModuleSecurityRealm=org.apache.causeway.extensions.secman.delegated.shiro.realm.CausewayModuleExtSecmanShiroRealm -causewayModuleSecurityRealm.delegateAuthenticationRealm=$ldapRealm -causewayModuleSecurityRealm.authenticationCachingEnabled = true - -cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager - -securityManager.authenticator.authenticationStrategy = $authenticationStrategy -securityManager.realms = $causewayModuleSecurityRealm -securityManager.cacheManager = $cacheManager - -[users] -# unused - -[roles] -# unused - - - - diff --git a/regressiontests/incubating/src/test/resources/shiro-secman-ldap.ini b/regressiontests/incubating/src/test/resources/shiro-secman-ldap.ini deleted file mode 100644 index 338714a551e..00000000000 --- a/regressiontests/incubating/src/test/resources/shiro-secman-ldap.ini +++ /dev/null @@ -1,51 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -[main] - -contextFactory = org.apache.causeway.extensions.shirorealmldap.realm.impl.CausewayLdapContextFactory -contextFactory.url = ldap://localhost:10389 -contextFactory.authenticationMechanism = simple -contextFactory.systemAuthenticationMechanism = simple -contextFactory.systemUsername = uid=admin,ou=system -contextFactory.systemPassword = secret - -ldapRealm = org.apache.causeway.extensions.shirorealmldap.realm.impl.CausewayLdapRealm -ldapRealm.contextFactory = $contextFactory -ldapRealm.searchBase = ou=groups,o=mojo -ldapRealm.groupObjectClass = groupOfUniqueNames -ldapRealm.uniqueMemberAttribute = uniqueMember -ldapRealm.uniqueMemberAttributeValueTemplate = uid={0} - -authenticationStrategy=org.apache.causeway.extensions.secman.delegated.shiro.realm.AuthenticationStrategyForSecMan -causewayModuleSecurityRealm=org.apache.causeway.extensions.secman.delegated.shiro.realm.CausewayModuleExtSecmanShiroRealm -causewayModuleSecurityRealm.delegateAuthenticationRealm=$ldapRealm - -securityManager.authenticator.authenticationStrategy = $authenticationStrategy -securityManager.realms = $causewayModuleSecurityRealm - -[users] -# unused - -[roles] -# unused - - - - diff --git a/regressiontests/incubating/src/test/resources/shiro-secman.ini b/regressiontests/incubating/src/test/resources/shiro-secman.ini deleted file mode 100644 index 59085f0c100..00000000000 --- a/regressiontests/incubating/src/test/resources/shiro-secman.ini +++ /dev/null @@ -1,31 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -[main] - -authenticationStrategy=org.apache.causeway.extensions.secman.delegated.shiro.realm.AuthenticationStrategyForSecMan -causewayModuleSecurityRealm=org.apache.causeway.extensions.secman.delegated.shiro.realm.CausewayModuleExtSecmanShiroRealm - -securityManager.authenticator.authenticationStrategy = $authenticationStrategy -securityManager.realms = $causewayModuleSecurityRealm - -[users] -[roles] - - diff --git a/regressiontests/incubating/src/test/resources/shiro-simple.ini b/regressiontests/incubating/src/test/resources/shiro-simple.ini deleted file mode 100644 index bc528951943..00000000000 --- a/regressiontests/incubating/src/test/resources/shiro-simple.ini +++ /dev/null @@ -1,58 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -[main] - - -# to use .ini file -securityManager.realms = $iniRealm - - -# ----------------------------------------------------------------------------- -# Users and their assigned roles -# -# Each line conforms to the format defined in the -# org.apache.shiro.realm.text.TextConfigurationRealm#setUserDefinitions JavaDoc -# ----------------------------------------------------------------------------- - -[users] -# user = password, role1, role2, role3, ... - - -sven = pass, admin_role -dick = pass, user_role -bob = pass, user_role -joe = pass, user_role - - - -# ----------------------------------------------------------------------------- -# Roles with assigned permissions -# -# Each line conforms to the format defined in the -# org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc -# ----------------------------------------------------------------------------- - -[roles] -# role = perm1, perm2, perm3, ... -# perm in format: packageName:className:memberName:r,w - -user_role = *:HelloWorldObjects:*:*,\ - *:HelloWorldObject:*:* -admin_role = * diff --git a/security/adoc/modules/ROOT/pages/about.adoc b/security/adoc/modules/ROOT/pages/about.adoc index 417e7328486..c3dbea08115 100644 --- a/security/adoc/modules/ROOT/pages/about.adoc +++ b/security/adoc/modules/ROOT/pages/about.adoc @@ -26,7 +26,6 @@ There are several implementations of these SPIs to choose from; these make up th include::security:bypass:partial$module-nav.adoc[] include::security:simple: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[] diff --git a/security/adoc/modules/ROOT/partials/component-nav.adoc b/security/adoc/modules/ROOT/partials/component-nav.adoc index 600dbb3c239..492bac46868 100644 --- a/security/adoc/modules/ROOT/partials/component-nav.adoc +++ b/security/adoc/modules/ROOT/partials/component-nav.adoc @@ -2,7 +2,6 @@ include::security:ROOT:partial$module-nav.adoc[] include::security:core:partial$module-nav.adoc[] 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[] diff --git a/valuetypes/vega/adoc/modules/vega/pages/about.adoc b/valuetypes/vega/adoc/modules/vega/pages/about.adoc index 3e8abd113f0..7557b21a378 100644 --- a/valuetypes/vega/adoc/modules/vega/pages/about.adoc +++ b/valuetypes/vega/adoc/modules/vega/pages/about.adoc @@ -63,7 +63,7 @@ In those modules where there are domain objects that use the `Vega` value type: CausewayModuleValVegaApplib.class, // ... }) -public class MyModule { ... } +public class MyModule { } ---- In addition, in the webapp module of your application, add the following dependencies: diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/auth/AuthenticationStrategyBasicAuth.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/auth/AuthenticationStrategyBasicAuth.java index c908806b8c7..57bca402495 100644 --- a/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/auth/AuthenticationStrategyBasicAuth.java +++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/causeway/viewer/restfulobjects/viewer/webmodule/auth/AuthenticationStrategyBasicAuth.java @@ -49,13 +49,6 @@ public InteractionContext lookupValid( final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse) { - // Basic auth should never create sessions! - // However, telling this Shiro here, is a fragile approach. - //TODO[2156] do this somewhere else (more coupled with shiro) - httpServletRequest.setAttribute( - "org.apache.shiro.subject.support.DefaultSubjectContext.SESSION_CREATION_ENABLED", - Boolean.FALSE); - var digest = getBasicAuthDigest(httpServletRequest); if (digest == null) { return null;
