You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2016/10/14 19:36:12 UTC

[09/20] shiro git commit: SHIRO-590 - Added Spring Boot starters and programatic Spring support.

SHIRO-590 - Added Spring Boot starters and programatic Spring support.


Project: http://git-wip-us.apache.org/repos/asf/shiro/repo
Commit: http://git-wip-us.apache.org/repos/asf/shiro/commit/cd3dde8a
Tree: http://git-wip-us.apache.org/repos/asf/shiro/tree/cd3dde8a
Diff: http://git-wip-us.apache.org/repos/asf/shiro/diff/cd3dde8a

Branch: refs/heads/1.4.x
Commit: cd3dde8a99d8ecc8dbe38c270a21575a1bb6de7e
Parents: 1e48dbf
Author: Brian Demers <bd...@apache.org>
Authored: Fri Sep 23 16:43:48 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 pom.xml                                         |  77 ++++++++-
 samples/pom.xml                                 |   1 +
 samples/spring-boot-web/pom.xml                 |  88 +++++++++++
 .../shiro/examples/AccountInfoController.java   |  53 +++++++
 .../apache/shiro/examples/HelloController.java  |  61 +++++++
 .../apache/shiro/examples/LoginController.java  |  34 ++++
 .../examples/RestrictedErrorController.java     |  52 ++++++
 .../java/org/apache/shiro/examples/WebApp.java  | 108 +++++++++++++
 .../src/main/resources/application.properties   |  21 +++
 .../main/resources/templates/account-info.html  |  39 +++++
 .../src/main/resources/templates/error.html     |  39 +++++
 .../resources/templates/fragments/head.html     |  54 +++++++
 .../src/main/resources/templates/hello.html     |  45 ++++++
 .../src/main/resources/templates/login.html     |  91 +++++++++++
 src/license/header.txt                          |  16 ++
 src/license/header_format.xml                   |  57 +++++++
 support/pom.xml                                 |   1 +
 support/spring-boot/pom.xml                     |  58 +++++++
 support/spring-boot/spring-boot-starter/pom.xml |  71 +++++++++
 ...iroAnnotationProcessorAutoConfiguration.java |  53 +++++++
 .../autoconfigure/ShiroAutoConfiguration.java   | 114 ++++++++++++++
 .../ShiroBeanAutoConfiguration.java             |  57 +++++++
 ...dditional-spring-configuration-metadata.json |  16 ++
 .../main/resources/META-INF/spring.factories    |   1 +
 .../src/main/resources/META-INF/spring.provides |   1 +
 .../ShiroSpringAutoConfigurationTest.groovy     |  78 +++++++++
 .../ShiroAutoConfigurationTestApplication.java  |  84 ++++++++++
 .../spring-boot/spring-boot-web-starter/pom.xml |  89 +++++++++++
 ...iroAnnotationProcessorAutoConfiguration.java |  53 +++++++
 .../ShiroBeanAutoConfiguration.java             |  57 +++++++
 .../ShiroWebAutoConfiguration.java              | 138 ++++++++++++++++
 .../ShiroWebFilterConfiguration.java            |  54 +++++++
 ...dditional-spring-configuration-metadata.json |  46 ++++++
 .../main/resources/META-INF/spring.factories    |   1 +
 .../src/main/resources/META-INF/spring.provides |   1 +
 .../ShiroWebSpringAutoConfigurationTest.groovy  |  70 +++++++++
 ...hiroWebAutoConfigurationTestApplication.java |  91 +++++++++++
 .../spring/LifecycleBeanPostProcessor.java      |  11 ++
 .../spring/ShiroEventBusBeanPostProcessor.java  |  73 +++++++++
 ...ctShiroAnnotationProcessorConfiguration.java |  41 +++++
 .../config/AbstractShiroBeanConfiguration.java  |  43 +++++
 .../config/AbstractShiroConfiguration.java      | 152 ++++++++++++++++++
 .../ShiroAnnotationProcessorConfiguration.java  |  46 ++++++
 .../spring/config/ShiroBeanConfiguration.java   |  50 ++++++
 .../shiro/spring/config/ShiroConfiguration.java | 109 +++++++++++++
 .../config/AbstractShiroWebConfiguration.java   | 157 +++++++++++++++++++
 .../AbstractShiroWebFilterConfiguration.java    |  59 +++++++
 .../DefaultShiroFilterChainDefinition.java      |  44 ++++++
 .../web/config/ShiroFilterChainDefinition.java  |  29 ++++
 .../web/config/ShiroWebConfiguration.java       | 120 ++++++++++++++
 .../web/config/ShiroWebFilterConfiguration.java |  37 +++++
 .../config/ShiroBeanConfigurationTest.groovy    |  60 +++++++
 .../spring/config/ShiroConfigurationTest.groovy |  75 +++++++++
 ...nfigurationWithOptionalComponentsTest.groovy |  73 +++++++++
 ...iroEventBusAwareBeanPostProcessorTest.groovy |  69 ++++++++
 .../web/config/ShiroWebConfigurationTest.groovy | 106 +++++++++++++
 .../ShiroWebConfigurationWithCacheTest.groovy   |  57 +++++++
 .../EventBusConsumersTestConfiguration.java     |  61 +++++++
 .../config/EventBusTestConfiguration.java       |  37 +++++
 .../OptionalComponentsTestConfiguration.java    |  57 +++++++
 .../spring/config/RealmTestConfiguration.java   |  44 ++++++
 .../web/config/CacheManagerConfiguration.java   |  33 ++++
 test-coverage/pom.xml                           |  97 ++++++++++++
 63 files changed, 3707 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a65a52c..b219d6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -91,16 +91,22 @@
         <quartz.version>1.6.1</quartz.version>
         <slf4j.version>1.6.4</slf4j.version>
         <spring.version>3.1.0.RELEASE</spring.version>
