| <!DOCTYPE html> |
| <!-- |
| 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. |
| --> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"/> |
| <title>Integrating Apache Shiro into Spring-based Applications | Apache Shiro</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta name="keywords" content='documentation,manual,spring'> |
| <meta name="generator" content="JBake"> |
| <meta name="google-site-verification" content="QIax6uT5UX3enoU0G8Pz2pXbQ45KaQuHZ3nCh9V27mw"> |
| <meta name="google-site-verification" content="ecFap6dWJgS_GCCtxmJQJ_nFYQhM6EgSpBPZDU7xsCE"> |
| <meta name="google-site-verification" content="gBTYOG8lMfNb_jrWrH3kFbudpEs_WrAJ2lb2-zLRaso"/> |
| <meta name="msvalidate.01" content="0B57EB46CBFAD8FD45008D2DB6B6C68C"> |
| |
| <meta property="og:title" content="Integrating Apache Shiro into Spring-based Applications | Apache Shiro"/> |
| <meta property="og:type" content="article"/> |
| <meta name="twitter:card" content="summary" /> |
| <meta name="twitter:site" content="@ApacheShiro" /> |
| <meta property="article:modification_time" content="2010-03-18T00:00:00Z"/> |
| <meta property="article:tag" content='documentation'/> |
| <meta property="article:tag" content='manual'/> |
| <meta property="article:tag" content='spring'/> |
| <meta property="og:locale" content="en_US" /> |
| <meta property="og:url" content='https://shiro.apache.org/spring-framework.html'/> |
| <meta property="og:image" content='images/shiro-featured-image.png'/> |
| <meta property="og:image:width" content='1200'/> |
| <meta property="og:image:height" content='628'/> |
| <meta property="og:site_name" content="Apache Shiro"/> |
| |
| <!-- Le styles --> |
| <link href="css/bootstrap.min.css" rel="stylesheet"> |
| <link href="bootstrap-icons-1.5.0/bootstrap-icons.css" rel="stylesheet"> |
| <link href="css/asciidoctor.css" rel="stylesheet"> |
| <link href="css/base.css" rel="stylesheet"> |
| <link href="highlight.js-11.2.0/styles/default.min.css" rel="stylesheet"> |
| <link href="css/gh-pages/gh-fork-ribbon.css" rel="stylesheet"/> |
| |
| <!-- Fav and touch icons --> |
| <!--<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../assets/ico/apple-touch-icon-144-precomposed.png"> |
| <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../assets/ico/apple-touch-icon-114-precomposed.png"> |
| <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../assets/ico/apple-touch-icon-72-precomposed.png"> |
| <link rel="apple-touch-icon-precomposed" href="../assets/ico/apple-touch-icon-57-precomposed.png">--> |
| <link rel="shortcut icon" href="favicon.ico"> |
| |
| <!-- Matomo --> |
| <script> |
| var _paq = window._paq = window._paq || []; |
| /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ |
| _paq.push(['disableCookies']); |
| _paq.push(['trackPageView']); |
| _paq.push(['enableLinkTracking']); |
| (function() { |
| var u="//matomo.privacy.apache.org/"; |
| _paq.push(['setTrackerUrl', u+'matomo.php']); |
| _paq.push(['setSiteId', '2']); |
| var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; |
| g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); |
| })(); |
| </script> |
| <!-- End Matomo Code --> |
| </head> |
| <body> |
| <div id="top-bar"></div> |
| <a class="github-fork-ribbon right-top" href="https://github.com/apache/shiro" title="Fork me on GitHub">Fork me on GitHub</a> |
| |
| <div id="wrap"> |
| |
| <div class="masthead"> |
| <p class="lead"> |
| <a href="index.html"><img src="images/apache-shiro-logo.png" style="height:100px; width:auto; vertical-align: bottom; margin-top: 20px;" alt="Apache Shiro Logo"></a> |
| <span class="tagline">Simple. Java. Security.</span> |
| <a class="pull-right" href="https://www.apache.org/events/current-event.html"> |
| <img style="padding-top: 8px" src="https://www.apache.org/events/current-event-125x125.png" alt="Apache Software Foundation Event Banner"/> |
| </a> |
| </p> |
| </div> |
| |
| <!-- Fixed navbar --> |
| <nav class="navbar navbar-expand-lg navbar-light bg-light shadow-sm mb-4"> |
| <div class="container-fluid"> |
| <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> |
| <span class="navbar-toggler-icon"></span> |
| </button> |
| |
| <div class="collapse navbar-collapse" id="navbarSupportedContent"> |
| <ul class="navbar-nav me-auto mb-2 mb-lg-0"> |
| <li class="nav-item"> |
| <a class="nav-link" href="get-started.html">Get Started</a> |
| </li> |
| <li class="nav-item"> |
| <a class="nav-link" href="documentation.html">Docs</a> |
| </li> |
| |
| <li class="nav-item dropdown"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown-webapps" role="button" data-bs-toggle="dropdown" aria-expanded="false"> |
| Web Apps |
| </a> |
| <ul class="dropdown-menu" aria-labelledby="navbarDropdown-webapps"> |
| <li><a class="dropdown-item" href="web.html">General</a></li> |
| <li><a class="dropdown-item" href="jaxrs.html">JAX-RS</a></li> |
| <li><a class="dropdown-item" href="jakarta-ee.html">Jakarta EE</a></li> |
| <li><hr class="dropdown-divider"></li> |
| <li><a class="dropdown-item" href="web-features.html">Features</a></li> |
| </ul> |
| </li> |
| |
| <li><a class="nav-link" href="features.html">Features</a></li> |
| |
| <!-- integrations --> |
| <li class="nav-item dropdown"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown-integrations" role="button" data-bs-toggle="dropdown" aria-expanded="false"> |
| Integrations |
| </a> |
| <ul class="dropdown-menu" aria-labelledby="navbarDropdown-integrations"> |
| <li><a class="dropdown-item" href="spring-boot.html">Spring</a></li> |
| <li><a class="dropdown-item" href="guice.html">Guice</a></li> |
| <li><hr class="dropdown-divider"></li> |
| <li><a class="dropdown-item" href="integration.html">Third-Party Integrations</a></li> |
| </ul> |
| </li> |
| |
| <!-- Community --> |
| <li class="nav-item dropdown"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown-community" role="button" data-bs-toggle="dropdown" aria-expanded="false"> |
| Community |
| </a> |
| <ul class="dropdown-menu" aria-labelledby="navbarDropdown-community"> |
| <li><a class="dropdown-item" href="forums.html">Community Forums</a></li> |
| <li><a class="dropdown-item" href="mailing-lists.html">Mailing Lists</a></li> |
| <li><a class="dropdown-item" href="articles.html">Articles</a></li> |
| <li><a class="dropdown-item" href="news.html">News</a></li> |
| <li><a class="dropdown-item" href="events.html">Events</a></li> |
| <li><hr class="dropdown-divider"></li> |
| <li><a class="dropdown-item" href="community.html">More</a></li> |
| </ul> |
| </li> |
| |
| <!-- About --> |
| <li class="nav-item dropdown"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown-about" role="button" data-bs-toggle="dropdown" aria-expanded="false"> |
| About |
| </a> |
| <ul class="dropdown-menu" aria-labelledby="navbarDropdown-about"> |
| <li><a class="dropdown-item" href="about.html">About</a></li> |
| <li><a class="dropdown-item" href="privacy-policy.html">Privacy Policy</a></li> |
| <li><a class="dropdown-item" href="security-reports.html">Vulnerability Reports</a></li> |
| </ul> |
| </li> |
| </ul> |
| |
| <ul class="d-flex justify-content-end navbar-nav mb-2 mb-lg-0"> |
| <!-- The ASF --> |
| <li class="nav-item dropdown"> |
| <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown-asf" role="button" data-bs-toggle="dropdown" aria-expanded="false"> |
| Apache Software Foundation |
| </a> |
| <ul class="dropdown-menu" aria-labelledby="navbarDropdown-asf"> |
| <li><a class="dropdown-item" href="https://www.apache.org/">Apache Homepage</a></li> |
| <li><a class="dropdown-item" href="https://www.apache.org/licenses/">License</a></li> |
| <li><a class="dropdown-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> |
| <li><a class="dropdown-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| <li><a class="dropdown-item" href="https://www.apache.org/security/">Security</a></li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </nav> |
| |
| <div class="page-header"> |
| <h1>Integrating Apache Shiro into Spring-based Applications</h1> |
| </div> |
| |
| |
| <div class="admonitionblock tip"> |
| <table> |
| <tbody> |
| <tr> |
| <td class="icon"> |
| <div class="title">Handy Hint</div> |
| </td> |
| <td class="content"> |
| <div class="title">Shiro v1 version notice</div> |
| <div class="paragraph"> |
| <p>As of 2024-03-01, Shiro v1 will soon be superseded by v2.<p> |
| </div> |
| </td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| |
| <div id="toc" class="toc"> |
| <div id="toctitle">Table of Contents</div> |
| <ul class="sectlevel1"> |
| <li><a href="#standalone_applications">Standalone Applications</a></li> |
| <li><a href="#web_applications">Web Applications</a></li> |
| <li><a href="#enabling_shiro_annotations">Enabling Shiro Annotations</a> |
| <ul class="sectlevel2"> |
| <li><a href="#annotations_and_web_applications">Annotations and Web Applications</a></li> |
| </ul> |
| </li> |
| <li><a href="#caching">Caching</a></li> |
| <li><a href="#configuration_properties">Configuration Properties</a></li> |
| </ul> |
| </div> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>This page covers the ways to integrate Shiro into <a href="https://spring.io">Spring</a>-based applications.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="standalone_applications">Standalone Applications</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Include the Shiro Spring dependency in you application classpath (we recommend using a tool such as Apache Maven or Gradle to manage this).</p> |
| </div> |
| <ul class="nav nav-tabs" id="dependency-cli-tab" role="tablist"> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link active" |
| id="maven-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#maven-cli" |
| type="button" |
| role="tab" |
| aria-controls="maven-cli" |
| aria-selected="true" |
| >Maven</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="gradle-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#gradle-cli" |
| type="button" |
| role="tab" |
| aria-controls="gradle-cli" |
| aria-selected="false" |
| >Gradle</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="sbt-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#sbt-cli" |
| type="button" |
| role="tab" |
| aria-controls="sbt-cli" |
| aria-selected="false" |
| >SBT</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="ivy-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#ivy-cli" |
| type="button" |
| role="tab" |
| aria-controls="ivy-cli" |
| aria-selected="false" |
| >Ivy</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="leiningen-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#leiningen-cli" |
| type="button" |
| role="tab" |
| aria-controls="leiningen-cli" |
| aria-selected="false" |
| >Leiningen</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="buildr-cli-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#buildr-cli" |
| type="button" |
| role="tab" |
| aria-controls="buildr-cli" |
| aria-selected="false" |
| >Buildr</button> |
| </li> |
| </ul> |
| |
| <div class="tab-content" id="dependency-cli-tab-content"> |
| <div |
| class="tab-pane fade show active" |
| id="maven-cli" |
| role="tabpanel" |
| aria-labelledby="maven-cli-tab" |
| > |
| <pre><code class='xml language-xml'><dependency> |
| <groupId>org.apache.shiro</groupId> |
| <artifactId>shiro-spring</artifactId> |
| <version>2.0.0</version> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework</groupId> |
| <artifactId>spring-context</artifactId> |
| <version>${spring.version}</version> |
| </dependency> |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="gradle-cli" |
| role="tabpanel" |
| aria-labelledby="gradle-cli-tab" |
| > |
| <pre><code class='groovy language-groovy'>compile 'org.apache.shiro:shiro-spring:2.0.0' |
| compile 'org.springframework:spring-context:${spring.version}' |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="sbt-cli" |
| role="tabpanel" |
| aria-labelledby="sbt-cli-tab" |
| > |
| <pre><code class='scala language-scala'>libraryDependencies += "org.apache.shiro" % "shiro-spring" % "2.0.0" |
| libraryDependencies += "org.springframework" % "spring-context" % "${spring.version}" |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="ivy-cli" |
| role="tabpanel" |
| aria-labelledby="ivy-cli-tab" |
| > |
| <pre><code class='xml language-xml'><dependency org="org.apache.shiro" name="shiro-spring" rev="2.0.0"/> |
| <dependency org="org.springframework" name="spring-context" rev="${spring.version}"/> |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="leiningen-cli" |
| role="tabpanel" |
| aria-labelledby="leiningen-cli-tab" |
| > |
| <pre><code class='clojure language-clojure'>[org.apache.shiro/shiro-spring "2.0.0"] |
| [org.springframework/spring-context "${spring.version}"] |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="buildr-cli" |
| role="tabpanel" |
| aria-labelledby="buildr-cli-tab" |
| > |
| <pre><code class='groovy language-groovy'>'org.apache.shiro:shiro-spring:jar:2.0.0' |
| 'org.springframework:spring-context:jar:${spring.version}' |
| </code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Import the Shiro Spring configurations:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Configuration |
| @Import({ShiroBeanConfiguration.class, |
| ShiroConfiguration.class, |
| ShiroAnnotationProcessorConfiguration.class}) |
| public class CliAppConfig { |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The above configurations do the following:</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 55%;"> |
| <col style="width: 45%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">Configuration Class</th> |
| <th class="tableblock halign-left valign-top">Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.config.ShiroBeanConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Shiro’s lifecycle and events</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.config.ShiroConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Shiro Beans (SecurityManager, SessionManager, etc)</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Enables Shiro’s annotation processing</p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p>The only thing that is left is to configure a <a href="realm.html">realm</a>:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean |
| public Realm realm() { |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The easiest way to set up Shiro, so that all SecurityUtils.* methods work in all cases, is to make the <code>SecurityManager</code> bean a static singleton. |
| DO NOT do this in web applications - see the <a href="#web_applications">Web Applications</a> section below instead.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Autowired |
| private SecurityManager securityManager; |
| |
| @PostConstruct |
| private void initStaticSecurityManager() { |
| SecurityUtils.setSecurityManager(securityManager); |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>That is it, now you can get the current <code>Subject</code> using:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">SecurityUtils.getSubject();</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>You can see a full example in our <a href="https://github.com/apache/shiro/tree/main/samples/spring">samples on GitHub</a>.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="web_applications">Web Applications</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Shiro has first-class support for Spring web applications. In a web application, all Shiro-accessible web requests must go through a main Shiro Filter. This filter itself is extremely powerful, allowing for ad-hoc custom filter chains to be executed based on any URL path expression.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Include the Shiro Spring web dependencies in you application classpath (we recommend using a tool such as Apache Maven or Gradle to manage this).</p> |
| </div> |
| <ul class="nav nav-tabs" id="dependency-web-tab" role="tablist"> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link active" |
| id="maven-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#maven-web" |
| type="button" |
| role="tab" |
| aria-controls="maven-web" |
| aria-selected="true" |
| >Maven</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="gradle-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#gradle-web" |
| type="button" |
| role="tab" |
| aria-controls="gradle-web" |
| aria-selected="false" |
| >Gradle</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="sbt-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#sbt-web" |
| type="button" |
| role="tab" |
| aria-controls="sbt-web" |
| aria-selected="false" |
| >SBT</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="ivy-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#ivy-web" |
| type="button" |
| role="tab" |
| aria-controls="ivy-web" |
| aria-selected="false" |
| >Ivy</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="leiningen-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#leiningen-web" |
| type="button" |
| role="tab" |
| aria-controls="leiningen-web" |
| aria-selected="false" |
| >Leiningen</button> |
| </li> |
| <li class="nav-item" role="presentation"> |
| <button |
| class="nav-link" |
| id="buildr-web-tab" |
| data-bs-toggle="tab" |
| data-bs-target="#buildr-web" |
| type="button" |
| role="tab" |
| aria-controls="buildr-web" |
| aria-selected="false" |
| >Buildr</button> |
| </li> |
| </ul> |
| |
| <div class="tab-content" id="dependency-web-tab-content"> |
| <div |
| class="tab-pane fade show active" |
| id="maven-web" |
| role="tabpanel" |
| aria-labelledby="maven-web-tab" |
| > |
| <pre><code class='xml language-xml'><dependency> |
| <groupId>org.apache.shiro</groupId> |
| <artifactId>shiro-spring</artifactId> |
| <version>2.0.0</version> |
| </dependency> |
| <dependency> |
| <groupId>org.apache.shiro</groupId> |
| <artifactId>shiro-web</artifactId> |
| <version>2.0.0</version> |
| </dependency> |
| <dependency> |
| <groupId>org.springframework</groupId> |
| <artifactId>spring-webmvc</artifactId> |
| <version>${spring.version}</version> |
| </dependency> |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="gradle-web" |
| role="tabpanel" |
| aria-labelledby="gradle-web-tab" |
| > |
| <pre><code class='groovy language-groovy'>compile 'org.apache.shiro:shiro-spring:2.0.0' |
| compile 'org.apache.shiro:shiro-web:2.0.0' |
| compile 'org.springframework:spring-webmvc:${spring.version}' |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="sbt-web" |
| role="tabpanel" |
| aria-labelledby="sbt-web-tab" |
| > |
| <pre><code class='scala language-scala'>libraryDependencies += "org.apache.shiro" % "shiro-spring" % "2.0.0" |
| libraryDependencies += "org.apache.shiro" % "shiro-web" % "2.0.0" |
| libraryDependencies += "org.springframework" % "spring-webmvc" % "${spring.version}" |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="ivy-web" |
| role="tabpanel" |
| aria-labelledby="ivy-web-tab" |
| > |
| <pre><code class='xml language-xml'><dependency org="org.apache.shiro" name="shiro-spring" rev="2.0.0"/> |
| <dependency org="org.apache.shiro" name="shiro-web" rev="2.0.0"/> |
| <dependency org="org.springframework" name="spring-webmvc" rev="${spring.version}"/> |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="leiningen-web" |
| role="tabpanel" |
| aria-labelledby="leiningen-web-tab" |
| > |
| <pre><code class='clojure language-clojure'>[org.apache.shiro/shiro-spring "2.0.0"] |
| [org.apache.shiro/shiro-web "2.0.0"] |
| [org.springframework/spring-webmvc "${spring.version}"] |
| </code></pre> |
| </div> |
| <div |
| class="tab-pane fade" |
| id="buildr-web" |
| role="tabpanel" |
| aria-labelledby="buildr-web-tab" |
| > |
| <pre><code class='groovy language-groovy'>'org.apache.shiro:shiro-spring:jar:2.0.0' |
| 'org.apache.shiro:shiro-web:jar:2.0.0' |
| 'org.springframework:spring-webmvc:jar:${spring.version}' |
| </code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Import the Shiro Spring configurations:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Configuration |
| @Import({ShiroBeanConfiguration.class, |
| ShiroAnnotationProcessorConfiguration.class, |
| ShiroWebConfiguration.class, |
| ShiroWebFilterConfiguration.class, |
| ShiroRequestMappingConfig.class}) |
| public class ApplicationConfig { |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The above configurations do the following:</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 55%;"> |
| <col style="width: 45%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">Configuration Class</th> |
| <th class="tableblock halign-left valign-top">Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.config.ShiroBeanConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Shiro’s lifecycle and events</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Enables Shiro’s annotation processing</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.web.config.ShiroWebConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Shiro Beans for web usage (SecurityManager, SessionManager, etc)</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.web.config.ShiroWebFilterConfiguration</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Shiro’s web filter</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">org.apache.shiro.spring.web.config.ShiroRequestMappingConfig</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Configures Spring with Shiro’s <code>UrlPathHelper</code> implementation to ensure URLs are processed the same both frameworks</p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p>Provide a Realm implementation:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean |
| public Realm realm() { |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>And finally a <code>ShiroFilterChainDefinition</code> which will map any application specific paths to a given filter, in order to allow different paths different levels of access.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean |
| public ShiroFilterChainDefinition shiroFilterChainDefinition() { |
| DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); |
| |
| // logged in users with the 'admin' role |
| chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]"); |
| |
| // logged in users with the 'document:read' permission |
| chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]"); |
| |
| // all other paths require a logged in user |
| chainDefinition.addPathDefinition("/**", "authc"); |
| return chainDefinition; |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If you are using Shiro’s annotations see the <a href="#annotations_and_web_applications">annotation</a> section below.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You can see a full example in our <a href="https://github.com/apache/shiro/tree/main/samples/spring-mvc">samples on GitHub</a>.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="enabling_shiro_annotations">Enabling Shiro Annotations</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>In both standalone and web applications, you might want to use Shiro’s Annotations for security checks (for example, <code>@RequiresRoles</code>, <code>@RequiresPermissions</code>, etc.) These annotations are enabled by importing the <code>ShiroAnnotationProcessorConfiguration</code> Spring configuration in both sections above.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Simply annotate your methods in order to use them:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@RequiresPermissions("document:read") |
| public void readDocument() { |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="annotations_and_web_applications">Annotations and Web Applications</h3> |
| <div class="paragraph"> |
| <p>Shiro annotations are fully supported for use in <code>@Controller</code> classes, for example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Controller |
| public class AccountInfoController { |
| |
| @RequiresRoles("admin") |
| @RequestMapping("/admin/config") |
| public String adminConfig(Model model) { |
| return "view"; |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>A <code>ShiroFilterChainDefinition</code> bean with at least one definition is still required for this to work, either configure all paths to be accessible via the <code>anon</code> filter or a filter in 'permissive' mode, for example: <code>authcBasic[permissive]</code>.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean |
| public ShiroFilterChainDefinition shiroFilterChainDefinition() { |
| DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); |
| chainDefinition.addPathDefinition("/**", "anon"); // all paths are managed via annotations |
| |
| // or allow basic authentication, but NOT require it. |
| // chainDefinition.addPathDefinition("/**", "authcBasic[permissive]"); |
| return chainDefinition; |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="caching">Caching</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Enabling caching is as simple as providing a <a href="https://shiro.apache.org/caching.html">CacheManager</a> bean:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Bean |
| protected CacheManager cacheManager() { |
| return new MemoryConstrainedCacheManager(); |
| }</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="configuration_properties">Configuration Properties</h2> |
| <div class="sectionbody"> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 40%;"> |
| <col style="width: 15.5555%;"> |
| <col style="width: 44.4445%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">Key</th> |
| <th class="tableblock halign-left valign-top">Default Value</th> |
| <th class="tableblock halign-left valign-top">Description</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.deleteInvalidSessions</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Remove invalid |
| session from session storage</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.sessionIdCookieEnabled</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Enable session ID |
| to cookie, for session tracking</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.sessionIdUrlRewritingEnabled</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>true</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Enable |
| session URL rewriting support</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.userNativeSessionManager</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">If enabled Shiro will manage |
| the HTTP sessions instead of the container</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.cookie.name</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>JSESSIONID</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Session cookie name</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.cookie.maxAge</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>-1</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Session cookie max age</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.cookie.domain</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Session cookie domain</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.cookie.path</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Session cookie path</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.sessionManager.cookie.secure</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Session cookie secure flag</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.rememberMeManager.cookie.name</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>rememberMe</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">RememberMe cookie |
| name</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.rememberMeManager.cookie.maxAge</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">one year</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">RememberMe cookie max |
| age</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.rememberMeManager.cookie.domain</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">RememberMe cookie domain</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.rememberMeManager.cookie.path</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">RememberMe cookie path</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.rememberMeManager.cookie.secure</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>false</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">RememberMe cookie |
| secure flag</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.loginUrl</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/login.jsp</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Login URL used when unauthenticated users |
| are redirected to login page</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.successUrl</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><code>/</code></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Default landing page after a user logs in (if |
| alternative cannot be found in the current session)</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">shiro.unauthorizedUrl</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">null</p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Page to redirect user to if they are |
| unauthorized (403 page)</p></td> |
| </tr> |
| </tbody> |
| </table> |
| </div> |
| </div> |
| <hr /> |
| |
| </div> |
| |
| <div class="footer-padding"></div> |
| |
| <div class="container-fluid pt-2 border-top" id="custom-footer"> |
| <footer class="row justify-content-between align-items-center"> |
| <div class=" col-md-5"> |
| <div class="copyright-footer justify-content-start"> |
| <a href="https://www.apache.org/foundation/contributing.html">Donate to the ASF</a> | |
| <a href="https://www.apache.org/licenses/LICENSE-2.0.html">License</a> |
| <p class="text-muted">Copyright © 2008-2024 The Apache Software Foundation</p> |
| </div> |
| </div> |
| |
| <div class="d-flex justify-content-center col-md-1"> |
| <a class="btn btn-social"><span class="social-icon social-twitter"><i class="bi bi-twitter"></i></span></a> |
| <a class="btn btn-social"><span class="social-icon social-facebook"><i class="bi bi-facebook"></i></span></a> |
| <a class="btn btn-social"><span class="social-icon social-linkedin"><i class="bi bi-linkedin"></i></span></a> |
| </div> |
| |
| <div class="d-flex justify-content-end col-md-4" id="editThisPage"> |
| <input type="hidden" id="ghEditPage" value="https://github.com/apache/shiro-site/edit/main/src/site/content/spring-framework.adoc"/> |
| </div> |
| |
| <div class="d-flex col-md-2 justify-content-end" style="position: relative"> |
| <div class="footer-shield"></div> |
| </div> |
| </footer> |
| </div> |
| |
| |
| <!-- Le javascript |
| ================================================== --> |
| <!-- Placed at the end of the document so the pages load faster --> |
| <script src="js/bootstrap.min.js"></script> |
| <script src="highlight.js-11.2.0/highlight.min.js"></script> |
| <script src="js/shiro.js"></script> |
| |
| <script> |
| docReady( |
| addPageEditLink() |
| ); |
| </script> |
| <script>hljs.highlightAll();</script> |
| |
| </body> |
| </html> |