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/aa2cd4fc
Tree: http://git-wip-us.apache.org/repos/asf/shiro/tree/aa2cd4fc
Diff: http://git-wip-us.apache.org/repos/asf/shiro/diff/aa2cd4fc

Branch: refs/heads/master
Commit: aa2cd4fca10416623ecc29008cd851a4f1ed3d98
Parents: d9715bc
Author: Brian Demers <bdem...@apache.org>
Authored: Fri Sep 23 16:43:48 2016 -0400
Committer: Brian Demers <bdem...@apache.org>
Committed: Tue Oct 18 11:45:44 2016 -0400

----------------------------------------------------------------------
 all/pom.xml                                     |   4 -
 pom.xml                                         |  79 ++++++++--
 samples/pom.xml                                 |   3 +-
 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 ++++++++++++
 64 files changed, 3704 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/aa2cd4fc/all/pom.xml
----------------------------------------------------------------------
diff --git a/all/pom.xml b/all/pom.xml
index e555355..cde82cc 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -75,10 +75,6 @@
         </dependency>
         <dependency>
             <groupId>org.apache.shiro</groupId>
-            <artifactId>shiro-cas</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.shiro</groupId>
             <artifactId>shiro-ehcache</artifactId>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/aa2cd4fc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index bcfaa29..8322e9b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -92,16 +92,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>
-        <gmaven.version>1.4</gmaven.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>
 
@@ -204,6 +210,7 @@
         <module>samples</module>
         <module>tools</module>
         <module>all</module>
+        <module>test-coverage</module>
     </modules>
 
     <build>
@@ -244,6 +251,9 @@
                             <exclude>velocity.log</exclude>
                             <exclude>CONTRIBUTING.md</exclude>
                             <exclude>README.md</exclude>
+                            <exclude>**/*.json</exclude>
+                            <exclude>**/spring.factories</exclude>
+                            <exclude>**/spring.provides</exclude>
                         </excludes>
                     </configuration>
                 </plugin>
@@ -385,6 +395,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>
@@ -507,6 +532,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>
@@ -601,11 +631,6 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
-                <artifactId>shiro-cas</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-ehcache</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -641,6 +666,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: -->
@@ -936,6 +971,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>
@@ -1056,6 +1114,9 @@
                         <exclude>velocity.log</exclude>
                         <exclude>CONTRIBUTING.md</exclude>
                         <exclude>README.md</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/aa2cd4fc/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 7ce6803..d607267 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -39,7 +39,8 @@
         <module>spring-client</module>
         <module>spring</module>
         <module>spring-hibernate</module>
-           <module>guice</module>
+        <module>spring-boot-web</module>
+        <module>guice</module>
         <module>quickstart-guice</module>
     </modules>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index 4771708..40c1fd4 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -41,6 +41,7 @@
         <module>guice</module>
         <module>openid4j</module>
         <module>features</module>
+        <module>spring-boot</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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/aa2cd4fc/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();
+    }
+}

Reply via email to