+        <spring-boot.version>1.4.0.RELEASE</spring-boot.version>
         <guice.version>3.0</guice.version>
 
         <!-- Test 3rd-party dependencies: -->
-        <easymock.version>3.1</easymock.version>
+        <easymock.version>3.4</easymock.version>
         <gmaven.version>1.3</gmaven.version>
         <groovy.version>1.8.5</groovy.version>
-        <junit.version>4.8.2</junit.version>
+        <junit.version>4.12</junit.version>
         <!-- so we can mock static methods in 3rd party libraries that sometimes don't use proper interfaces
              ahem, hazelcast, ahem... -->
-        <powermock.version>1.5</powermock.version>
+        <powermock.version>1.6.5</powermock.version>
+
+        <maven.compiler.source>${jdk.version}</maven.compiler.source>
+        <maven.compiler.target>${jdk.version}</maven.compiler.target>
+
+        <root.dir>${session.executionRootDirectory}</root.dir>
 
     </properties>
 
@@ -198,6 +204,7 @@
         <module>samples</module>
         <module>tools</module>
         <module>all</module>
+        <module>test-coverage</module>
     </modules>
 
     <build>
@@ -233,6 +240,9 @@
                             <exclude>**/infinitest.filters</exclude>
                             <!-- Apparently some test in samples/spring-client generates velocity log - would better to reconfigure to output to target/ -->
                             <exclude>velocity.log</exclude>
+                            <exclude>**/*.json</exclude>
+                            <exclude>**/spring.factories</exclude>
+                            <exclude>**/spring.provides</exclude>
                         </excludes>
                     </configuration>
                 </plugin>
@@ -354,6 +364,21 @@
                     <artifactId>jacoco-maven-plugin</artifactId>
                     <version>0.7.7.201606060606</version>
                 </plugin>
+                <plugin>
+                    <groupId>com.mycila</groupId>
+                    <artifactId>license-maven-plugin</artifactId>
+                    <version>3.0</version>
+                    <configuration>
+                        <aggregate>true</aggregate>
+                        <header>${root.dir}/src/license/header.txt</header>
+                        <headerDefinitions>
+                            <headerDefinition>${root.dir}/src/license/header_format.xml</headerDefinition>
+                        </headerDefinitions>
+                        <excludes>
+                            <exclude>**/*.txt</exclude>
+                        </excludes>
+                    </configuration>
+                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>
@@ -487,6 +512,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>java-hamcrest</artifactId>
+            <version>2.0.0.0</version>
+        </dependency>
+        <dependency>
             <groupId>org.easymock</groupId>
             <artifactId>easymock</artifactId>
             <version>${easymock.version}</version>
@@ -553,6 +583,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-cas</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-all</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -561,6 +596,16 @@
                 <artifactId>samples-spring-client</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-spring-boot-starter</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-spring-boot-web-starter</artifactId>
+                <version>${project.version}</version>
+            </dependency>
 
             <!-- Intra project test dependencies: -->
             <dependency>
@@ -839,6 +884,29 @@
                     </exclusion>
                 </exclusions>
             </dependency>
+
+            <!-- Spring Boot-->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-autoconfigure</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-configuration-processor</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-test</artifactId>
+                <version>${spring-boot.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>com.google.inject</groupId>
                 <artifactId>guice</artifactId>
@@ -957,6 +1025,9 @@
                         <exclude>**/infinitest.filters</exclude>
                         <!-- Apparently some test in samples/spring-client generates velocity log - would better to reconfigure to output to target/ -->
                         <exclude>velocity.log</exclude>
