blob: 3c48a043a8785ba3407f5505140a9e2613a7ca96 [file] [log] [blame]
<a name="SecurityManager-UnderstandingtheSecurityManagerinApacheShiro"></a>
Understanding the SecurityManager in Apache Shiro
=================================================
The [SecurityManager](static/current/apidocs/org/apache/shiro/mgt/SecurityManager.html) lies at the heart of Shiro's architecture. While the [Subject](subject.html "Subject") represents security functionality and state for a _single_ application user, the `SecurityManager` performs security operations and manages state for _all_ application users.
Because Shiro's API encourages a `Subject`-centric programming approach, most application developers will rarely, if ever, interact with the `SecurityManager` directly (framework developers however might sometimes find it useful). Even so, it is still important to know how the `SecurityManager` functions, especially when configuring one for an application.
<a name="SecurityManager-Design"></a>
Design
------
As stated previously, the application's `SecurityManager` performs security operations and manages state for _all_ application users. In Shiro's default `SecurityManager` implementations, this includes:
* Authentication
* Authorization
* Session Management
* Cache Management
* [Realm](realm.html "Realm") coordination
* Event propagation
* "Remember Me" Services
* Subject creation
* Logout
and more.
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.
To simplify configuration and enable flexible configuration/pluggability, Shiro'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 `SecurityManager` implementations mostly act as a lightweight 'container' component, delegating almost all behavior to nested/wrapped components.
<a name="SecurityManager-Modularity"></a>
#[[###Modularity]]#
To simplify the `SecurityManager` implementation complexity and allow for pluggable behavior, the Shiro `SecurityManager` implementations delegate almost all logic to a nested set of modular components that actually perform the necessary functionality. While the components actually execute the logic, the `SecurityManager` implementation knows how and when to coordinate the components for the correct behavior.
The nested components that the `SecurityManager` coordinates and delegates to are:
* Authenticator (`org.apache.shiro.authc.Authenticator`)
* Authorizer (`org.apache.shiro.authz.Authorizer`)
* SessionManager (`org.apache.shiro.session.mgt.SessionManager`)
* [CacheManager](cachemanager.html "CacheManager") (`org.apache.shiro.cache.CacheManager`)
* RememberMeManager (`org.apache.shiro.mgt.RememberMeManager`)
* SubjectFactory(`org.apache.shiro.mgt.SubjectFactory`)
The `SecurityManager` implementations and 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's architectural modularity can translate into very easy configuration for custom behavior.
#tip('Easy Configuration', '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" title="Spring">Spring</a>, Guice, JBoss, etc.')
<a name="SecurityManager-ProgrammaticConfiguration"></a>
#[[###Programmatic Configuration]]#
The absolute simplest way to create a SecurityManager and make it available to the application is to create a `org.apache.shiro.mgt.DefaultSecurityManager` and wire it up in code:
``` java
Realm realm = //instantiate or acquire a Realm instance. We'll discuss Realms later.
SecurityManager securityManager = new DefaultSecurityManager(realm);
//Make the SecurityManager instance available to the entire application:
SecurityUtils.setSecurityManager(securityManager);
```
Surprisingly, after only 3 lines of code, you now have a fully functional Shiro environment suitable for most applications. How easy was that!?
You could additionally call any of the `SecurityManager` instance's setter methods with custom implementations of the nested components listed above to fully customize its behavior.
But, as simple as programmatic customization is, these 3 lines of code do not represent the ideal configuration for most real world applications. There are a few reasons why programmatic configuration may not be suitable for your application:
1. It requires you to know about and instantiate a direct implementation. It would be nicer if you didn't have to know about concrete implementations and where to find them.
2. The `SecurityUtils.setSecurityManager` method call makes the instantiated `SecurityManager` instance a VM static singleton, which, while fine for many applications, would cause problems if more than one Shiro-enabled application was running on the same JVM. It could be better if the instance was an application singleton, but not a static memory reference.
3. It requires you to recompile your application every time you want to make a Shiro configuration change.
Most applications instead benefit from text-based configuration that could be modified independently of source code and even make things easier to understand for those not intimately familiar with Shiro's APIs.
<a name="SecurityManager-TextConfiguration"></a>
#[[###Text Configuration]]#
Shiro provides a simple INI-based [configuration](configuration.html "Configuration") that can be used out of the box, but any other JavaBeans-compatible mechanism can be used as well. For example, Shiro has excellent [Spring support](spring.html "Spring") too. Other similar frameworks (Guice, JBoss, etc) could also be used.
#lendAHandDoc()
<input type="hidden" id="ghEditPage" value="securitymanager.md.vtl"></input>