Fork me on GitHub

Simple. Java. Security.

Integrating Apache Shiro into Spring-Boot Applications

Shiro’s Spring-Boot integration is the easiest way to integrate Shiro into a Spring-base application, for more general Spring Framework integration, take a the annotation or XML guides.

Standalone Applications

Include the Shiro Spring starter dependency in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.7.0</version>
</dependency>
compile 'org.apache.shiro:shiro-spring-boot-starter:1.7.0'

The only thing that is left is to configure a realm:

@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 section below instead.

@Autowired
private SecurityManager securityManager;
    
 @PostConstruct
 private void initStaticSecurityManager() {
     SecurityUtils.setSecurityManager(securityManager);
 }

That is it, now you can get the current Subject using:

SecurityUtils.getSubject();

You can see a full example in our samples on Github.

Web Applications

Shiro has first-class support for Spring web applications. In a web application, all Shiro-accessible web requests must go through a master Shiro Filter. This filter itself is extremely powerful, allowing for ad-hoc custom filter chains to be executed based on any URL path expression.

First include the Shiro Spring web starter dependency in you application classpath (we recomend using a tool such as Apache Maven or Gradle to manage this).

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-web-starter</artifactId>
    <version>1.7.0</version>
</dependency>
compile 'org.apache.shiro:shiro-spring-boot-web-starter:1.7.0'

Provide a Realm implementation:

@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.

@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 section below.

You can see a full example in our 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 automatically in both starters listed above.

Simply annotate your methods in order to use them:

@RequiresPermissions("document:read")
public void readDocument() {
    ...
}

Annotations and Web Applications

Shiro annotations are fully supported for use in @Controller classes, for example:

@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].

@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 CacheManager bean:

@Bean
protected CacheManager cacheManager() {
    return new MemoryConstrainedCacheManager();
}

Configuration Properties

Key Default Value Description
shiro.enabled true Enables Shiro’s Spring module
shiro.web.enabled true Enables Shiro’s Spring web module
shiro.annotations.enabled true Enables Spring support for Shiro’s annotations
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)