+                        <exclude>**/*.json</exclude>
+                        <exclude>**/spring.factories</exclude>
+                        <exclude>**/spring.provides</exclude>
                     </excludes>
                 </configuration>
             </plugin>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 5e6a023..c48092a 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -39,6 +39,7 @@
         <module>spring-client</module>
         <module>spring</module>
         <module>spring-hibernate</module>
+        <module>spring-boot-web</module>
         <module>guice</module>
         <module>quickstart-guice</module>
     </modules>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/pom.xml b/samples/spring-boot-web/pom.xml
new file mode 100644
index 0000000..4aef911
--- /dev/null
+++ b/samples/spring-boot-web/pom.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-spring-boot</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>samples-spring-boot-web</artifactId>
+    <name>Apache Shiro :: Samples :: Spring Boot Web</name>
+
+    <properties>
+        <!-- These spring-boot modules require spring 4 -->
+        <spring.version>4.3.2.RELEASE</spring.version>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring-boot-web-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+            <version>${spring-boot.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Spring -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/AccountInfoController.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/AccountInfoController.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/AccountInfoController.java
new file mode 100644
index 0000000..fa721f5
--- /dev/null
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/AccountInfoController.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.examples;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+@Controller
+public class AccountInfoController {
+
+    @RequiresRoles("admin")
+    @RequestMapping("/account-info")
+    public String home(Model model) {
+
+        String name = "World";
+
+        Subject subject = SecurityUtils.getSubject();
+
+        PrincipalCollection principalCollection = subject.getPrincipals();
+
+        if (!CollectionUtils.isEmpty(principalCollection)) {
+            name = principalCollection.getPrimaryPrincipal().toString();
+        }
+
+        model.addAttribute("name", name);
+
+        return "account-info";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/HelloController.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/HelloController.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/HelloController.java
new file mode 100644
index 0000000..45637b8
--- /dev/null
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/HelloController.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.examples;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Collection;
+import java.util.Map;
+
+@Controller
+public class HelloController {
+
+    @SuppressWarnings("Duplicates")
+    @RequestMapping("/")
+    public String home(HttpServletRequest request, Model model) {
+
+        String name = "World";
+
+        Subject subject = SecurityUtils.getSubject();
+
+        PrincipalCollection principalCollection = subject.getPrincipals();
+
+        if (!CollectionUtils.isEmpty(principalCollection)) {
+            Collection<Map> principalMaps = subject.getPrincipals().byType(Map.class);
+            if (CollectionUtils.isEmpty(principalMaps)) {
+                name = subject.getPrincipal().toString();
+            }
+            else {
+                name = (String) principalMaps.iterator().next().get("username");
+            }
+        }
+
+        model.addAttribute("name", name);
+
+        return "hello";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/LoginController.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/LoginController.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/LoginController.java
new file mode 100644
index 0000000..7667795
--- /dev/null
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/LoginController.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.examples;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+@Controller
+public class LoginController {
+
+    @RequestMapping("/login.html")
+    public String loginTemplate() {
+
+        return "login";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/RestrictedErrorController.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/RestrictedErrorController.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/RestrictedErrorController.java
new file mode 100644
index 0000000..240a8fc
--- /dev/null
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/RestrictedErrorController.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.examples;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.web.ErrorAttributes;
+import org.springframework.boot.autoconfigure.web.ErrorController;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ */
+@Controller
+public class RestrictedErrorController implements ErrorController {
+    private static final String ERROR_PATH = "/error";
+
+    @Autowired
+    private ErrorAttributes errorAttributes;
+
+    @Override
+    public String getErrorPath() {
+        return ERROR_PATH;
+    }
+
+    @RequestMapping(ERROR_PATH)
+    String error(HttpServletRequest request, Model model) {
+        Map<String, Object> errorMap = errorAttributes.getErrorAttributes(new ServletRequestAttributes(request), false);
+        model.addAttribute("errors", errorMap);
+        return "error";
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/WebApp.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/WebApp.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/WebApp.java
new file mode 100644
index 0000000..3871b4a
--- /dev/null
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/examples/WebApp.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.examples;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.TextConfigurationRealm;
+import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.web.filter.mgt.DefaultFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpStatus;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+import java.security.Security;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@ControllerAdvice
+@SpringBootApplication
+public class WebApp { //NOPMD
+
+    private static Logger log = LoggerFactory.getLogger(WebApp.class);
+
+    public static void main(String[] args) {
+
+        SpringApplication.run(WebApp.class, args);
+    }
+
+    @ExceptionHandler(AuthorizationException.class)
+    @ResponseStatus(HttpStatus.FORBIDDEN)
+    public String handleException(AuthorizationException e, Model model) {
+
+        // you could return a 404 here instead (this is how github handles 403, so the user does NOT know there is a
+        // resource at that location)
+        log.debug("AuthorizationException was thrown", e);
+
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("status", HttpStatus.FORBIDDEN.value());
+        map.put("message", "No message available");
+        model.addAttribute("errors", map);
+
+        return "error";
+    }
+
+//
+//    @Bean
+//    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
+//        DefaultShiroFilterChainDefinition filterChainDefinition = new DefaultShiroFilterChainDefinition();
+//        filterChainDefinition.addPathDefinition("/assets/**", DefaultFilter.anon.name()); // static web resources
+//        filterChainDefinition.addPathDefinition("/", DefaultFilter.anon.name());  // the welcome page allows guest or logged in users
+//        filterChainDefinition.addPathDefinition("/account-info", DefaultFilter.authc.name()); // the account-info page requires a user
+//        return filterChainDefinition;
+//    }
+
+    @Bean
+    public Realm realm() {
+        TextConfigurationRealm realm = new TextConfigurationRealm();
+        realm.setUserDefinitions("joe.coder=password,user\n" +
+                "jill.coder=password,admin");
+
+        realm.setRoleDefinitions("admin=read,write\n" +
+                "user=read");
+        realm.setCachingEnabled(true);
+        return realm;
+    }
+
+    @Bean
+    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
+        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
+        chainDefinition.addPathDefinition("/login.html", "authc"); // need to accept POSTs from the login form
+        chainDefinition.addPathDefinition("/logout", "logout");
+        return chainDefinition;
+    }
+
+    @ModelAttribute(name = "subject")
+    public Subject subject() {
+        return SecurityUtils.getSubject();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/application.properties b/samples/spring-boot-web/src/main/resources/application.properties
new file mode 100644
index 0000000..d153c17
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/application.properties
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+
+shiro.loginUrl = /login.html
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/templates/account-info.html
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/templates/account-info.html b/samples/spring-boot-web/src/main/resources/templates/account-info.html
new file mode 100644
index 0000000..1fc0ca9
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/templates/account-info.html
@@ -0,0 +1,39 @@
+<!--
+  ~ 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.
+  -->
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+    <head>
+        <title>Account Info</title>
+        <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->
+    </head>
+    <body>
+        <div class="container">
+            <h1 th:text="'Account Info Page for: ' + ${name} + '!'"/>
+
+            <a th:href="@{/}" class="btn btn-primary">Home</a>
+
+            <form id="logoutForm" th:action="@{/logout}" method="post">
+                <input type="submit" class="btn btn-danger" value="Logout"/>
+            </form>
+
+        </div>
+        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
+        <script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/templates/error.html
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/templates/error.html b/samples/spring-boot-web/src/main/resources/templates/error.html
new file mode 100644
index 0000000..77362a3
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/templates/error.html
@@ -0,0 +1,39 @@
+<!--
+  ~ 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 xmlns:th="http://www.thymeleaf.org">
+<head>
+    <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->
+</head>
+<body>
+<div class="container-fluid">
+    <div class="row">
+        <div class="box col-md-6 col-md-offset-3">
+            <div class="custom-header">
+                <img src="http://shiro.apache.org/assets/images/apache-shiro-logo.png"/>
+            </div>
+            <div class="logo">
+                <h1 th:text="${errors.status}"></h1>
+            </div>
+            <p class="lead text-muted" th:text="${errors.message}">Unauthorized</p>
+            <a href="/" class="btn btn-primary">Go Home</a>
+        </div>
+    </div>
+</div>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/templates/fragments/head.html
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/templates/fragments/head.html b/samples/spring-boot-web/src/main/resources/templates/fragments/head.html
new file mode 100644
index 0000000..58ab413
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/templates/fragments/head.html
@@ -0,0 +1,54 @@
+<!--
+  ~ 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.
+  -->
+<!DOCTYPE html>
+<html xmlns:th="http://www.thymeleaf.org">
+<head th:fragment="head">
+    <meta charset="utf-8"/>
+    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <meta name="viewport" content="width=device-width"/>
+    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,300,400italic,400,600italic,600,700italic,700,800italic,800" rel="stylesheet" type="text/css"/>
+    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
+
+    <style>
+        body {
+            margin-top: 60px;
+        }
+        .box {
+            padding: 50px;
+            text-align: center;
+            vertical-align: middle;
+        }
+        .custom-header {
+            /*background-color: #161616;*/
+            border: 2px solid #3254a0;
+        }
+    </style>
+
+    <!--[if lt IE 9]>
+    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.2/html5shiv.js"></script>
+    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
+    <![endif]-->
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
+    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
+</head>
+<body>
+<p>Nothing to see here, move along.</p>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/templates/hello.html
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/templates/hello.html b/samples/spring-boot-web/src/main/resources/templates/hello.html
new file mode 100644
index 0000000..cc198be
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/templates/hello.html
@@ -0,0 +1,45 @@
+<!--
+  ~ 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.
+  -->
+<!DOCTYPE HTML>
+<html xmlns:th="http://www.thymeleaf.org">
+    <head>
+        <title>Getting Started: Serving Web Content</title>
+        <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->
+    </head>
+    <body>
+        <div class="container">
+            <h1 th:text="'Hello, ' + ${name} + '!'"/>
+
+            <div th:unless="${subject.authenticated}">
+                <a th:href="@{/login.html}" class="btn btn-primary">Login</a>
+            </div>
+            <div th:if="${subject.authenticated}">
+                <h4 th:text="'Principal: ' + ${subject.principal}"></h4>
+                <form id="logoutForm" th:action="@{/logout}" method="post">
+                    <input type="submit" class="btn btn-danger" value="Logout"/>
+                </form>
+            </div>
+
+            <h4><a th:href="@{/account-info}" class="btn btn-primary">Account info</a>&nbsp;(Requires 'admin' role.)</h4>
+
+        </div>
+        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
+        <script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/samples/spring-boot-web/src/main/resources/templates/login.html
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/resources/templates/login.html b/samples/spring-boot-web/src/main/resources/templates/login.html
new file mode 100644
index 0000000..7c9c5aa
--- /dev/null
+++ b/samples/spring-boot-web/src/main/resources/templates/login.html
@@ -0,0 +1,91 @@
+<!--
+  ~ 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.
+  -->
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <title>Getting Started: Serving Web Content</title>
+        <!--/*/ <th:block th:include="fragments/head :: head"/> /*/-->
+    </head>
+    <body>
+        <div class="container">
+
+
+            <div class="row">
+                <div class="col-md-4 col-md-offset-4">
+                    <p>Here are a few sample accounts to play with from the text-based Realm</p>
+                    <table class="table">
+                        <thead>
+                        <tr>
+                            <th>Username</th>
+                            <th>Password</th>
+                            <th>Roles</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        <tr>
+                            <td>joe.coder</td>
+                            <td>password</td>
+                            <td>user</td>
+                        </tr>
+                        <tr>
+                            <td>jill.coder</td>
+                            <td>password</td>
+                            <td>admin</td>
+                        </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+
+            <div class="row">
+                <div class="col-md-4 col-md-offset-4">
+                    <div class="panel panel-default">
+                        <div class="panel-heading">
+                            <h3 class="panel-title">Login</h3>
+                        </div>
+                        <div class="panel-body">
+                            <form name="loginform" action="" method="POST" accept-charset="UTF-8" role="form">
+                                <fieldset>
+                                    <div class="form-group">
+                                        <input class="form-control" placeholder="Username or Email" name="username" type="text"/>
+                                    </div>
+                                    <div class="form-group">
+                                        <input class="form-control" placeholder="Password" name="password" type="password" value=""/>
+                                    </div>
+
+                                    <input class="btn btn-lg btn-success btn-block" type="submit" value="Login"/>
+                                </fieldset>
+                            </form>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
+        <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
+        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
+        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
+        <!--[if lt IE 9]>
+        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
+        <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
+        <![endif]-->
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/src/license/header.txt
----------------------------------------------------------------------
diff --git a/src/license/header.txt b/src/license/header.txt
new file mode 100644
index 0000000..c1640de
--- /dev/null
+++ b/src/license/header.txt
@@ -0,0 +1,16 @@
+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.
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/src/license/header_format.xml
----------------------------------------------------------------------
diff --git a/src/license/header_format.xml b/src/license/header_format.xml
new file mode 100644
index 0000000..c164bc6
--- /dev/null
+++ b/src/license/header_format.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  ~ 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.
+  -->
+<additionalHeaders>
+    <xml_style>
+        <firstLine><![CDATA[<!--]]></firstLine>
+        <beforeEachLine>  ~ </beforeEachLine>
+        <endLine><![CDATA[  -->]]></endLine>
+        <!--<afterEachLine><![CDATA[]]></afterEachLine>-->
+        <skipLine><![CDATA[^<\?xml.*>$]]></skipLine>
+        <firstLineDetectionPattern><![CDATA[(\s|\t)*<!--.*$]]></firstLineDetectionPattern>
+        <lastLineDetectionPattern><![CDATA[.*-->(\s|\t)*$]]></lastLineDetectionPattern>
+        <allowBlankLines>false</allowBlankLines>
+        <isMultiline>true</isMultiline>
+        <padLines>false</padLines>
+    </xml_style>
+    <javadoc_style>
+        <firstLine>/*</firstLine>
+        <beforeEachLine> * </beforeEachLine>
+        <endLine> */</endLine>
+        <!--<afterEachLine></afterEachLine>-->
+        <!--skipLine></skipLine-->
+        <firstLineDetectionPattern>(\s|\t)*/\*.*$</firstLineDetectionPattern>
+        <lastLineDetectionPattern>.*\*/(\s|\t)*$</lastLineDetectionPattern>
+        <allowBlankLines>false</allowBlankLines>
+        <isMultiline>true</isMultiline>
+        <padLines>false</padLines>
+    </javadoc_style>
+    <dynascript_style>
+        <firstLine><![CDATA[<%--EOL]]></firstLine>
+        <beforeEachLine>  ~ </beforeEachLine>
+        <endLine><![CDATA[EOL  --%>]]></endLine>
+        <firstLineDetectionPattern><![CDATA[(\s|\t)*<%--.*$]]></firstLineDetectionPattern>
+        <lastLineDetectionPattern><![CDATA[.*--%>(\s|\t)*$]]></lastLineDetectionPattern>
+        <allowBlankLines>false</allowBlankLines>
+        <isMultiline>true</isMultiline>
+        <padLines>false</padLines>
+    </dynascript_style>
+
+
+</additionalHeaders>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index 77a94db..b30b471 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -40,6 +40,7 @@
         <module>guice</module>
         <module>features</module>
         <module>cas</module>
+        <module>spring-boot</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/pom.xml
----------------------------------------------------------------------
diff --git a/support/spring-boot/pom.xml b/support/spring-boot/pom.xml
new file mode 100644
index 0000000..94cf20c
--- /dev/null
+++ b/support/spring-boot/pom.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-root</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>shiro-spring-boot</artifactId>
+    <name>Apache Shiro :: Support :: Spring Boot Parent</name>
+    <packaging>pom</packaging>
+
+    <properties>
+        <!-- These spring-boot modules require spring 4 -->
+        <spring.version>4.3.2.RELEASE</spring.version>
+    </properties>
+
+    <modules>
+        <module>spring-boot-starter</module>
+        <module>spring-boot-web-starter</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <!--
+            The spring test API uses mockito, as much as I prefer mockito over easymock, one mock framework is
+            probably enough, so putting in this pom makes that more obvious.
+            -->
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>1.10.17</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/pom.xml
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/pom.xml b/support/spring-boot/spring-boot-starter/pom.xml
new file mode 100644
index 0000000..d9ad99a
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-spring-boot</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>shiro-spring-boot-starter</artifactId>
+    <name>Apache Shiro :: Support :: Spring Boot</name>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+        </dependency>
+
+        <!-- Spring -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
new file mode 100644
index 0000000..6c00d29
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure;
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.config.AbstractShiroAnnotationProcessorConfiguration;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @since 1.4.0
+ */
+@SuppressWarnings("SpringFacetCodeInspection")
+@Configuration
+@ConditionalOnProperty(name = "shiro.annotations.enabled", matchIfMissing = true)
+public class ShiroAnnotationProcessorAutoConfiguration extends AbstractShiroAnnotationProcessorConfiguration {
+
+    @Bean
+    @DependsOn("lifecycleBeanPostProcessor")
+    @ConditionalOnMissingBean
+    @Override
+    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        return super.defaultAdvisorAutoProxyCreator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+        return super.authorizationAttributeSourceAdvisor(securityManager);
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfiguration.java b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfiguration.java
new file mode 100644
index 0000000..e013a4b
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfiguration.java
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure;
+
+import org.apache.shiro.authc.Authenticator;
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authz.Authorizer;
+import org.apache.shiro.mgt.SessionStorageEvaluator;
+import org.apache.shiro.mgt.SessionsSecurityManager;
+import org.apache.shiro.mgt.SubjectDAO;
+import org.apache.shiro.mgt.SubjectFactory;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.session.mgt.SessionFactory;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.apache.shiro.spring.config.AbstractShiroConfiguration;
+import org.apache.shiro.spring.config.ShiroBeanConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+import java.util.List;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+@SuppressWarnings("SpringFacetCodeInspection")
+@ConditionalOnProperty(name = "shiro.enabled", matchIfMissing = true)
+public class ShiroAutoConfiguration extends AbstractShiroConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected AuthenticationStrategy authenticationStrategy() {
+        return super.authenticationStrategy();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected Authenticator authenticator() {
+        return super.authenticator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SubjectDAO subjectDAO() {
+        return super.subjectDAO();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionStorageEvaluator sessionStorageEvaluator() {
+        return super.sessionStorageEvaluator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SubjectFactory subjectFactory() {
+        return super.subjectFactory();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionFactory sessionFactory() {
+        return super.sessionFactory();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionDAO sessionDAO() {
+        return super.sessionDAO();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionManager sessionManager() {
+        return super.sessionManager();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionsSecurityManager securityManager(List<Realm> realms) {
+        return super.securityManager(realms);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
new file mode 100644
index 0000000..9e9cbe1
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/java/org/apache/shiro/spring/boot/autoconfigure/ShiroBeanAutoConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.config.AbstractShiroBeanConfiguration;
+import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+@ConditionalOnProperty(name = "shiro.enabled", matchIfMissing = true)
+public class ShiroBeanAutoConfiguration extends AbstractShiroBeanConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return super.lifecycleBeanPostProcessor();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected EventBus eventBus() {
+        return super.eventBus();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public ShiroEventBusBeanPostProcessor shiroEventBusAwareBeanPostProcessor() {
+        return super.shiroEventBusAwareBeanPostProcessor();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
new file mode 100644
index 0000000..c498c16
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -0,0 +1,16 @@
+{
+  "groups": [
+    {
+      "name": "shiro"
+    },
+  ],
+  "properties": [
+
+    {
+      "name": "shiro.enabled",
+      "type": "java.lang.Boolean",
+      "description": "A boolean flag that can disable all Shiro Spring Boot starters.  This is mostly useful during testing or debugging, or if you want to compare behavior when Shiro is enabled or disabled.",
+      "defaultValue": true
+    },
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.factories b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..6d6f529
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration = org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration,org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfiguration,org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.provides
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.provides b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000..1749212
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: shiro
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/ShiroSpringAutoConfigurationTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/ShiroSpringAutoConfigurationTest.groovy b/support/spring-boot/spring-boot-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/ShiroSpringAutoConfigurationTest.groovy
new file mode 100644
index 0000000..d2c6b12
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/ShiroSpringAutoConfigurationTest.groovy
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure
+
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfigurationTestApplication.EventBusAwareObject;
+import org.apache.shiro.spring.boot.autoconfigure.ShiroAutoConfigurationTestApplication.SubscribedListener;
+
+import org.apache.shiro.authc.UsernamePasswordToken
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.mgt.DefaultSecurityManager
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.subject.Subject
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
+
+import static org.junit.Assert.*;
+
+/**
+ * @since 1.4.0
+ */
+@SpringBootTest(classes = [ShiroAutoConfigurationTestApplication])
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ShiroSpringAutoConfigurationTest {
+
+    @Autowired
+    private SecurityManager securityManager
+
+    @Autowired
+    private EventBus eventBus
+
+    @Autowired
+    private EventBusAwareObject eventBusAwareObject
+
+    @Autowired
+    private SubscribedListener subscribedListener
+
+    @Test
+    public void testMinimalConfiguration() {
+
+        // first do a quick check of the injected objects
+        assertNotNull securityManager
+
+        assertNotNull eventBusAwareObject
+        assertNotNull eventBus
+        assertTrue(eventBus.registry.containsKey(subscribedListener))
+        assertSame(eventBusAwareObject.getEventBus(), eventBus)
+        assertSame(((DefaultSecurityManager)securityManager).getEventBus(), eventBus)
+
+        // now lets do a couple quick permission tests to make sure everything has been initialized correctly.
+        Subject joeCoder = new Subject.Builder(securityManager).buildSubject()
+        joeCoder.login(new UsernamePasswordToken("joe.coder", "password"))
+        joeCoder.checkPermission("read")
+        assertTrue joeCoder.hasRole("user")
+        assertFalse joeCoder.hasRole("admin")
+        joeCoder.logout()
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfigurationTestApplication.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfigurationTestApplication.java b/support/spring-boot/spring-boot-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfigurationTestApplication.java
new file mode 100644
index 0000000..914e48e
--- /dev/null
+++ b/support/spring-boot/spring-boot-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/ShiroAutoConfigurationTestApplication.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure;
+
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.TextConfigurationRealm;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableAutoConfiguration
+public class ShiroAutoConfigurationTestApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ShiroAutoConfigurationTestApplication.class, args);
+    }
+
+    @Bean
+    @SuppressWarnings("Duplicates")
+    Realm getTextConfigurationRealm() {
+
+        TextConfigurationRealm realm = new TextConfigurationRealm();
+        realm.setUserDefinitions("joe.coder=password,user\n" +
+                                 "jill.coder=password,admin");
+
+        realm.setRoleDefinitions("admin=read,write\n" +
+                                 "user=read");
+        realm.setCachingEnabled(true);
+        return realm;
+    }
+
+    @Bean
+    EventBusAwareObject eventBusAwareObject() {
+        return new EventBusAwareObject();
+    }
+
+    @Bean
+    SubscribedListener subscribedListener() {
+        return new SubscribedListener();
+    }
+
+
+    public static class EventBusAwareObject implements EventBusAware {
+
+        private EventBus eventBus;
+
+        @Override
+        public void setEventBus(EventBus bus) {
+            this.eventBus = bus;
+        }
+
+        public EventBus getEventBus() {
+            return eventBus;
+        }
+    }
+
+    public static class SubscribedListener {
+
+        @Subscribe
+        public void onEvent(Object object) {}
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/pom.xml
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/pom.xml b/support/spring-boot/spring-boot-web-starter/pom.xml
new file mode 100644
index 0000000..15d9d9a
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/pom.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<!--suppress osmorcNonOsgiMavenDependency -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-spring-boot</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>shiro-spring-boot-web-starter</artifactId>
+    <name>Apache Shiro :: Support :: Spring Boot Web</name>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.1.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Spring -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+            <version>${spring-boot.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>${spring-boot.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
new file mode 100644
index 0000000..c740fcf
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroAnnotationProcessorAutoConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.config.web.autoconfigure;
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.config.AbstractShiroAnnotationProcessorConfiguration;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @since 1.4.0
+ */
+@SuppressWarnings("SpringFacetCodeInspection")
+@Configuration
+@ConditionalOnProperty(name = "shiro.annotations.enabled", matchIfMissing = true)
+public class ShiroAnnotationProcessorAutoConfiguration extends AbstractShiroAnnotationProcessorConfiguration {
+
+    @Bean
+    @DependsOn("lifecycleBeanPostProcessor")
+    @ConditionalOnMissingBean
+    @Override
+    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        return super.defaultAdvisorAutoProxyCreator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+        return super.authorizationAttributeSourceAdvisor(securityManager);
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroBeanAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroBeanAutoConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroBeanAutoConfiguration.java
new file mode 100644
index 0000000..24ff025
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroBeanAutoConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.apache.shiro.spring.config.web.autoconfigure;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.config.AbstractShiroBeanConfiguration;
+import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
+public class ShiroBeanAutoConfiguration extends AbstractShiroBeanConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return super.lifecycleBeanPostProcessor();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public EventBus eventBus() {
+        return super.eventBus();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    public ShiroEventBusBeanPostProcessor shiroEventBusAwareBeanPostProcessor() {
+        return super.shiroEventBusAwareBeanPostProcessor();
+    }
+}