blob: 23ea7251441f68ddc24d0d43cd73a60b6d9f1cb8 [file] [log] [blame]
#parse("templates/includes.vtl")
<a name="SpringFramework-IntegratingApacheShirointoSpringbasedApplications"></a>
Integrating Apache Shiro into Spring-based Applications
===
This page covers the ways to integrate Shiro into [Spring](http://spring.io)-based applications.
<a name="SpringFramework-StandaloneApplications"></a>
Standalone Applications
---
Include the Shiro Spring dependency in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).
#dependencies('cli', [['org.apache.shiro', 'shiro-spring', "${latestRelease}"],['org.springframework', 'spring-context', '${spring.version}']])
Import the Shiro Spring configurations:
``` java
@Configuration
@Import({ShiroBeanConfiguration.class,
ShiroConfiguration.class,
ShiroAnnotationProcessorConfiguration.class})
public class CliAppConfig {
...
}
```
The above configurations do the following:
| Configuration Class | Description |
| ------------------- | ----------- |
| org.apache.shiro.spring.config.ShiroBeanConfiguration | Configures Shiro's lifecycle and events |
| org.apache.shiro.spring.config.ShiroConfiguration | Configures Shiro Beans (SecurityManager, SessionManager, etc) |
| org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration | Enables Shiro's annotation processing |
The only thing that is left is to configure a [realm](realm.html):
``` java
@Bean
public Realm realm() {
...
}
```
The easiest way to setup Shiro, so that all SecurityUtils.* methods work in all cases, is to make the `SecurityManager` bean a static singleton. DO NOT do this in web applications - see the [Web Applications](#Spring-WebApplications) section below instead.
``` java
@Autowired
private SecurityManager securityManager;
@PostConstruct
private void initStaticSecurityManager() {
SecurityUtils.setSecurityManager(securityManager);
}
```
That is it, now you can get the current `Subject` using:
``` java
SecurityUtils.getSubject();
```
You can see a full example in our [samples on Github](https://github.com/apache/shiro/tree/main/samples/spring).
<a name="SpringFramework-WebApplications"></a>
Web Applications
---
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.
Include the Shiro Spring web dependencies in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).
#dependencies('web', [['org.apache.shiro', 'shiro-spring', "${latestRelease}"], ['org.apache.shiro', 'shiro-web', "${latestRelease}"],['org.springframework', 'spring-webmvc', '${spring.version}']])
<a name="SpringFramework-WebConfig"></a>
Import the Shiro Spring configurations:
``` java
@Configuration
@Import({ShiroBeanConfiguration.class,
ShiroAnnotationProcessorConfiguration.class,
ShiroWebConfiguration.class,
ShiroWebFilterConfiguration.class,
ShiroRequestMappingConfig.class})
public class ApplicationConfig {
...
}
```
The above configurations do the following:
| Configuration Class | Description |
| ------------------- | ----------- |
| org.apache.shiro.spring.config.ShiroBeanConfiguration | Configures Shiro's lifecycle and events |
| org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration | Enables Shiro's annotation processing |
| org.apache.shiro.spring.web.config.ShiroWebConfiguration | Configures Shiro Beans for web usage (SecurityManager, SessionManager, etc) |
| org.apache.shiro.spring.web.config.ShiroWebFilterConfiguration | Configures Shiro's web filter |
| org.apache.shiro.spring.web.config.ShiroRequestMappingConfig | Configures Spring with Shiro's `UrlPathHelper` implementation to ensure URLs are processed the same both frameworks |
Provide a Realm implementation:
``` java
@Bean
public Realm realm() {
...
}
```
And finally a `ShiroFilterChainDefinition` which will map any application specific paths to a given filter, in order to allow different paths different levels of access.
``` 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;
}
```
If you are using Shiro's annotations see the [annotation](#Spring-annotations-web) section below.
You can see a full example in our [samples on Github](https://github.com/apache/shiro/tree/main/samples/spring-mvc).
<a name="Spring-annotations"></a>
Enabling Shiro Annotations
---
In both standalone and web applications, you might want to use Shiro's Annotations for security checks (for example, `@RequiresRoles`, `@RequiresPermissions`, etc.) These annotations are enabled by importing the `ShiroAnnotationProcessorConfiguration` Spring configuration in both sections above.
Simply annotate your methods in order to use them:
``` java
@RequiresPermissions("document:read")
public void readDocument() {
...
}
```
<a name="Spring-annotations-web"></a>
#[[###]]# Annotations and Web Applications
Shiro annotations are fully supported for use in `@Controller` classes, for example:
``` java
@Controller
public class AccountInfoController {
@RequiresRoles("admin")
@RequestMapping("/admin/config")
public String adminConfig(Model model) {
return "view";
}
}
```
A `ShiroFilterChainDefinition` bean with at least one definition is still required for this to work, either configure all paths to be accessable via the `anon` filter or a filter in 'permissive' mode, for example: `authcBasic[permissive]`.
``` 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;
}
```
<a name="Spring-caching"></a>
# Caching
Enabling caching is as simple as providing a [CacheManager](http://shiro.apache.org/caching.html) bean:
``` java
@Bean
protected CacheManager cacheManager() {
return new MemoryConstrainedCacheManager();
}
```
<!-- Work around for table styling until, all pages are updated. -->
#mdStyle()
# Configuration Properties
| Key | Default Value | Description |
| --- | ------------- | ----------- |
| shiro.sessionManager.deleteInvalidSessions | `true` | Remove invalid session from session storage |
| shiro.sessionManager.sessionIdCookieEnabled | `true` | Enable session ID to cookie, for session tracking |
| shiro.sessionManager.sessionIdUrlRewritingEnabled | `true` | Enable session URL rewriting support |
| shiro.userNativeSessionManager | `false` | If enabled Shiro will manage the HTTP sessions instead of the container |
| shiro.sessionManager.cookie.name | `JSESSIONID` | Session cookie name |
| shiro.sessionManager.cookie.maxAge | `-1` | Session cookie max age |
| shiro.sessionManager.cookie.domain | null | Session cookie domain |
| shiro.sessionManager.cookie.path | null | Session cookie path |
| shiro.sessionManager.cookie.secure | `false` | Session cookie secure flag |
| shiro.rememberMeManager.cookie.name | `rememberMe` | RememberMe cookie name |
| shiro.rememberMeManager.cookie.maxAge | one year | RememberMe cookie max age |
| shiro.rememberMeManager.cookie.domain | null | RememberMe cookie domain|
| shiro.rememberMeManager.cookie.path | null | RememberMe cookie path|
| shiro.rememberMeManager.cookie.secure | `false` | RememberMe cookie secure flag|
| shiro.loginUrl | `/login.jsp` | Login URL used when unauthenticated users are redirected to login page |
| shiro.successUrl | `/` | Default landing page after a user logs in (if alternative cannot be found in the current session) |
| shiro.unauthorizedUrl | null | Page to redirect user to if they are unauthorized (403 page) |
<input type="hidden" id="ghEditPage" value="spring-framework.md.vtl"></input>