blob: a72dc065b3c37ea14a7457edc8d15a134cc66fa3 [file] [log] [blame]
<!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>Apache Shiro Architecture | Apache Shiro</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="keywords" content='documentation,manual'>
<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="Apache Shiro Architecture | 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="og:locale" content="en_US" />
<meta property="og:url" content='https://shiro.apache.org/architecture.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>Apache Shiro Architecture</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="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Apache Shiro&#8217;s design goals are to simplify application security by being intuitive and easy to use. Shiro&#8217;s core design models how most people think about application security - in the context of someone (or something) interacting with an application.</p>
</div>
<div class="paragraph">
<p>Software applications are usually designed based on user stories. That is, you&#8217;ll often design user interfaces or service APIs based on how a user would (or should) interact with the software. For example, you might say, "If the user interacting with my application is logged in, I will show them a button they can click to view their account information. If they are not logged in, I will show a sign-up button."</p>
</div>
<div class="paragraph">
<p>This example statement indicates that applications are largely written to satisfy user requirements and needs. Even if the 'user' is another software system and not a human being, you still write code to reflect behavior based on who (or what) is currently interacting with your software.</p>
</div>
<div class="paragraph">
<p>Shiro reflects these concepts in its own design. By matching what is already intuitive for software developers, Apache Shiro remains intuitive and easy to use in practically any application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="high_level_overview">High-Level Overview</h2>
<div class="sectionbody">
<div class="paragraph">
<p>At the highest conceptual level, Shiro&#8217;s architecture has 3 primary concepts: the <code>Subject</code>, <code>SecurityManager</code> and <code>Realms</code>. The following diagram is a high-level overview of how these components interact, and we&#8217;ll cover each concept below:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="/images/ShiroBasicArchitecture.png" alt="Shiro Basic Architecture Diagram">
</div>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Subject</strong>: As we&#8217;ve mentioned in our <a href="tutorial.html">Tutorial</a>, the <code>Subject</code> is essentially a security specific 'view' of the currently executing user. Whereas the word 'User' often implies a human being, a <code>Subject</code> can be a person, but it could also represent a 3rd-party service, daemon account, cron job, or anything similar - basically anything that is currently interacting with the software.</p>
<div class="paragraph">
<p><code>Subject</code> instances are all bound to (and require) a <code>SecurityManager</code>. When you interact with a <code>Subject</code>, those interactions translate to subject-specific interactions with the <code>SecurityManager</code>.</p>
</div>
</li>
<li>
<p><strong>SecurityManager</strong>: The <code>SecurityManager</code> is the heart of Shiro&#8217;s architecture and acts as a sort of 'umbrella&#8217; object that coordinates its internal security components that together form an object graph. However, once the SecurityManager and its internal object graph is configured for an application, it is usually left alone and application developers spend almost all of their time with the <code>Subject</code> API.</p>
<div class="paragraph">
<p>We will talk about the <code>SecurityManager</code> in detail later on, but it is important to realize that when you interact with a <code>Subject</code>, it is really the <code>SecurityManager</code> behind the scenes that does all the heavy lifting for any <code>Subject</code> security operation. This is reflected in the basic flow diagram above.</p>
</div>
</li>
<li>
<p><strong>Realms</strong>: Realms act as the &#8216;bridge&#8217; or &#8216;connector&#8217; between Shiro and your application&#8217;s security data. When it comes time to actually interact with security-related data like user accounts to perform authentication (login) and authorization (access control), Shiro looks up many of these things from one or more Realms configured for an application.</p>
<div class="paragraph">
<p>In this sense a Realm is essentially a security-specific <a href="https://en.wikipedia.org/wiki/Data_access_object">DAO</a>: it encapsulates connection details for data sources and makes the associated data available to Shiro as needed. When configuring Shiro, you must specify at least one Realm to use for authentication and/or authorization. The <code>SecurityManager</code> may be configured with multiple Realms, but at least one is required.</p>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="detailed_architecture">Detailed Architecture</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following diagram shows Shiro&#8217;s core architectural concepts followed by short summaries of each:</p>
</div>
<div class="imageblock text-center">
<div class="content">
<img src="/images/ShiroArchitecture.png" alt="Shiro Architecture Diagram">
</div>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Subject</strong> (<a href="static/current/apidocs/org/apache/shiro/subject/Subject.html"><code>org.apache.shiro.subject.Subject</code></a>)
A security-specific 'view' of the entity (user, 3rd-party service, cron job, etc.) currently interacting with the software.</p>
</li>
<li>
<p><strong>SecurityManager</strong> (<a href="static/current/apidocs/org/apache/shiro/mgt/SecurityManager.html">org.apache.shiro.mgt.SecurityManager</a>)
As mentioned above, the <code>SecurityManager</code> is the heart of Shiro&#8217;s architecture. It is mostly an 'umbrella' object that coordinates its managed components to ensure they work smoothly together. It also manages Shiro&#8217;s view of every application user, so it knows how to perform security operations per user.</p>
</li>
<li>
<p><strong>Authenticator</strong> (<a href="static/current/apidocs/org/apache/shiro/authc/Authenticator.html">org.apache.shiro.authc.Authenticator</a>)
The <code>Authenticator</code> is the component that is responsible for executing and reacting to authentication (log-in) attempts by users. When a user tries to log-in, that logic is executed by the <code>Authenticator</code>. The <code>Authenticator</code> knows how to coordinate with one or more <code>Realms</code> that store relevant user/account information. The data obtained from these <code>Realms</code> is used to verify the user&#8217;s identity to guarantee the user really is who they say they are.</p>
<div class="ulist">
<ul>
<li>
<p><strong>Authentication Strategy</strong> (<a href="static/current/apidocs/org/apache/shiro/authc/pam/AuthenticationStrategy.html">org.apache.shiro.authc.pam.AuthenticationStrategy</a>)
If more than one <code>Realm</code> is configured, the <code>AuthenticationStrategy</code> will coordinate the Realms to determine the conditions under which an authentication attempt succeeds or fails (for example, if one realm succeeds but others fail, is the attempt successful? Must all realms succeed? Only the first?).</p>
</li>
</ul>
</div>
</li>
<li>
<p><strong>Authorizer</strong> (<a href="static/current/apidocs/org/apache/shiro/authz/Authorizer.html">org.apache.shiro.authz.Authorizer</a>)
The <code>Authorizer</code> is the component responsible determining users' access control in the application. It is the mechanism that ultimately says if a user is allowed to do something or not. Like the <code>Authenticator</code>, the <code>Authorizer</code> also knows how to coordinate with multiple back-end data sources to access role and permission information. The <code>Authorizer</code> uses this information to determine exactly if a user is allowed to perform a given action.</p>
</li>
<li>
<p><strong>SessionManager</strong> (<a href="static/current/apidocs/org/apache/shiro/session/mgt/SessionManager.html">org.apache.shiro.session.mgt.SessionManager</a>)
The <code>SessionManager</code> knows how to create and manage user <code>Session</code> lifecycles to provide a robust Session experience for users in all environments. This is a unique feature in the world of security frameworks - Shiro has the ability to natively manage user Sessions in any environment, even if there is no Web/Servlet or EJB container available. By default, Shiro will use an existing session mechanism if available, (e.g. Servlet Container), but if there isn&#8217;t one, such as in a standalone application or non-web environment, it will use its built-in enterprise session management to offer the same programming experience. The <code>SessionDAO</code> exists to allow any datasource to be used to persist sessions.</p>
<div class="ulist">
<ul>
<li>
<p><strong>SessionDAO</strong> (<a href="static/current/apidocs/org/apache/shiro/session/mgt/eis/SessionDAO.html">org.apache.shiro.session.mgt.eis.SessionDAO</a>)
The <code>SessionDAO</code> performs <code>Session</code> persistence (CRUD) operations on behalf of the <code>SessionManager</code>. This allows any data store to be plugged in to the Session Management infrastructure.</p>
</li>
</ul>
</div>
</li>
<li>
<p><strong>CacheManager</strong> (<a href="static/current/apidocs/org/apache/shiro/cache/CacheManager.html">org.apache.shiro.cache.CacheManager</a>)
The <code>CacheManager</code> creates and manages <code>Cache</code> instance lifecycles used by other Shiro components. Because Shiro can access many back-end data sources for authentication, authorization and session management, caching has always been a first-class architectural feature in the framework to improve performance while using these data sources. Any of the modern open-source and/or enterprise caching products can be plugged in to Shiro to provide a fast and efficient user-experience.</p>
</li>
<li>
<p><strong>Cryptography</strong> (<a href="static/current/apidocs/org/apache/shiro/crypto/package-summary.html">org.apache.shiro.crypto.*</a>)
Cryptography is a natural addition to an enterprise security framework. Shiro&#8217;s <code>crypto</code> package contains easy-to-use and understand representations of crytographic Ciphers, Hashes (aka digests) and different codec implementations. All the classes in this package are carefully designed to be very easy to use and easy to understand. Anyone who has used Java&#8217;s native cryptography support knows it can be a challenging animal to tame. Shiro&#8217;s crypto APIs simplify the complicated Java mechanisms and make cryptography easy to use for normal mortal human beings.</p>
</li>
<li>
<p><strong>Realms</strong> (<a href="static/current/apidocs/org/apache/shiro/realm/Realm.html">org.apache.shiro.realm.Realm</a>)
As mentioned above, Realms act as the &#8216;bridge&#8217; or &#8216;connector&#8217; between Shiro and your application&#8217;s security data. When it comes time to actually interact with security-related data like user accounts to perform authentication (login) and authorization (access control), Shiro looks up many of these things from one or more Realms configured for an application. You can configure as many <code>Realms</code> as you need (usually one per data source) and Shiro will coordinate with them as necessary for both authentication and authorization.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="the_securitymanager">The <code>SecurityManager</code></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Because Shiro&#8217;s API encourages a <code>Subject</code>-centric programming approach, most application developers will rarely, if ever, interact with the <code>SecurityManager</code> directly (framework developers however might sometimes find it useful). Even so, it is still important to know how the <code>SecurityManager</code> functions, especially when configuring one for an application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="design">Design</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As stated previously, the application&#8217;s <code>SecurityManager</code> performs security operations and manages state for &lt;em&gt;all&lt;/em&gt; application users. In Shiro&#8217;s default <code>SecurityManager</code> implementations, this includes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Authentication</p>
</li>
<li>
<p>Authorization</p>
</li>
<li>
<p>Session Management</p>
</li>
<li>
<p>Cache Management</p>
</li>
<li>
<p><a href="realm.html">Realm</a> coordination</p>
</li>
<li>
<p>Event propagation</p>
</li>
<li>
<p>"Remember Me" Services</p>
</li>
<li>
<p>Subject creation</p>
</li>
<li>
<p>Logout and more.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>But this is a lot of functionality to try to manage in a single component. And, making these things flexible and customizable would be very difficult if everything were lumped into a single implementation class.</p>
</div>
<div class="paragraph">
<p>To simplify configuration and enable flexible configuration/pluggability, Shiro&#8217;s implementations are all highly modular in design - so modular in fact, that the SecurityManager implementation (and its class-hierarchy) does not do much at all. Instead, the <code>SecurityManager</code> implementations mostly act as a lightweight 'container' component, delegating almost all behavior to nested/wrapped components. This 'wrapper' design is reflected in the detailed architecture diagram above.</p>
</div>
<div class="paragraph">
<p>While the components actually execute the logic, the <code>SecurityManager</code> implementation knows how and when to coordinate the components for the correct behavior.</p>
</div>
<div class="paragraph">
<p>The <code>SecurityManager</code> implementations and the components are also JavaBeans compatible, which allows you (or a configuration mechanism) to easily customize the pluggable components via standard JavaBeans accessor/mutator methods (get*/set*). This means the Shiro&#8217;s architectural modularity can translate into very easy configuration for custom behavior.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<div class="title">Easy Configuration</div>
</td>
<td class="content">
<div class="paragraph">
<p>Because of JavaBeans compatibility, it is very easy to configure the <code>SecurityManager</code> with custom components via any mechanism that supports JavaBeans-style configuration, such as <a href="/spring.html">Spring</a>, Guice, JBoss, etc.')</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>We will cover <a href="configuration.html">Configuration</a> next.</p>
</div>
</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>&nbsp;|&nbsp;
<a href="https://www.apache.org/licenses/LICENSE-2.0.html">License</a>&nbsp;
<p class="text-muted">Copyright &copy; 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/architecture.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>