| = Integrating Apache Shiro into Spring-based Applications |
| :jbake-date: 2010-03-18 00:00:00 |
| :jbake-type: page |
| :jbake-status: published |
| :jbake-tags: documentation, manual, spring |
| :idprefix: |
| :toc: |
| |
| This page covers the ways to integrate Shiro into link:https://spring.io[Spring]-based applications. |
| |
| == 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.dependencies anchorId="cli" deps=[{'g':'org.apache.shiro', 'a':'shiro-spring', "v":"${versions.latestRelease}"},{"g":'org.springframework', "a":'spring-context', "v":'${r"${spring.version}"}'}] /> |
| ++++ |
| |
| Import the Shiro Spring configurations: |
| |
| [source,java] |
| ---- |
| @Configuration |
| @Import({ShiroBeanConfiguration.class, |
| ShiroConfiguration.class, |
| ShiroAnnotationProcessorConfiguration.class}) |
| public class CliAppConfig { |
| ... |
| } |
| ---- |
| |
| The above configurations do the following: |
| |
| [width="100%",cols="55%,45%",options="header",] |
| |=== |
| |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 link:realm.html[realm]: |
| |
| [source,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 link:#web_applications[Web Applications] section below instead. |
| |
| [source,java] |
| ---- |
| @Autowired |
| private SecurityManager securityManager; |
| |
| @PostConstruct |
| private void initStaticSecurityManager() { |
| SecurityUtils.setSecurityManager(securityManager); |
| } |
| ---- |
| |
| That is it, now you can get the current `Subject` using: |
| [source,java] |
| ---- |
| SecurityUtils.getSubject(); |
| ---- |
| |
| You can see a full example in our link:https://github.com/apache/shiro/tree/main/samples/spring[samples on Github]. |
| |
| [#web_applications] |
| == 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.dependencies anchorId="web" deps=[{"g":'org.apache.shiro', "a":'shiro-spring', "v":"${versions.latestRelease}"}, {"g":'org.apache.shiro', "a":'shiro-web', "v":"${versions.latestRelease}"},{"g":'org.springframework', "a":'spring-webmvc', "v":'${r"${spring.version}"}'}] /> |
| ++++ |
| |
| Import the Shiro Spring configurations: |
| |
| [source,java] |
| ---- |
| @Configuration |
| @Import({ShiroBeanConfiguration.class, |
| ShiroAnnotationProcessorConfiguration.class, |
| ShiroWebConfiguration.class, |
| ShiroWebFilterConfiguration.class, |
| ShiroRequestMappingConfig.class}) |
| public class ApplicationConfig { |
| ... |
| } |
| ---- |
| |
| The above configurations do the following: |
| |
| [width="100%",cols="55%,45%",options="header",] |
| |=== |
| |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: |
| [source,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. |
| |
| [source,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 link:#annotations_and_web_applications[annotation] section below. |
| |
| You can see a full example in our link:https://github.com/apache/shiro/tree/main/samples/spring-mvc[samples on Github]. |
| |
| == 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: |
| |
| [source,java] |
| ---- |
| @RequiresPermissions("document:read") |
| public void readDocument() { |
| ... |
| } |
| ---- |
| |
| === Annotations and Web Applications |
| |
| Shiro annotations are fully supported for use in `@Controller` classes, for example: |
| |
| [source,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]`. |
| |
| [source,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; |
| } |
| ---- |
| |
| == Caching |
| |
| Enabling caching is as simple as providing a link:https://shiro.apache.org/caching.html[CacheManager] bean: |
| |
| [source,java] |
| ---- |
| @Bean |
| protected CacheManager cacheManager() { |
| return new MemoryConstrainedCacheManager(); |
| } |
| ---- |
| |
| |
| == Configuration Properties |
| |
| [width="100%",cols="36%,14%,40%",options="header",] |
| |=== |
| |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) |
| |=== |
| |
| |
| |