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:04 UTC

[01/20] shiro git commit: updating versions in 1.4.x branch

Repository: shiro
Updated Branches:
  refs/heads/1.4.x [created] a63e1d85f


updating versions in 1.4.x branch


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

Branch: refs/heads/1.4.x
Commit: 1e48dbfb8262ef9cf138bc70d1977a06fd108bfe
Parents: 4d08760
Author: Brian Demers <bd...@apache.org>
Authored: Tue Sep 20 09:53:36 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Tue Sep 20 09:53:36 2016 -0400

----------------------------------------------------------------------
 all/pom.xml                      | 2 +-
 core/pom.xml                     | 2 +-
 pom.xml                          | 2 +-
 samples/aspectj/pom.xml          | 2 +-
 samples/guice/pom.xml            | 2 +-
 samples/pom.xml                  | 2 +-
 samples/quickstart-guice/pom.xml | 2 +-
 samples/quickstart/pom.xml       | 2 +-
 samples/spring-client/pom.xml    | 2 +-
 samples/spring-hibernate/pom.xml | 2 +-
 samples/spring/pom.xml           | 2 +-
 samples/web/pom.xml              | 2 +-
 support/aspectj/pom.xml          | 2 +-
 support/cas/pom.xml              | 2 +-
 support/ehcache/pom.xml          | 2 +-
 support/features/pom.xml         | 2 +-
 support/guice/pom.xml            | 2 +-
 support/hazelcast/pom.xml        | 2 +-
 support/pom.xml                  | 2 +-
 support/quartz/pom.xml           | 2 +-
 support/spring/pom.xml           | 2 +-
 tools/hasher/pom.xml             | 2 +-
 tools/pom.xml                    | 2 +-
 web/pom.xml                      | 2 +-
 24 files changed, 24 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/all/pom.xml
----------------------------------------------------------------------
diff --git a/all/pom.xml b/all/pom.xml
index 07cb317..f4279b4 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 6848162..79f67fa 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 35dc2ca..a65a52c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
     <groupId>org.apache.shiro</groupId>
     <artifactId>shiro-root</artifactId>
     <packaging>pom</packaging>
-    <version>1.3.3-SNAPSHOT</version>
+    <version>1.4.0-SNAPSHOT</version>
 
     <name>Apache Shiro</name>
     <url>http://shiro.apache.org/</url>

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/aspectj/pom.xml
----------------------------------------------------------------------
diff --git a/samples/aspectj/pom.xml b/samples/aspectj/pom.xml
index cb81dd8..c8fe4c0 100644
--- a/samples/aspectj/pom.xml
+++ b/samples/aspectj/pom.xml
@@ -23,7 +23,7 @@
 	<parent>
 		<groupId>org.apache.shiro.samples</groupId>
 		<artifactId>shiro-samples</artifactId>
-		<version>1.3.3-SNAPSHOT</version>
+		<version>1.4.0-SNAPSHOT</version>
 	        <relativePath>../pom.xml</relativePath> 
         </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index b28c8fa..ed3e287 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -21,7 +21,7 @@
 	<parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-		<version>1.3.3-SNAPSHOT</version>
+		<version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
 	</parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index d45bfc3..5e6a023 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/quickstart-guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/quickstart-guice/pom.xml b/samples/quickstart-guice/pom.xml
index b39c364..99d000d 100644
--- a/samples/quickstart-guice/pom.xml
+++ b/samples/quickstart-guice/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/quickstart/pom.xml
----------------------------------------------------------------------
diff --git a/samples/quickstart/pom.xml b/samples/quickstart/pom.xml
index 8025afb..70978ac 100644
--- a/samples/quickstart/pom.xml
+++ b/samples/quickstart/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/spring-client/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-client/pom.xml b/samples/spring-client/pom.xml
index e6a8404..bd55849 100644
--- a/samples/spring-client/pom.xml
+++ b/samples/spring-client/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/spring-hibernate/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-hibernate/pom.xml b/samples/spring-hibernate/pom.xml
index fb5c3df..8ab9367 100644
--- a/samples/spring-hibernate/pom.xml
+++ b/samples/spring-hibernate/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/spring/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring/pom.xml b/samples/spring/pom.xml
index bd79f08..70b6e69 100644
--- a/samples/spring/pom.xml
+++ b/samples/spring/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index dd638f5..a06352b 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro.samples</groupId>
         <artifactId>shiro-samples</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/aspectj/pom.xml
----------------------------------------------------------------------
diff --git a/support/aspectj/pom.xml b/support/aspectj/pom.xml
index 6231365..4df8c09 100644
--- a/support/aspectj/pom.xml
+++ b/support/aspectj/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/cas/pom.xml
----------------------------------------------------------------------
diff --git a/support/cas/pom.xml b/support/cas/pom.xml
index 4f6c792..387f018 100644
--- a/support/cas/pom.xml
+++ b/support/cas/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/ehcache/pom.xml
----------------------------------------------------------------------
diff --git a/support/ehcache/pom.xml b/support/ehcache/pom.xml
index 3b9e5ae..a58ae0f 100644
--- a/support/ehcache/pom.xml
+++ b/support/ehcache/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/features/pom.xml
----------------------------------------------------------------------
diff --git a/support/features/pom.xml b/support/features/pom.xml
index eac1128..b4d4fbb 100644
--- a/support/features/pom.xml
+++ b/support/features/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/guice/pom.xml
----------------------------------------------------------------------
diff --git a/support/guice/pom.xml b/support/guice/pom.xml
index c5adf45..9e0849d 100644
--- a/support/guice/pom.xml
+++ b/support/guice/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/hazelcast/pom.xml
----------------------------------------------------------------------
diff --git a/support/hazelcast/pom.xml b/support/hazelcast/pom.xml
index 4a08fbd..293fbbd 100644
--- a/support/hazelcast/pom.xml
+++ b/support/hazelcast/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index ee9c19e..77a94db 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/quartz/pom.xml
----------------------------------------------------------------------
diff --git a/support/quartz/pom.xml b/support/quartz/pom.xml
index 05c2961..5d47816 100644
--- a/support/quartz/pom.xml
+++ b/support/quartz/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/support/spring/pom.xml
----------------------------------------------------------------------
diff --git a/support/spring/pom.xml b/support/spring/pom.xml
index 89c7330..60f69cd 100644
--- a/support/spring/pom.xml
+++ b/support/spring/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/tools/hasher/pom.xml
----------------------------------------------------------------------
diff --git a/tools/hasher/pom.xml b/tools/hasher/pom.xml
index b47f336..4579b56 100644
--- a/tools/hasher/pom.xml
+++ b/tools/hasher/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro.tools</groupId>
         <artifactId>shiro-tools</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/tools/pom.xml
----------------------------------------------------------------------
diff --git a/tools/pom.xml b/tools/pom.xml
index 56143d4..c2c0324 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/1e48dbfb/web/pom.xml
----------------------------------------------------------------------
diff --git a/web/pom.xml b/web/pom.xml
index 7fee79a..6c55ff6 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.shiro</groupId>
         <artifactId>shiro-root</artifactId>
-        <version>1.3.3-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 


[04/20] shiro git commit: SHIRO-589 - Update Servlet Dependency to 3.1

Posted by bd...@apache.org.
SHIRO-589 - Update Servlet Dependency to 3.1


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

Branch: refs/heads/1.4.x
Commit: 19158022f2bc5632a78bf18830c1df8ed361cb74
Parents: cd3dde8
Author: Brian Demers <bd...@apache.org>
Authored: Tue Sep 27 15:12:51 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 pom.xml                          | 6 +++---
 samples/guice/pom.xml            | 2 +-
 samples/spring-hibernate/pom.xml | 2 +-
 samples/spring/pom.xml           | 2 +-
 samples/web/pom.xml              | 2 +-
 support/guice/pom.xml            | 2 +-
 support/spring/pom.xml           | 2 +-
 web/pom.xml                      | 2 +-
 8 files changed, 10 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index b219d6b..02f837a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -703,8 +703,8 @@
             </dependency>
             <dependency>
                 <groupId>javax.servlet</groupId>
-                <artifactId>servlet-api</artifactId>
-                <version>2.5</version>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>3.1.0</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>
@@ -786,7 +786,7 @@
                     </exclusion>
                     <exclusion>
                         <groupId>javax.servlet</groupId>
-                        <artifactId>servlet-api</artifactId>
+                        <artifactId>javax.servlet-api</artifactId>
                     </exclusion>
                     <exclusion>
                         <groupId>jboss</groupId>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/samples/guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index ed3e287..ff6b52c 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -69,7 +69,7 @@
 	    </dependency>
 	    <dependency>
 	        <groupId>javax.servlet</groupId>
-	        <artifactId>servlet-api</artifactId>
+	        <artifactId>javax.servlet-api</artifactId>
 	        <scope>provided</scope>
 	    </dependency>
 	    <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/samples/spring-hibernate/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-hibernate/pom.xml b/samples/spring-hibernate/pom.xml
index 8ab9367..0f84239 100644
--- a/samples/spring-hibernate/pom.xml
+++ b/samples/spring-hibernate/pom.xml
@@ -105,7 +105,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/samples/spring/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring/pom.xml b/samples/spring/pom.xml
index 70b6e69..30361fa 100644
--- a/samples/spring/pom.xml
+++ b/samples/spring/pom.xml
@@ -137,7 +137,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index a06352b..a875aa6 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -72,7 +72,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/support/guice/pom.xml
----------------------------------------------------------------------
diff --git a/support/guice/pom.xml b/support/guice/pom.xml
index 9e0849d..78a97f8 100644
--- a/support/guice/pom.xml
+++ b/support/guice/pom.xml
@@ -60,7 +60,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/support/spring/pom.xml
----------------------------------------------------------------------
diff --git a/support/spring/pom.xml b/support/spring/pom.xml
index 60f69cd..3aa7155 100644
--- a/support/spring/pom.xml
+++ b/support/spring/pom.xml
@@ -42,7 +42,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/19158022/web/pom.xml
----------------------------------------------------------------------
diff --git a/web/pom.xml b/web/pom.xml
index 6c55ff6..b84b426 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -47,7 +47,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
         </dependency>
         <!-- Test dependencies - scope set appropriately already in the parent pom-->
         <dependency>


[11/20] shiro git commit: SHIRO-593 - Allow defaults added to the IniWebEnvironment to be passed into the SecurityManager and FilterChainResolver factories

Posted by bd...@apache.org.
SHIRO-593 - Allow defaults added to the IniWebEnvironment to be passed into the SecurityManager and FilterChainResolver factories


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

Branch: refs/heads/1.4.x
Commit: 542a32eca8d0f4b4cae86fe5429811ea8a40b4ac
Parents: 808cb1f
Author: Brian Demers <bd...@apache.org>
Authored: Thu Sep 29 11:24:00 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 .../apache/shiro/web/env/IniWebEnvironment.java | 35 ++++++++++++++------
 .../shiro/web/env/IniWebEnvironmentTest.groovy  |  4 +--
 2 files changed, 27 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/542a32ec/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
index f07406a..bff933a 100644
--- a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
+++ b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
@@ -22,10 +22,7 @@ import org.apache.shiro.config.ConfigurationException;
 import org.apache.shiro.config.Ini;
 import org.apache.shiro.config.IniFactorySupport;
 import org.apache.shiro.io.ResourceUtils;
-import org.apache.shiro.util.CollectionUtils;
-import org.apache.shiro.util.Destroyable;
-import org.apache.shiro.util.Initializable;
-import org.apache.shiro.util.StringUtils;
+import org.apache.shiro.util.*;
 import org.apache.shiro.web.config.IniFilterChainResolverFactory;
 import org.apache.shiro.web.config.WebIniSecurityManagerFactory;
 import org.apache.shiro.web.filter.mgt.FilterChainResolver;
@@ -37,6 +34,7 @@ import org.slf4j.LoggerFactory;
 import javax.servlet.ServletContext;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -47,6 +45,7 @@ import java.util.Map;
 public class IniWebEnvironment extends ResourceBasedWebEnvironment implements Initializable, Destroyable {
 
     public static final String DEFAULT_WEB_INI_RESOURCE_PATH = "/WEB-INF/shiro.ini";
+    public static final String FILTER_CHAIN_RESOLVER_NAME = "filterChainResolver";
 
     private static final Logger log = LoggerFactory.getLogger(IniWebEnvironment.class);
 
@@ -259,7 +258,13 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
             Ini.Section filters = ini.getSection(IniFilterChainResolverFactory.FILTERS);
             if (!CollectionUtils.isEmpty(urls) || !CollectionUtils.isEmpty(filters)) {
                 //either the urls section or the filters section was defined.  Go ahead and create the resolver:
-                IniFilterChainResolverFactory factory = new IniFilterChainResolverFactory(ini, this.objects);
+
+                Factory<FilterChainResolver> factory = (Factory<FilterChainResolver>) this.objects.get(FILTER_CHAIN_RESOLVER_NAME);
+                if (factory instanceof IniFactorySupport) {
+                    IniFactorySupport iniFactory = (IniFactorySupport) factory;
+                    iniFactory.setIni(ini);
+                    iniFactory.setDefaults(this.objects);
+                }
                 resolver = factory.getInstance();
             }
         }
@@ -268,12 +273,16 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
     }
 
     protected WebSecurityManager createWebSecurityManager() {
-        WebIniSecurityManagerFactory factory;
+        WebIniSecurityManagerFactory factory = new WebIniSecurityManagerFactory();
+
         Ini ini = getIni();
-        if (CollectionUtils.isEmpty(ini)) {
-            factory = new WebIniSecurityManagerFactory();
-        } else {
-            factory = new WebIniSecurityManagerFactory(ini);
+        if (!CollectionUtils.isEmpty(ini)) {
+            factory.setIni(ini);
+        }
+
+        Map<String, Object> defaults = getDefaults();
+        if (!CollectionUtils.isEmpty(defaults)) {
+            factory.setDefaults(defaults);
         }
 
         WebSecurityManager wsm = (WebSecurityManager)factory.getInstance();
@@ -382,4 +391,10 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
     public void setIni(Ini ini) {
         this.ini = ini;
     }
+
+    protected Map<String, Object> getDefaults() {
+        Map<String, Object> defaults = new HashMap<String, Object>();
+        defaults.put(FILTER_CHAIN_RESOLVER_NAME, new IniFilterChainResolverFactory());
+        return defaults;
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/542a32ec/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
----------------------------------------------------------------------
diff --git a/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy b/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
index 84b698d..7dcb40b 100644
--- a/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
+++ b/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
@@ -49,8 +49,8 @@ class IniWebEnvironmentTest {
         env.init()
 
         assertNotNull env.objects
-        //asserts that the objects size = securityManager (1) + the event bus (1) + num custom objects + num default filters
-        def expectedSize = 3 + DefaultFilter.values().length
+        //asserts that the objects size = securityManager (1) + the event bus (1) + filterChainResolverFactory (1) + num custom objects + num default filters
+        def expectedSize = 4 + DefaultFilter.values().length
         assertEquals expectedSize, env.objects.size()
         assertNotNull env.objects['securityManager']
         assertNotNull env.objects['compositeBean']


[05/20] shiro git commit: Fixed and enabled web sample test

Posted by bd...@apache.org.
Fixed and enabled web sample test


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

Branch: refs/heads/1.4.x
Commit: ea2b48330ad7b031741ea9c1ae2f739e4679863e
Parents: b05a48f
Author: Brian Demers <bd...@apache.org>
Authored: Fri Sep 30 11:57:15 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 .../apache/shiro/test/AbstractContainerIT.java  |  26 ++--
 samples/web/pom.xml                             | 130 ++++++++++++++-----
 .../shiro/test/AbstractContainerTest.java       |  88 -------------
 .../shiro/test/ContainerIntegrationIT.java      |  66 ++++++++++
 .../shiro/test/ContainerIntegrationTest.java    |  81 ------------
 5 files changed, 181 insertions(+), 210 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/ea2b4833/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
index f5b44f7..da02a0b 100644
--- a/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
+++ b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
@@ -56,19 +56,8 @@ public abstract class AbstractContainerIT {
     @BeforeClass
     public static void startContainer() throws Exception {
 
-        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-                return name.endsWith(".war");
-            }
-        });
-
-        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
-
-        String warDir = warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
-
         EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
-                .withWebapp(warDir)
+                .withWebapp(getWarDir())
                 .build();
 
         jetty = new EmbeddedJetty(config) {
@@ -131,6 +120,19 @@ public abstract class AbstractContainerIT {
         return "http://localhost:" + port + "/";
     }
 
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
     @Before
     public void beforeTest() {
         webClient.setThrowExceptionOnFailingStatusCode(true);

http://git-wip-us.apache.org/repos/asf/shiro/blob/ea2b4833/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index a875aa6..cf53c2b 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -32,7 +32,46 @@
     <name>Apache Shiro :: Samples :: Web</name>
     <packaging>war</packaging>
 
+    <properties>
+        <jetty.port>9080</jetty.port>
+        <jetty.postIT.sleep>1</jetty.postIT.sleep>
+    </properties>
+
     <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.mortbay.jetty</groupId>
+                    <artifactId>maven-jetty-plugin</artifactId>
+                    <version>${jetty.version}</version>
+                    <configuration>
+                        <contextPath>/</contextPath>
+                        <stopPort>8005</stopPort>
+                        <stopKey>STOP</stopKey>
+                        <connectors>
+                            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+                                <port>${jetty.port}</port>
+                                <maxIdleTime>60000</maxIdleTime>
+                            </connector>
+                        </connectors>
+                        <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
+                            <filename>./target/yyyy_mm_dd.request.log</filename>
+                            <retainDays>90</retainDays>
+                            <append>true</append>
+                            <extended>false</extended>
+                            <logTimeZone>GMT</logTimeZone>
+                        </requestLog>
+                    </configuration>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.mortbay.jetty</groupId>
+                            <artifactId>jsp-2.1-jetty</artifactId>
+                            <version>${jetty.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>
+            </plugins>
+        </pluginManagement>
         <plugins>
             <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
@@ -43,23 +82,6 @@
             <plugin>
                 <groupId>org.mortbay.jetty</groupId>
                 <artifactId>maven-jetty-plugin</artifactId>
-                <version>${jetty.version}</version>
-                <configuration>
-                    <contextPath>/</contextPath>
-                    <connectors>
-                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-                            <port>9080</port>
-                            <maxIdleTime>60000</maxIdleTime>
-                        </connector>
-                    </connectors>
-                    <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
-                        <filename>./target/yyyy_mm_dd.request.log</filename>
-                        <retainDays>90</retainDays>
-                        <append>true</append>
-                        <extended>false</extended>
-                        <logTimeZone>GMT</logTimeZone>
-                    </requestLog>
-                </configuration>
             </plugin>
         </plugins>
     </build>
@@ -100,22 +122,72 @@
             <artifactId>shiro-web</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty</artifactId>
-            <version>${jetty.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jsp-2.1-jetty</artifactId>
-            <version>${jetty.version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>jcl-over-slf4j</artifactId>
             <scope>runtime</scope>
         </dependency>
     </dependencies>
 
+    <profiles>
+        <profile>
+            <id>run-ITs</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.mortbay.jetty</groupId>
+                        <artifactId>maven-jetty-plugin</artifactId>
+                        <executions>
+                            <!-- start jetty before ITs -->
+                            <execution>
+                                <id>start-jetty</id>
+                                <phase>pre-integration-test</phase>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <scanIntervalSeconds>0</scanIntervalSeconds>
+                                    <daemon>true</daemon>
+                                </configuration>
+                            </execution>
+                            <!-- Stop jetty after ITs -->
+                            <execution>
+                                <id>stop-jetty</id>
+                                <phase>post-integration-test</phase>
+                                <goals>
+                                    <goal>stop</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <version>1.8</version>
+                        <executions>
+                            <execution>
+                                <id>sleep-for-a-while</id>
+                                <phase>post-integration-test</phase>
+                                <configuration>
+                                    <target>
+                                        <!-- This is dirty looking, but this old version needs it or the shutdown
+                                        hook will print exceptions, the build will still pass, so it is mostly cosmetic.
+                                        -->
+                                        <echo>Waiting for Jetty to stop</echo>
+                                        <sleep seconds="${jetty.postIT.sleep}" />
+                                    </target>
+                                </configuration>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/ea2b4833/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerTest.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerTest.java b/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerTest.java
deleted file mode 100644
index 6a0c6e8..0000000
--- a/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.test;
-
-import com.gargoylesoftware.htmlunit.WebClient;
-import static org.junit.Assert.assertTrue;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-import java.net.BindException;
-
-public abstract class AbstractContainerTest {
-    public static final int MAX_PORT = 9200;
-
-    protected static PauseableServer server;
-
-    private static int port = 9180;
-
-    protected final WebClient webClient = new WebClient();
-
-    @BeforeClass
-    public static void startContainer() throws Exception {
-        while (server == null && port < MAX_PORT) {
-            try {
-                server = createAndStartServer(port);
-            } catch (BindException e) {
-                System.err.printf("Unable to listen on port %d.  Trying next port.", port);
-                port++;
-            }
-        }
-        assertTrue(server.isStarted());
-    }
-
-    private static PauseableServer createAndStartServer(final int port) throws Exception {
-        PauseableServer server = new PauseableServer();
-        Connector connector = new SelectChannelConnector();
-        connector.setPort(port);
-        server.setConnectors(new Connector[]{connector});
-        server.setHandler(new WebAppContext("src/main/webapp", "/"));
-        server.start();
-        return server;
-    }
-
-    protected static String getBaseUri() {
-        return "http://localhost:" + port + "/";
-    }
-
-    @Before
-    public void beforeTest() {
-        webClient.setThrowExceptionOnFailingStatusCode(true);
-    }
-
-    public void pauseServer(boolean paused) {
-        if (server != null) server.pause(paused);
-    }
-
-    public static class PauseableServer extends Server {
-        public synchronized void pause(boolean paused) {
-            try {
-                if (paused) for (Connector connector : getConnectors())
-                    connector.stop();
-                else for (Connector connector : getConnectors())
-                    connector.start();
-            } catch (Exception e) {
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/shiro/blob/ea2b4833/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
new file mode 100644
index 0000000..e8f7b48
--- /dev/null
+++ b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
@@ -0,0 +1,66 @@
+/*
+ * 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.test;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+
+public class ContainerIntegrationIT {
+
+    protected final WebClient webClient = new WebClient();
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    protected static String getBaseUri() {
+        String port = System.getProperty("jetty.port", "9080");
+        return "http://localhost:" + port + "/";
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/ea2b4833/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationTest.java b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationTest.java
deleted file mode 100644
index 7123cc4..0000000
--- a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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.test;
-
-import com.gargoylesoftware.htmlunit.ElementNotFoundException;
-import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
-import com.gargoylesoftware.htmlunit.WebAssert;
-import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlInput;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-@Ignore
-public class ContainerIntegrationTest extends AbstractContainerTest {
-
-    @Before
-    public void logOut() throws IOException {
-        // Make sure we are logged out
-        final HtmlPage homePage = webClient.getPage(getBaseUri());
-        try {
-            homePage.getAnchorByHref("/logout").click();
-        }
-        catch (ElementNotFoundException e) {
-            //Ignore
-        }
-    }
-
-    @Test
-    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
-
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        page = form.<HtmlInput>getInputByName("submit").click();
-        // This'll throw an expection if not logged in
-        page.getAnchorByHref("/logout");
-    }
-
-    @Test
-    public void logInAndRememberMe() throws Exception {
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
-        checkbox.setChecked(true);
-        page = form.<HtmlInput>getInputByName("submit").click();
-        server.stop();
-        server.start();
-        page = webClient.getPage(getBaseUri());
-        // page.getAnchorByHref("/logout");
-        WebAssert.assertLinkPresentWithText(page, "Log out");
-        page = page.getAnchorByHref("/account").click();
-        // login page should be shown again - user remembered but not authenticated
-        WebAssert.assertFormPresent(page, "loginform");
-    }
-
-}


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

Posted by bd...@apache.org.
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/ShiroWebAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java
new file mode 100644
index 0000000..953a63e
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebAutoConfiguration.java
@@ -0,0 +1,138 @@
+/*
+ * 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.authc.Authenticator;
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authz.Authorizer;
+import org.apache.shiro.mgt.*;
+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.web.config.AbstractShiroWebConfiguration;
+import org.apache.shiro.web.servlet.Cookie;
+import org.springframework.boot.autoconfigure.AutoConfigureOrder;
+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
+@ConditionalOnProperty(name = "shiro.web.enabled", matchIfMissing = true)
+public class ShiroWebAutoConfiguration extends AbstractShiroWebConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected AuthenticationStrategy authenticationStrategy() {
+        return super.authenticationStrategy();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected Authenticator authenticator() {
+        return super.authenticator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected Authorizer authorizer() {
+        return super.authorizer();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SubjectDAO subjectDAO() {
+        return super.subjectDAO();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionStorageEvaluator sessionStorageEvaluator() {
+        return super.sessionStorageEvaluator();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionFactory sessionFactory() {
+        return super.sessionFactory();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SessionDAO sessionDAO() {
+        return super.sessionDAO();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(name = "sessionCookieTemplate")
+    @Override
+    protected Cookie sessionCookieTemplate() {
+        return super.sessionCookieTemplate();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected RememberMeManager rememberMeManager() {
+        return super.rememberMeManager();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(name = "rememberMeCookieTemplate")
+    @Override
+    protected Cookie rememberMeCookieTemplate() {
+        return super.rememberMeCookieTemplate();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected SubjectFactory subjectFactory() {
+        return super.subjectFactory();
+    }
+
+    @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-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebFilterConfiguration.java b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebFilterConfiguration.java
new file mode 100644
index 0000000..96e8ad1
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/java/org/apache/shiro/spring/config/web/autoconfigure/ShiroWebFilterConfiguration.java
@@ -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.
+ */
+package org.apache.shiro.spring.config.web.autoconfigure;
+
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.spring.web.config.AbstractShiroWebFilterConfiguration;
+import org.apache.shiro.web.servlet.AbstractShiroFilter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+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 ShiroWebFilterConfiguration extends AbstractShiroWebFilterConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean
+    @Override
+    protected ShiroFilterFactoryBean shiroFilterFactoryBean() {
+        return super.shiroFilterFactoryBean();
+    }
+
+    @Bean(name = "filterShiroFilterRegistrationBean")
+    @ConditionalOnMissingBean
+    protected FilterRegistrationBean filterShiroFilterRegistrationBean() throws Exception {
+
+        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
+        filterRegistrationBean.setFilter((AbstractShiroFilter) shiroFilterFactoryBean().getObject());
+        filterRegistrationBean.setOrder(1);
+
+        return filterRegistrationBean;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
new file mode 100644
index 0000000..a5157d3
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -0,0 +1,46 @@
+{
+  "groups": [
+    {
+      "name": "shiro"
+    },
+  ],
+  "properties": [
+
+    {
+      "name": "shiro.web.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
+    },
+    {
+      "name": "shiro.loginUrl",
+      "type": "java.lang.String",
+      "description": "The application's login URL to be assigned to all acquired Filters that subclass AccessControlFilter or 'null' if no value should be assigned globally.",
+      "defaultValue": "/login.jsp"
+    },
+    {
+      "name": "shiro.successUrl",
+      "type": "java.lang.String",
+      "description": "The application's after-login success URL to be assigned to all acquired Filters that subclass AuthenticationFilter or null if no value should be assigned globally.",
+      "defaultValue": "/"
+    },
+    {
+      "name": "shiro.unauthorizedUrl",
+      "type": "java.lang.String",
+      "description": "The application's 'unauthorized' URL to apply to as a convenience to all discovered AuthorizationFilter instances.",
+      "defaultValue": null
+    },
+    {
+      "name": "shiro.sessionManager.sessionIdCookieEnabled",
+      "type": "java.lang.String",
+      "description": "Enable or disable session tracking via a cookie.",
+      "defaultValue": true
+    },
+    {
+      "name": "shiro.sessionManager.sessionIdUrlRewritingEnabled",
+      "type": "java.lang.String",
+      "description": "Enable or disable session tracking via a URL parameter.  If your site requires cookies, it is recommended you disable this.",
+      "defaultValue": true
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..397c6e4
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/main/resources/META-INF/spring.factories
@@ -0,0 +1 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration = org.apache.shiro.spring.config.web.autoconfigure.ShiroBeanAutoConfiguration,org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration,org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration,org.apache.shiro.spring.config.web.autoconfigure.ShiroAnnotationProcessorAutoConfiguration

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

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebSpringAutoConfigurationTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebSpringAutoConfigurationTest.groovy b/support/spring-boot/spring-boot-web-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebSpringAutoConfigurationTest.groovy
new file mode 100644
index 0000000..db1b384
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/test/groovy/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebSpringAutoConfigurationTest.groovy
@@ -0,0 +1,70 @@
+/*
+ * 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.web
+
+import org.apache.shiro.spring.boot.autoconfigure.web.ShiroWebAutoConfigurationTestApplication.EventBusAwareObject
+import org.apache.shiro.spring.boot.autoconfigure.web.ShiroWebAutoConfigurationTestApplication.SubscribedListener
+
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.mgt.DefaultSecurityManager
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.web.mgt.WebSecurityManager
+import org.junit.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.instanceOf
+import static org.junit.Assert.*
+/**
+ * @since 1.4.0
+ */
+@SpringBootTest(classes = [ShiroWebAutoConfigurationTestApplication])
+public class ShiroWebSpringAutoConfigurationTest extends AbstractJUnit4SpringContextTests {
+
+    @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
+        assertThat securityManager, instanceOf(WebSecurityManager)
+
+        assertNotNull eventBusAwareObject
+        assertNotNull eventBus
+        assertTrue(eventBus.registry.containsKey(subscribedListener))
+        assertSame(eventBusAwareObject.getEventBus(), eventBus)
+        assertSame(((DefaultSecurityManager)securityManager).getEventBus(), eventBus)
+
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring-boot/spring-boot-web-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebAutoConfigurationTestApplication.java
----------------------------------------------------------------------
diff --git a/support/spring-boot/spring-boot-web-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebAutoConfigurationTestApplication.java b/support/spring-boot/spring-boot-web-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebAutoConfigurationTestApplication.java
new file mode 100644
index 0000000..8fdcc1a
--- /dev/null
+++ b/support/spring-boot/spring-boot-web-starter/src/test/java/org/apache/shiro/spring/boot/autoconfigure/web/ShiroWebAutoConfigurationTestApplication.java
@@ -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.
+ */
+package org.apache.shiro.spring.boot.autoconfigure.web;
+
+
+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.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+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 ShiroWebAutoConfigurationTestApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ShiroWebAutoConfigurationTestApplication.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
+    ShiroFilterChainDefinition shiroFilterChainDefinition() {
+        return new DefaultShiroFilterChainDefinition();
+    }
+
+    @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/src/main/java/org/apache/shiro/spring/LifecycleBeanPostProcessor.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/LifecycleBeanPostProcessor.java b/support/spring/src/main/java/org/apache/shiro/spring/LifecycleBeanPostProcessor.java
index a526769..a318d20 100644
--- a/support/spring/src/main/java/org/apache/shiro/spring/LifecycleBeanPostProcessor.java
+++ b/support/spring/src/main/java/org/apache/shiro/spring/LifecycleBeanPostProcessor.java
@@ -134,4 +134,15 @@ public class LifecycleBeanPostProcessor implements DestructionAwareBeanPostProce
         // LifecycleBeanPostProcessor needs Order. See https://issues.apache.org/jira/browse/SHIRO-222
         return order;
     }
+
+    /**
+     * Return true only if <code>bean</code> implements Destroyable.
+     * @param bean bean to check if requires destruction.
+     * @return true only if <code>bean</code> implements Destroyable.
+     * @since 1.4
+     */
+    @SuppressWarnings("unused")
+    public boolean requiresDestruction(Object bean) {
+        return (bean instanceof Destroyable);
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java b/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
new file mode 100644
index 0000000..64a40cf
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/ShiroEventBusBeanPostProcessor.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+import org.apache.shiro.util.ClassUtils;
+import org.apache.shiro.util.CollectionUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+import java.util.List;
+
+/**
+ * Spring {@link BeanPostProcessor} that detects, {@link EventBusAware} and classes containing {@link Subscribe @Subscribe} methods.
+ * Any classes implementing EventBusAware will have the setEventBus() method called with the <code>eventBus</code>. Any
+ * classes discovered with methods that are annotated with @Subscribe will be automaticly registered with the EventBus.
+ *
+ * <p><strong>NOTE:</strong> in a Spring environment implementing EventBusAware is not necessary, as you can just inject the EventBus with
+ * {@link org.springframework.beans.factory.annotation.Autowire @Autowire}.</p>
+ *
+ * @see EventBusAware
+ * @see Subscribe
+ * @since 1.4
+ */
+public class ShiroEventBusBeanPostProcessor implements BeanPostProcessor {
+
+    final private EventBus eventBus;
+
+    public ShiroEventBusBeanPostProcessor(EventBus eventBus) {
+        this.eventBus = eventBus;
+    }
+
+    @Override
+    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
+        return bean;
+    }
+
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
+        if (bean instanceof EventBusAware) {
+            ((EventBusAware) bean).setEventBus(eventBus);
+        }
+        else if (isEventSubscriber(bean)) {
+            eventBus.register(bean);
+        }
+
+        return bean;
+    }
+
+    private boolean isEventSubscriber(Object bean) {
+        List annotatedMethods = ClassUtils.getAnnotatedMethods(bean.getClass(), Subscribe.class);
+        return !CollectionUtils.isEmpty(annotatedMethods);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
new file mode 100644
index 0000000..679d205
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroAnnotationProcessorConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+
+/**
+ * @since 1.4.0
+ */
+public class AbstractShiroAnnotationProcessorConfiguration {
+
+    protected DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        return new DefaultAdvisorAutoProxyCreator();
+    }
+
+    protected AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
+        advisor.setSecurityManager(securityManager);
+        return advisor;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
new file mode 100644
index 0000000..5c9753f
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroBeanConfiguration.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.support.DefaultEventBus;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @since 1.4.0
+ */
+public class AbstractShiroBeanConfiguration {
+
+    protected LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return new LifecycleBeanPostProcessor();
+    }
+
+    protected EventBus eventBus() {
+        return new DefaultEventBus();
+    }
+
+    protected ShiroEventBusBeanPostProcessor shiroEventBusAwareBeanPostProcessor() {
+        return new ShiroEventBusBeanPostProcessor(eventBus());
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroConfiguration.java
new file mode 100644
index 0000000..7f25178
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/AbstractShiroConfiguration.java
@@ -0,0 +1,152 @@
+/*
+ * 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;
+
+import org.apache.shiro.authc.Authenticator;
+import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
+import org.apache.shiro.authz.Authorizer;
+import org.apache.shiro.authz.ModularRealmAuthorizer;
+import org.apache.shiro.authz.permission.PermissionResolver;
+import org.apache.shiro.authz.permission.RolePermissionResolver;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.mgt.*;
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.session.mgt.DefaultSessionManager;
+import org.apache.shiro.session.mgt.SessionFactory;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.session.mgt.SimpleSessionFactory;
+import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
+import org.apache.shiro.session.mgt.eis.SessionDAO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.util.List;
+
+/**
+ * @since 1.4.0
+ */
+public class AbstractShiroConfiguration {
+
+    @Autowired(required = false)
+    protected CacheManager cacheManager;
+
+    @Autowired(required = false)
+    protected RolePermissionResolver rolePermissionResolver;
+
+    @Autowired(required = false)
+    protected PermissionResolver permissionResolver;
+
+    @Autowired
+    protected EventBus eventBus;
+
+    @Value("#{ @environment['shiro.sessionManager.deleteInvalidSessions'] ?: true }")
+    protected boolean sessionManagerDeleteInvalidSessions;
+
+
+    protected SessionsSecurityManager securityManager(List<Realm> realms) {
+        SessionsSecurityManager securityManager = createSecurityManager();
+        securityManager.setAuthenticator(authenticator());
+        securityManager.setAuthorizer(authorizer());
+        securityManager.setRealms(realms);
+        securityManager.setSessionManager(sessionManager());
+        securityManager.setEventBus(eventBus);
+
+        if (cacheManager != null) {
+            securityManager.setCacheManager(cacheManager);
+        }
+
+        return securityManager;
+    }
+
+    protected SessionManager sessionManager() {
+        DefaultSessionManager sessionManager = new DefaultSessionManager();
+        sessionManager.setSessionDAO(sessionDAO());
+        sessionManager.setSessionFactory(sessionFactory());
+        sessionManager.setDeleteInvalidSessions(sessionManagerDeleteInvalidSessions);
+        return sessionManager;
+    }
+
+
+    protected SessionsSecurityManager createSecurityManager() {
+        DefaultSecurityManager securityManager = new DefaultSecurityManager();
+        securityManager.setSubjectDAO(subjectDAO());
+        securityManager.setSubjectFactory(subjectFactory());
+
+        RememberMeManager rememberMeManager = rememberMeManager();
+        if (rememberMeManager != null) {
+            securityManager.setRememberMeManager(rememberMeManager);
+        }
+
+        return securityManager;
+    }
+
+    protected RememberMeManager rememberMeManager() {
+        return null;
+    }
+
+    protected SubjectDAO subjectDAO() {
+        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
+        subjectDAO.setSessionStorageEvaluator(sessionStorageEvaluator());
+        return subjectDAO;
+    }
+
+    protected SessionStorageEvaluator sessionStorageEvaluator() {
+        return new DefaultSessionStorageEvaluator();
+    }
+
+    protected SubjectFactory subjectFactory() {
+        return new DefaultSubjectFactory();
+    }
+
+
+    protected SessionFactory sessionFactory() {
+        return new SimpleSessionFactory();
+    }
+
+    protected SessionDAO sessionDAO() {
+        return new MemorySessionDAO();
+    }
+
+    protected Authorizer authorizer() {
+        ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
+
+        if (permissionResolver != null) {
+            authorizer.setPermissionResolver(permissionResolver);
+        }
+
+        if (rolePermissionResolver != null) {
+            authorizer.setRolePermissionResolver(rolePermissionResolver);
+        }
+
+        return authorizer;
+    }
+
+    protected AuthenticationStrategy authenticationStrategy() {
+        return new AtLeastOneSuccessfulStrategy();
+    }
+
+    protected Authenticator authenticator() {
+        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
+        authenticator.setAuthenticationStrategy(authenticationStrategy());
+        return authenticator;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
new file mode 100644
index 0000000..d575352
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroAnnotationProcessorConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+public class ShiroAnnotationProcessorConfiguration extends AbstractShiroAnnotationProcessorConfiguration{
+
+    @Bean
+    @DependsOn("lifecycleBeanPostProcessor")
+    protected DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+        return super.defaultAdvisorAutoProxyCreator();
+    }
+
+    @Bean
+    protected AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
+        return super.authorizationAttributeSourceAdvisor(securityManager);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
new file mode 100644
index 0000000..37e1321
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroBeanConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+public class ShiroBeanConfiguration extends AbstractShiroBeanConfiguration {
+
+    @Bean
+    @Override
+    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+        return super.lifecycleBeanPostProcessor();
+    }
+
+    @Bean
+    @Override
+    protected EventBus eventBus() {
+        return super.eventBus();
+    }
+
+    @Bean
+    @Override
+    public ShiroEventBusBeanPostProcessor shiroEventBusAwareBeanPostProcessor() {
+        return super.shiroEventBusAwareBeanPostProcessor();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroConfiguration.java
new file mode 100644
index 0000000..dfd7c41
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/config/ShiroConfiguration.java
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import org.apache.shiro.authc.Authenticator;
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authz.Authorizer;
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.mgt.*;
+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.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
+@Import({ShiroBeanConfiguration.class})
+public class ShiroConfiguration extends AbstractShiroConfiguration {
+
+
+    @Bean
+    @Override
+    protected SessionsSecurityManager securityManager(List<Realm> realms) {
+        return super.securityManager(realms);
+    }
+
+    @Bean
+    @Override
+    protected SessionManager sessionManager() {
+        return super.sessionManager();
+    }
+
+    @Bean
+    @Override
+    protected SubjectDAO subjectDAO() {
+        return super.subjectDAO();
+    }
+
+    @Bean
+    @Override
+    protected SessionStorageEvaluator sessionStorageEvaluator() {
+        return super.sessionStorageEvaluator();
+    }
+
+    @Bean
+    @Override
+    protected SubjectFactory subjectFactory() {
+        return super.subjectFactory();
+    }
+
+    @Bean
+    @Override
+    protected SessionFactory sessionFactory() {
+        return super.sessionFactory();
+    }
+
+    @Bean
+    @Override
+    protected SessionDAO sessionDAO() {
+        return super.sessionDAO();
+    }
+
+    @Bean
+    @Override
+    protected Authorizer authorizer() {
+        return super.authorizer();
+    }
+
+    @Bean
+    @Override
+    protected AuthenticationStrategy authenticationStrategy() {
+        return super.authenticationStrategy();
+    }
+
+    @Bean
+    @Override
+    protected Authenticator authenticator() {
+        return super.authenticator();
+    }
+
+    @Bean
+    @Override
+    protected RememberMeManager rememberMeManager() {
+        return super.rememberMeManager();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
new file mode 100644
index 0000000..5762612
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebConfiguration.java
@@ -0,0 +1,157 @@
+/*
+ * 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.web.config;
+
+import org.apache.shiro.mgt.RememberMeManager;
+import org.apache.shiro.mgt.SessionsSecurityManager;
+import org.apache.shiro.mgt.SubjectFactory;
+import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.spring.config.AbstractShiroConfiguration;
+import org.apache.shiro.web.mgt.CookieRememberMeManager;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.mgt.DefaultWebSubjectFactory;
+import org.apache.shiro.web.servlet.Cookie;
+import org.apache.shiro.web.servlet.SimpleCookie;
+import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
+import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ * @since 1.4.0
+ */
+public class AbstractShiroWebConfiguration extends AbstractShiroConfiguration {
+
+    @Value("#{ @environment['shiro.sessionManager.sessionIdCookieEnabled'] ?: true }")
+    protected boolean sessionIdCookieEnabled;
+
+    @Value("#{ @environment['shiro.sessionManager.sessionIdUrlRewritingEnabled'] ?: true }")
+    protected boolean sessionIdUrlRewritingEnabled;
+
+    @Value("#{ @environment['shiro.userNativeSessionManager'] ?: false }")
+    protected boolean useNativeSessionManager;
+
+
+    // Session Cookie info
+
+    @Value("#{ @environment['shiro.sessionManager.cookie.name'] ?: T(org.apache.shiro.web.servlet.ShiroHttpSession).DEFAULT_SESSION_ID_NAME }")
+    protected String sessionIdCookieName;
+
+    @Value("#{ @environment['shiro.sessionManager.cookie.maxAge'] ?: T(org.apache.shiro.web.servlet.SimpleCookie).DEFAULT_MAX_AGE }")
+    protected int sessionIdCookieMaxAge;
+
+    @Value("#{ @environment['shiro.sessionManager.cookie.domain'] ?: null }")
+    protected String sessionIdCookieDomain;
+
+    @Value("#{ @environment['shiro.sessionManager.cookie.path'] ?: null }")
+    protected String sessionIdCookiePath;
+
+    @Value("#{ @environment['shiro.sessionManager.cookie.secure'] ?: false }")
+    protected boolean sessionIdCookieSecure;
+
+
+    // RememberMe Cookie info
+
+    @Value("#{ @environment['shiro.rememberMeManager.cookie.name'] ?: T(org.apache.shiro.web.mgt.CookieRememberMeManager).DEFAULT_REMEMBER_ME_COOKIE_NAME }")
+    protected String rememberMeCookieName;
+
+    @Value("#{ @environment['shiro.rememberMeManager.cookie.maxAge'] ?: T(org.apache.shiro.web.servlet.Cookie).ONE_YEAR }")
+    protected int rememberMeCookieMaxAge;
+
+    @Value("#{ @environment['shiro.rememberMeManager.cookie.domain'] ?: null }")
+    protected String rememberMeCookieDomain;
+
+    @Value("#{ @environment['shiro.rememberMeManager.cookie.path'] ?: null }")
+    protected String rememberMeCookiePath;
+
+    @Value("#{ @environment['shiro.rememberMeManager.cookie.secure'] ?: false }")
+    protected boolean rememberMeCookieSecure;
+
+
+    protected SessionManager nativeSessionManager() {
+        DefaultWebSessionManager webSessionManager = new DefaultWebSessionManager();
+        webSessionManager.setSessionIdCookieEnabled(sessionIdCookieEnabled);
+        webSessionManager.setSessionIdUrlRewritingEnabled(sessionIdUrlRewritingEnabled);
+        webSessionManager.setSessionIdCookie(sessionCookieTemplate());
+
+        webSessionManager.setSessionFactory(sessionFactory());
+        webSessionManager.setSessionDAO(sessionDAO());
+        webSessionManager.setDeleteInvalidSessions(sessionManagerDeleteInvalidSessions);
+
+        return webSessionManager;
+    }
+
+    protected Cookie sessionCookieTemplate() {
+        return buildCookie(
+                sessionIdCookieName,
+                sessionIdCookieMaxAge,
+                sessionIdCookiePath,
+                sessionIdCookieDomain,
+                sessionIdCookieSecure);
+    }
+
+    protected Cookie rememberMeCookieTemplate() {
+        return buildCookie(
+                rememberMeCookieName,
+                rememberMeCookieMaxAge,
+                rememberMeCookiePath,
+                rememberMeCookieDomain,
+                rememberMeCookieSecure);
+    }
+
+    protected Cookie buildCookie(String name, int maxAge, String path, String domain, boolean secure) {
+        Cookie cookie = new SimpleCookie(name);
+        cookie.setHttpOnly(true);
+        cookie.setMaxAge(maxAge);
+        cookie.setPath(path);
+        cookie.setDomain(domain);
+        cookie.setSecure(secure);
+
+        return cookie;
+    }
+
+    @Override
+    protected SessionManager sessionManager() {
+        if (useNativeSessionManager) {
+            return nativeSessionManager();
+        }
+        return new ServletContainerSessionManager();
+    }
+
+    protected RememberMeManager rememberMeManager() {
+        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
+        cookieRememberMeManager.setCookie(rememberMeCookieTemplate());
+        return cookieRememberMeManager;
+    }
+
+    @Override
+    protected SubjectFactory subjectFactory() {
+        return new DefaultWebSubjectFactory();
+    }
+
+    protected SessionsSecurityManager createSecurityManager() {
+
+        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+        securityManager.setSubjectDAO(subjectDAO());
+        securityManager.setSubjectFactory(subjectFactory());
+        securityManager.setRememberMeManager(rememberMeManager());
+
+        return securityManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java
new file mode 100644
index 0000000..fb12601
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/AbstractShiroWebFilterConfiguration.java
@@ -0,0 +1,59 @@
+/*
+ * 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.web.config;
+
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+
+/**
+ * @since 1.4.0
+ */
+public class AbstractShiroWebFilterConfiguration {
+
+    @Autowired
+    protected SecurityManager securityManager;
+
+    @Autowired
+    protected ShiroFilterChainDefinition shiroFilterChainDefinition;
+
+    @Value("#{ @environment['shiro.loginUrl'] ?: '/login.jsp' }")
+    protected String loginUrl;
+
+    @Value("#{ @environment['shiro.successUrl'] ?: '/' }")
+    protected String successUrl;
+
+    @Value("#{ @environment['shiro.unauthorizedUrl'] ?: null }")
+    protected String unauthorizedUrl;
+
+    protected ShiroFilterFactoryBean shiroFilterFactoryBean() {
+        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
+
+        filterFactoryBean.setLoginUrl(loginUrl);
+        filterFactoryBean.setSuccessUrl(successUrl);
+        filterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
+
+        filterFactoryBean.setSecurityManager(securityManager);
+        filterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
+
+        return filterFactoryBean;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/DefaultShiroFilterChainDefinition.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/DefaultShiroFilterChainDefinition.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/DefaultShiroFilterChainDefinition.java
new file mode 100644
index 0000000..bbd3f60
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/DefaultShiroFilterChainDefinition.java
@@ -0,0 +1,44 @@
+/*
+ * 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.web.config;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @since 1.4.0
+ */
+public class DefaultShiroFilterChainDefinition implements ShiroFilterChainDefinition {
+
+    final private Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
+
+    public void addPathDefinition(String antPath, String definition) {
+        filterChainDefinitionMap.put(antPath, definition);
+    }
+
+    public void addPathDefinitions(Map<String, String> pathDefinitions) {
+        filterChainDefinitionMap.putAll(pathDefinitions);
+    }
+
+    @Override
+    public Map<String, String> getFilterChainMap() {
+        return filterChainDefinitionMap;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroFilterChainDefinition.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroFilterChainDefinition.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroFilterChainDefinition.java
new file mode 100644
index 0000000..fe9f5d6
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroFilterChainDefinition.java
@@ -0,0 +1,29 @@
+/*
+ * 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.web.config;
+
+import java.util.Map;
+
+/**
+ * @since 1.4.0
+ */
+public interface ShiroFilterChainDefinition {
+
+    Map<String, String> getFilterChainMap();
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
new file mode 100644
index 0000000..e3bb516
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebConfiguration.java
@@ -0,0 +1,120 @@
+/*
+ * 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.web.config;
+
+import org.apache.shiro.authc.Authenticator;
+import org.apache.shiro.authc.pam.AuthenticationStrategy;
+import org.apache.shiro.authz.Authorizer;
+import org.apache.shiro.mgt.*;
+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.web.servlet.Cookie;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+import java.util.List;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+public class ShiroWebConfiguration extends AbstractShiroWebConfiguration {
+
+    @Bean
+    @Override
+    protected SubjectDAO subjectDAO() {
+        return super.subjectDAO();
+    }
+
+    @Bean
+    @Override
+    protected SessionStorageEvaluator sessionStorageEvaluator() {
+        return super.sessionStorageEvaluator();
+    }
+
+    @Bean
+    @Override
+    protected SessionFactory sessionFactory() {
+        return super.sessionFactory();
+    }
+
+    @Bean
+    @Override
+    protected SessionDAO sessionDAO() {
+        return super.sessionDAO();
+    }
+
+    @Bean(name = "sessionCookieTemplate")
+    @Override
+    protected Cookie sessionCookieTemplate() {
+        return super.sessionCookieTemplate();
+    }
+
+    @Bean(name = "rememberMeCookieTemplate")
+    @Override
+    protected Cookie rememberMeCookieTemplate() {
+        return super.rememberMeCookieTemplate();
+    }
+
+    @Bean
+    @Override
+    protected RememberMeManager rememberMeManager() {
+        return super.rememberMeManager();
+    }
+
+    @Bean
+    @Override
+    protected SubjectFactory subjectFactory() {
+        return super.subjectFactory();
+    }
+
+    @Bean
+    @Override
+    protected Authorizer authorizer() {
+        return super.authorizer();
+    }
+
+    @Bean
+    @Override
+    protected AuthenticationStrategy authenticationStrategy() {
+        return super.authenticationStrategy();
+    }
+
+    @Bean
+    @Override
+    protected Authenticator authenticator() {
+        return super.authenticator();
+    }
+
+    @Bean
+    @Override
+    protected SessionManager sessionManager() {
+        return super.sessionManager();
+    }
+
+    @Bean
+    @Override
+    protected SessionsSecurityManager securityManager(List<Realm> realms) {
+        return super.securityManager(realms);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
new file mode 100644
index 0000000..72a4ecb
--- /dev/null
+++ b/support/spring/src/main/java/org/apache/shiro/spring/web/config/ShiroWebFilterConfiguration.java
@@ -0,0 +1,37 @@
+/*
+ * 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.web.config;
+
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @since 1.4.0
+ */
+@Configuration
+public class ShiroWebFilterConfiguration extends AbstractShiroWebFilterConfiguration {
+
+    @Bean
+    @Override
+    protected ShiroFilterFactoryBean shiroFilterFactoryBean() {
+        return super.shiroFilterFactoryBean();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroBeanConfigurationTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroBeanConfigurationTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroBeanConfigurationTest.groovy
new file mode 100644
index 0000000..6c9b893
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroBeanConfigurationTest.groovy
@@ -0,0 +1,60 @@
+/*
+ * 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
+
+import org.apache.shiro.event.EventBus
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
+
+import static org.junit.Assert.*
+
+/**
+ * @since 1.4.0
+ */
+@ContextConfiguration(classes = [ShiroBeanConfiguration, EventBusConsumersTestConfiguration])
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ShiroBeanConfigurationTest {
+
+    @Autowired
+    private EventBus eventBus;
+
+    @Autowired
+    private EventBusConsumersTestConfiguration.EventBusAwareObject eventBusAwareObject;
+
+    @Autowired
+    private EventBusConsumersTestConfiguration.EventSubscriber eventSubscriber;
+
+    @Test
+    public void testBasicUsage() {
+
+        assertNotNull eventBus
+        assertNotNull eventBusAwareObject
+        assertNotNull eventSubscriber
+
+        assertTrue eventBus.registry.containsKey(eventSubscriber)
+        assertSame(eventBus, eventBusAwareObject.eventBus)
+
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationTest.groovy
new file mode 100644
index 0000000..12640e5
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationTest.groovy
@@ -0,0 +1,75 @@
+/*
+ * 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
+
+import org.apache.shiro.authc.UsernamePasswordToken
+import org.apache.shiro.authz.ModularRealmAuthorizer
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.mgt.DefaultSecurityManager
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.realm.text.TextConfigurationRealm
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
+import org.apache.shiro.subject.Subject
+import org.junit.Assert
+import org.junit.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.*
+import static org.junit.Assert.*
+
+/**
+ * @since 1.4.0
+ */
+@ContextConfiguration(classes = [RealmTestConfiguration, ShiroConfiguration])
+public class ShiroConfigurationTest extends AbstractJUnit4SpringContextTests {
+
+    @Autowired
+    private SecurityManager securityManager
+
+    @Autowired
+    private EventBus eventBus;
+
+    @Test
+    public void testMinimalConfiguration() {
+
+        // first do a quick check of the injected objects
+        assertNotNull securityManager
+        assertThat securityManager.realms, allOf(hasSize(1), hasItem(instanceOf(TextConfigurationRealm)))
+        assertNull securityManager.cacheManager
+
+        assertSame(((DefaultSecurityManager)securityManager).getEventBus(), eventBus)
+
+        def defaultSecurityManager = (DefaultSecurityManager) securityManager
+        def authorizor = (ModularRealmAuthorizer) defaultSecurityManager.getAuthorizer();
+        assertNull authorizor.rolePermissionResolver
+        assertNull authorizor.permissionResolver
+
+        // 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/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationWithOptionalComponentsTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationWithOptionalComponentsTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationWithOptionalComponentsTest.groovy
new file mode 100644
index 0000000..ec42297
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroConfigurationWithOptionalComponentsTest.groovy
@@ -0,0 +1,73 @@
+/*
+ * 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
+
+import org.apache.shiro.authc.UsernamePasswordToken
+import org.apache.shiro.authz.ModularRealmAuthorizer
+import org.apache.shiro.mgt.DefaultSecurityManager
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.realm.text.TextConfigurationRealm
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
+import org.apache.shiro.subject.Subject
+import org.junit.Test
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
+
+import static org.junit.Assert.*
+import static org.hamcrest.Matchers.*
+import static org.hamcrest.MatcherAssert.*
+
+/**
+ * @since 1.4.0
+ */
+@ContextConfiguration(classes = [RealmTestConfiguration, OptionalComponentsTestConfiguration, ShiroConfiguration, ShiroAnnotationProcessorConfiguration])
+public class ShiroConfigurationWithOptionalComponentsTest extends AbstractJUnit4SpringContextTests {
+
+    @Autowired
+    private SecurityManager securityManager
+
+    @Autowired
+    private AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
+
+    @Test
+    public void testMinimalConfiguration() {
+
+        // first do a quick check of the injected objects
+        assertNotNull authorizationAttributeSourceAdvisor
+        assertNotNull securityManager
+        assertSame securityManager, authorizationAttributeSourceAdvisor.securityManager
+        assertThat securityManager.realms, allOf(hasSize(1), hasItem(instanceOf(TextConfigurationRealm)))
+        assertNotNull securityManager.cacheManager
+
+        def defaultSecurityManager = (DefaultSecurityManager) securityManager
+        def authorizor = (ModularRealmAuthorizer) defaultSecurityManager.getAuthorizer();
+        assertNotNull authorizor.rolePermissionResolver
+        assertNotNull authorizor.permissionResolver
+
+        // 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/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
new file mode 100644
index 0000000..b4224a1
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
@@ -0,0 +1,69 @@
+/*
+ * 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
+
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.event.EventBusAware
+import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor
+import org.junit.Assert
+import org.junit.Test
+
+import static org.easymock.EasyMock.*
+
+/**
+ * Tests for {@link org.apache.shiro.spring.ShiroEventBusBeanPostProcessor}
+ */
+class ShiroEventBusAwareBeanPostProcessorTest {
+
+    @Test
+    void testPostConstructNonAware() {
+
+        def eventBus = createStrictMock(EventBus)
+        def bean = createStrictMock(Object)
+
+        replay eventBus, bean
+
+        def postProcessor = new ShiroEventBusBeanPostProcessor(eventBus);
+        def resultAfter = postProcessor.postProcessAfterInitialization(bean, "bean")
+        def resultBefore = postProcessor.postProcessBeforeInitialization(bean, "bean")
+
+        verify eventBus, bean
+        Assert.assertSame resultAfter, bean
+        Assert.assertSame resultBefore, bean
+    }
+
+    @Test
+    void testPostConstructWithEventBusAware() {
+
+        def eventBus = createStrictMock(EventBus)
+        def bean = createStrictMock(EventBusAware)
+        bean.eventBus = eventBus
+
+        replay eventBus, bean
+
+        def postProcessor = new ShiroEventBusBeanPostProcessor(eventBus);
+        def resultAfter = postProcessor.postProcessAfterInitialization(bean, "bean")
+        def resultBefore = postProcessor.postProcessBeforeInitialization(bean, "bean")
+
+        verify eventBus, bean
+        Assert.assertSame resultAfter, bean
+        Assert.assertSame resultBefore, bean
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationTest.groovy
new file mode 100644
index 0000000..6031deb
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationTest.groovy
@@ -0,0 +1,106 @@
+/*
+ * 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.web.config
+
+import org.apache.shiro.event.EventBus
+import org.apache.shiro.event.support.DefaultEventBus
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.realm.text.TextConfigurationRealm
+import org.apache.shiro.spring.config.EventBusTestConfiguration
+import org.apache.shiro.spring.config.RealmTestConfiguration
+import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration
+import org.apache.shiro.spring.config.ShiroBeanConfiguration
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
+import org.apache.shiro.web.mgt.CookieRememberMeManager
+import org.apache.shiro.web.mgt.WebSecurityManager
+import org.apache.shiro.web.servlet.Cookie
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Qualifier
+import org.springframework.expression.Expression
+import org.springframework.expression.ExpressionParser
+import org.springframework.expression.spel.standard.SpelExpressionParser
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.*
+import static org.junit.Assert.*
+
+/**
+ * @since 1.4.0
+ */
+@ContextConfiguration(classes = [EventBusTestConfiguration, RealmTestConfiguration, ShiroWebConfiguration])
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ShiroWebConfigurationTest {
+
+    @Autowired
+    private SecurityManager securityManager
+
+    @Autowired
+    @Qualifier("rememberMeCookieTemplate")
+    private Cookie rememberMeCookie;
+
+    @Autowired
+    @Qualifier("sessionCookieTemplate")
+    private Cookie sessionCookieTemplate;
+
+    @Test
+    public void testMinimalConfiguration() {
+
+        // first do a quick check of the injected objects
+        assertNotNull securityManager
+        assertThat securityManager, instanceOf(WebSecurityManager)
+        assertThat securityManager.realms, allOf(hasSize(1), hasItem(instanceOf(TextConfigurationRealm)))
+        assertNull securityManager.cacheManager
+
+
+//        // 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()
+    }
+
+    @Test
+    public void fakeCookie() {
+        ExpressionParser parser = new SpelExpressionParser();
+        Expression exp = parser.parseExpression("T(org.apache.shiro.web.mgt.CookieRememberMeManager).DEFAULT_REMEMBER_ME_COOKIE_NAME");
+//        Expression exp = parser.parseExpression("@environment['shiro.rememberMeManager.cookie.name'] ?: T(org.apache.shiro.web.mgt.CookieRememberMeManager).DEFAULT_REMEMBER_ME_COOKIE_NAME");
+
+        String message = (String) exp.getValue();
+
+        println(message);
+    }
+
+    @Test
+    public void rememberMeCookie() {
+        assertEquals "rememberMe", rememberMeCookie.name
+    }
+
+    @Test
+    public void sessionCookie() {
+        assertSame "JSESSIONID", sessionCookieTemplate.name
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationWithCacheTest.groovy
----------------------------------------------------------------------
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationWithCacheTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationWithCacheTest.groovy
new file mode 100644
index 0000000..296b519
--- /dev/null
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/web/config/ShiroWebConfigurationWithCacheTest.groovy
@@ -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.web.config
+
+import org.apache.shiro.mgt.SecurityManager
+import org.apache.shiro.realm.text.TextConfigurationRealm
+import org.apache.shiro.spring.config.EventBusTestConfiguration
+import org.apache.shiro.spring.config.RealmTestConfiguration
+import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.*
+
+/**
+ * @since 1.4.0
+ */
+@ContextConfiguration(classes = [EventBusTestConfiguration, RealmTestConfiguration, CacheManagerConfiguration, ShiroWebConfiguration])
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ShiroWebConfigurationWithCacheTest {
+
+    @Autowired
+    private SecurityManager securityManager
+
+    @Test
+    public void testMinimalConfiguration() {
+
+        // first do a quick check of the injected objects
+        Assert.assertNotNull securityManager
+        assertThat securityManager.realms, allOf(hasSize(1), hasItem(instanceOf(TextConfigurationRealm)))
+        Assert.assertNotNull securityManager.cacheManager
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusConsumersTestConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusConsumersTestConfiguration.java b/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusConsumersTestConfiguration.java
new file mode 100644
index 0000000..83d35be
--- /dev/null
+++ b/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusConsumersTestConfiguration.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.spring.config;
+
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class EventBusConsumersTestConfiguration {
+
+    @Bean
+    protected EventBusAwareObject eventBusAwareObject() {
+        return new EventBusAwareObject();
+    }
+
+    @Bean
+    protected EventSubscriber subscriber(){
+        return new EventSubscriber();
+    }
+
+    public class EventBusAwareObject implements EventBusAware {
+
+        private EventBus eventBus;
+
+        public EventBus getEventBus() {
+            return eventBus;
+        }
+
+        public void setEventBus(EventBus eventBus) {
+            this.eventBus = eventBus;
+        }
+    }
+
+    public class EventSubscriber {
+
+        @Subscribe
+        public void listen(Object object) {}
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusTestConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusTestConfiguration.java b/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusTestConfiguration.java
new file mode 100644
index 0000000..2050b0f
--- /dev/null
+++ b/support/spring/src/test/java/org/apache/shiro/spring/config/EventBusTestConfiguration.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.support.DefaultEventBus;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class EventBusTestConfiguration {
+
+    @Bean
+    protected EventBus eventBus() {
+        return new DefaultEventBus();
+    }
+
+
+
+}


[19/20] shiro git commit: SHIRO-493 - Adding new methods and deprecating old to ShiroWebModule to support Guice 4

Posted by bd...@apache.org.
http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 53c8946..d85823e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,6 +110,17 @@
 
     </properties>
 
+    <modules>
+        <module>core</module>
+        <module>web</module>
+        <module>support</module>
+        <module>samples</module>
+        <module>tools</module>
+        <module>all</module>
+        <module>integration-tests</module>
+        <module>test-coverage</module>
+    </modules>
+
     <mailingLists>
         <mailingList>
             <name>Apache Shiro Users Mailing List</name>
@@ -197,16 +208,6 @@
         </developer>
     </developers>
 
-    <modules>
-        <module>core</module>
-        <module>web</module>
-        <module>support</module>
-        <module>samples</module>
-        <module>tools</module>
-        <module>all</module>
-        <module>test-coverage</module>
-    </modules>
-
     <build>
         <pluginManagement>
             <plugins>
@@ -384,6 +385,25 @@
                         </excludes>
                     </configuration>
                 </plugin>
+                <plugin>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-maven-plugin</artifactId>
+                    <version>${jetty.version}</version>
+                    <configuration>
+                        <contextPath>/</contextPath>
+                        <httpConnector>
+                            <port>9080</port>
+                            <idleTimeout>60000</idleTimeout>
+                        </httpConnector>
+                        <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+                            <filename>./target/yyyy_mm_dd.request.log</filename>
+                            <retainDays>90</retainDays>
+                            <append>true</append>
+                            <extended>false</extended>
+                            <logTimeZone>GMT</logTimeZone>
+                        </requestLog>
+                    </configuration>
+                </plugin>
             </plugins>
         </pluginManagement>
         <plugins>
@@ -445,6 +465,13 @@
                                 <goal>prepare-agent</goal>
                             </goals>
                         </execution>
+                        <execution>
+                            <id>prepare-agent-integration</id>
+                            <phase>pre-integration-test</phase>
+                            <goals>
+                                <goal>prepare-agent-integration</goal>
+                            </goals>
+                        </execution>
                     </executions>
                 </plugin>
             <!-- Allow Groovy tests to run: -->
@@ -485,7 +512,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
-                <version>2.3.1</version>
+                <version>3.0.2</version>
                 <configuration>
                     <archive>
                         <manifest>
@@ -1000,6 +1027,12 @@
                 <version>1.1.2</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>com.github.mjeanroy</groupId>
+                <artifactId>junit-servers-jetty</artifactId>
+                <version>0.4.2</version>
+                <scope>test</scope>
+            </dependency>
         </dependencies>
     </dependencyManagement>
     
@@ -1093,7 +1126,7 @@
             </plugin>
             <plugin>
                 <artifactId>maven-surefire-report-plugin</artifactId>
-                <version>2.5</version>
+                <version>2.19.1</version>
             </plugin>
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
@@ -1143,8 +1176,9 @@
                 <artifactId>jacoco-maven-plugin</artifactId>
                 <reportSets>
                     <reportSet>
-                        <id>javadoc-aggregate</id>
+                        <id>jacoco-aggregate</id>
                         <reports>
+                            <report>report-integration</report>
                             <report>report</report>
                         </reports>
                     </reportSet>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/samples/guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index ce9d56c..e51c0e0 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -32,30 +32,9 @@
 
 	<build>
 	    <plugins>
-	        <plugin>
-	            <artifactId>maven-surefire-plugin</artifactId>
-	            <configuration>
-	                <forkMode>never</forkMode>
-	            </configuration>
-	        </plugin>
 			<plugin>
 				<groupId>org.eclipse.jetty</groupId>
 				<artifactId>jetty-maven-plugin</artifactId>
-				<version>${jetty.version}</version>
-				<configuration>
-					<contextPath>/</contextPath>
-					<httpConnector>
-						<port>9080</port>
-						<idleTimeout>60000</idleTimeout>
-					</httpConnector>
-					<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
-						<filename>./target/yyyy_mm_dd.request.log</filename>
-						<retainDays>90</retainDays>
-						<append>true</append>
-						<extended>false</extended>
-						<logTimeZone>GMT</logTimeZone>
-					</requestLog>
-				</configuration>
 			</plugin>
 	    </plugins>
 	</build>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/samples/guice/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java b/samples/guice/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
index 01a0113..945ae70 100644
--- a/samples/guice/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
+++ b/samples/guice/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
@@ -31,6 +31,7 @@ import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 import org.apache.shiro.web.mgt.WebSecurityManager;
 
 import javax.inject.Singleton;
+import javax.servlet.Filter;
 import javax.servlet.ServletContext;
 import java.net.MalformedURLException;
 import java.net.URL;
@@ -56,7 +57,8 @@ public class SampleShiroServletModule extends ShiroWebModule {
         this.addFilterChain("/login.jsp", AUTHC);
         this.addFilterChain("/logout", LOGOUT);
         this.addFilterChain("/account/**", AUTHC);
-        this.addFilterChain("/remoting/**", AUTHC, config(ROLES, "b2bClient"), config(PERMS, "remote:invoke:lan,wan"));
+
+        this.addFilterChain("/remoting/**", filterConfig(AUTHC), filterConfig(ROLES, "b2bClient"), filterConfig(PERMS, "remote:invoke:lan,wan"));
     }
 
     @Provides

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/samples/jaxrs/pom.xml
----------------------------------------------------------------------
diff --git a/samples/jaxrs/pom.xml b/samples/jaxrs/pom.xml
index c2ef72f..ad3716e 100644
--- a/samples/jaxrs/pom.xml
+++ b/samples/jaxrs/pom.xml
@@ -62,12 +62,6 @@
         </pluginManagement>
         <plugins>
             <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <forkMode>never</forkMode>
-                </configuration>
-            </plugin>
-            <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
             </plugin>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/samples/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/pom.xml b/samples/servlet-plugin/pom.xml
index 75c7cb6..c03d4f1 100644
--- a/samples/servlet-plugin/pom.xml
+++ b/samples/servlet-plugin/pom.xml
@@ -34,12 +34,6 @@
     <build>
         <plugins>
             <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <forkMode>never</forkMode>
-                </configuration>
-            </plugin>
-            <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
                 <version>${jetty.version}</version>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index 8b045fd..8d93a9a 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -40,12 +40,6 @@
     <build>
         <plugins>
             <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <forkMode>never</forkMode>
-                </configuration>
-            </plugin>
-            <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
                 <version>${jetty.version}</version>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/pom.xml
----------------------------------------------------------------------
diff --git a/support/guice/pom.xml b/support/guice/pom.xml
index 78a97f8..f91cb4e 100644
--- a/support/guice/pom.xml
+++ b/support/guice/pom.xml
@@ -31,10 +31,6 @@
     <name>Apache Shiro :: Support :: Guice</name>
     <packaging>bundle</packaging>
 
-    <properties>
-        <guice.version>3.0</guice.version>
-    </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.apache.shiro</groupId>
@@ -68,6 +64,16 @@
             <artifactId>jcl-over-slf4j</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -89,7 +95,18 @@
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <!-- Package tests so we can re-run them with guice4 -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
-
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
----------------------------------------------------------------------
diff --git a/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java b/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
index 00c40a4..2eac73d 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/ShiroModule.java
@@ -18,20 +18,33 @@
  */
 package org.apache.shiro.guice;
 
+import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 import java.util.WeakHashMap;
 
 import javax.annotation.PreDestroy;
 
+import com.google.inject.Provider;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.name.Names;
+import com.google.inject.spi.InjectionListener;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
 import org.apache.shiro.config.ConfigurationException;
 import org.apache.shiro.env.Environment;
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+import org.apache.shiro.event.support.DefaultEventBus;
 import org.apache.shiro.mgt.DefaultSecurityManager;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.realm.Realm;
 import org.apache.shiro.session.mgt.DefaultSessionManager;
 import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.util.ClassUtils;
 import org.apache.shiro.util.Destroyable;
 
 import com.google.inject.Key;
@@ -57,6 +70,9 @@ public abstract class ShiroModule extends PrivateModule implements Destroyable {
         bindSessionManager(bind(SessionManager.class));
         bindEnvironment(bind(Environment.class));
         bindListener(BeanTypeListener.MATCHER, new BeanTypeListener());
+        bindEventBus(bind(EventBus.class));
+        bindListener(Matchers.any(), new SubscribedEventTypeListener());
+        bindListener(Matchers.any(), new EventBusAwareTypeListener());
         final DestroyableInjectionListener.DestroyableRegistry registry = new DestroyableInjectionListener.DestroyableRegistry() {
             public void add(Destroyable destroyable) {
                 ShiroModule.this.add(destroyable);
@@ -70,6 +86,7 @@ public abstract class ShiroModule extends PrivateModule implements Destroyable {
         bindListener(LifecycleTypeListener.MATCHER, new LifecycleTypeListener(registry));
 
         expose(SecurityManager.class);
+        expose(EventBus.class);
 
         configureShiro();
         bind(realmCollectionKey())
@@ -153,6 +170,15 @@ public abstract class ShiroModule extends PrivateModule implements Destroyable {
     }
 
     /**
+     * Binds the EventBus.  Override this method in order to provide your own {@link EventBus} binding.
+     * @param bind
+     * @since 1.4
+     */
+    protected void bindEventBus(AnnotatedBindingBuilder<EventBus> bind) {
+        bind.to(DefaultEventBus.class).asEagerSingleton();
+    }
+
+    /**
      * Destroys all beans created within this module that implement {@link org.apache.shiro.util.Destroyable}.  Should be called when this
      * module will no longer be used.
      *
@@ -167,4 +193,39 @@ public abstract class ShiroModule extends PrivateModule implements Destroyable {
     public void add(Destroyable destroyable) {
         this.destroyables.add(destroyable);
     }
+
+    private class SubscribedEventTypeListener implements TypeListener {
+        @Override
+        public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
+
+            final Provider<EventBus> eventBusProvider = typeEncounter.getProvider(EventBus.class);
+
+            List<Method> methods = ClassUtils.getAnnotatedMethods(typeLiteral.getRawType(), Subscribe.class);
+            if (methods != null && !methods.isEmpty()) {
+                typeEncounter.register( new InjectionListener<I>() {
+                    @Override
+                    public void afterInjection(Object o) {
+                        eventBusProvider.get().register(o);
+                    }
+                });
+            }
+        }
+    }
+
+    private class EventBusAwareTypeListener implements TypeListener {
+        @Override
+        public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
+
+            final Provider<EventBus> eventBusProvider = typeEncounter.getProvider(EventBus.class);
+
+            if (EventBusAware.class.isAssignableFrom(typeLiteral.getRawType())) {
+                typeEncounter.register( new InjectionListener<I>() {
+                    @Override
+                    public void afterInjection(Object o) {
+                        ((EventBusAware)o).setEventBus(eventBusProvider.get());
+                    }
+                });
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
----------------------------------------------------------------------
diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java b/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
index 45bc916..15431e5 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/ShiroWebModule.java
@@ -18,10 +18,7 @@
  */
 package org.apache.shiro.guice.web;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.*;
 
 import javax.servlet.Filter;
 import javax.servlet.ServletContext;
@@ -31,6 +28,7 @@ import org.apache.shiro.env.Environment;
 import org.apache.shiro.guice.ShiroModule;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.util.StringUtils;
 import org.apache.shiro.web.env.WebEnvironment;
 import org.apache.shiro.web.filter.PathMatchingFilter;
 import org.apache.shiro.web.filter.authc.AnonymousFilter;
@@ -94,7 +92,7 @@ public abstract class ShiroWebModule extends ShiroModule {
      * We use a LinkedHashMap here to ensure that iterator order is the same as add order.  This is important, as the
      * FilterChainResolver uses iterator order when searching for a matching chain.
      */
-    private final Map<String, Key<? extends Filter>[]> filterChains = new LinkedHashMap<String, Key<? extends Filter>[]>();
+    private final Map<String, FilterConfig<? extends Filter>[]> filterChains = new LinkedHashMap<String, FilterConfig<? extends Filter>[]>();
     private final ServletContext servletContext;
 
     public ShiroWebModule(ServletContext servletContext) {
@@ -134,37 +132,65 @@ public abstract class ShiroWebModule extends ShiroModule {
 
         this.configureShiroWeb();
 
-        setupFilterChainConfigs();
-
-        bind(FilterChainResolver.class).toProvider(new FilterChainResolverProvider(filterChains));
+        bind(FilterChainResolver.class).toProvider(new FilterChainResolverProvider(setupFilterChainConfigs()));
     }
 
-    private void setupFilterChainConfigs() {
-        Map<Key<? extends PathMatchingFilter>, Map<String, String>> configs = new HashMap<Key<? extends PathMatchingFilter>, Map<String, String>>();
+    private Map<String, Key<? extends Filter>[]> setupFilterChainConfigs() {
+
+        // loop through and build a map of Filter Key -> Map<Path, Config>
+        Map<Key<? extends Filter>, Map<String, String>> filterToPathToConfig = new HashMap<Key<? extends Filter>, Map<String, String>>();
+
+        // At the same time build a map to return with Path -> Key[]
+        Map<String, Key<? extends Filter>[]> resultConfigMap = new HashMap<String, Key<? extends Filter>[]>();
+
+        for (Map.Entry<String, FilterConfig<? extends Filter>[]> filterChain : filterChains.entrySet()) {
+
+            String path = filterChain.getKey();
+
+            // collect the keys used for this path
+            List<Key<? extends Filter>> keysForPath = new ArrayList<Key<? extends Filter>>();
 
-        for (Map.Entry<String, Key<? extends Filter>[]> filterChain : filterChains.entrySet()) {
             for (int i = 0; i < filterChain.getValue().length; i++) {
-                Key<? extends Filter> key = filterChain.getValue()[i];
-                if (key instanceof FilterConfigKey) {
-                    FilterConfigKey<? extends PathMatchingFilter> configKey = (FilterConfigKey<? extends PathMatchingFilter>) key;
-                    key = configKey.getKey();
-                    filterChain.getValue()[i] = key;
-                    if (!PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
-                        throw new ConfigurationException("Config information requires a PathMatchingFilter - can't apply to " + key.getTypeLiteral().getRawType());
-                    }
-                    if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());
-                    configs.get(castToPathMatching(key)).put(filterChain.getKey(), configKey.getConfigValue());
-                } else if (PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
-	                  if (configs.get(castToPathMatching(key)) == null) configs.put(castToPathMatching(key), new HashMap<String, String>());
-                    configs.get(castToPathMatching(key)).put(filterChain.getKey(), "");
+                FilterConfig<? extends Filter> filterConfig = filterChain.getValue()[i];
+
+                Key<? extends Filter> key = filterConfig.getKey();
+                String config = filterConfig.getConfigValue();
+
+                // initialize key in filterToPathToConfig, if it doesn't exist
+                if (filterToPathToConfig.get(key) == null) {
+                    filterToPathToConfig.put((key), new HashMap<String, String>());
+                }
+                // now set the value
+                filterToPathToConfig.get(key).put(path, config);
+
+                // Config error if someone configured a non PathMatchingFilter with a config value
+                if (StringUtils.hasText(config) && !PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
+                    throw new ConfigurationException("Config information requires a PathMatchingFilter - can't apply to " + key.getTypeLiteral().getRawType());
                 }
+
+                // store the key in keysForPath
+                keysForPath.add(key);
             }
+
+            // map the current path to all of its Keys
+            resultConfigMap.put(path, keysForPath.toArray(new Key[keysForPath.size()]));
         }
-        for (Key<? extends PathMatchingFilter> filterKey : configs.keySet()) {
-            bindPathMatchingFilter(filterKey, configs.get(filterKey));
+
+        // now we find only the PathMatchingFilter and configure bindings
+        // non PathMatchingFilter, can be loaded with the default provider via the class name
+        for (Key<? extends Filter> key : filterToPathToConfig.keySet()) {
+            if (PathMatchingFilter.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
+                bindPathMatchingFilter(castToPathMatching(key), filterToPathToConfig.get(key));
+            }
+            else {
+                bind(key);
+            }
         }
+
+        return resultConfigMap;
     }
 
+
     private <T extends PathMatchingFilter> void bindPathMatchingFilter(Key<T> filterKey, Map<String, String> configs) {
         bind(filterKey).toProvider(new PathMatchingFilterProvider<T>(filterKey, configs)).asEagerSingleton();
     }
@@ -218,6 +244,126 @@ public abstract class ShiroWebModule extends ShiroModule {
         bind.to(WebGuiceEnvironment.class).asEagerSingleton();
     }
 
+    protected final void addFilterChain(String pattern, Key<? extends Filter> key) {
+        // check for legacy API
+        if (key instanceof FilterConfigKey) {
+            addLegacyFilterChain(pattern, (FilterConfigKey) key);
+        }
+        else {
+            addFilterChain(pattern, new FilterConfig<Filter>((Key<Filter>) key, ""));
+        }
+    }
+
+    /**
+     * Maps 'n' number of <code>filterConfig</code>s to a specific path pattern.<BR/>
+     * For example, a path of '/my_private_resource/**' to 'filterConfig(AUTHC)' would require
+     * any resource under the path '/my_private_resource' would be processed through the {@link FormAuthenticationFilter}.
+     *
+     * @param pattern URL patter to be mapped to a FilterConfig, e.g. '/my_private-path/**'
+     * @param filterConfigs FilterConfiguration representing the Filter and config to be used when processing resources on <code>pattern</code>.
+     * @since 1.4
+     */
+    protected final void addFilterChain(String pattern, FilterConfig<? extends Filter>... filterConfigs) {
+        filterChains.put(pattern, filterConfigs);
+    }
+
+    /**
+     * Builds a FilterConfig from a Filer and configuration String
+     * @param baseKey The Key of the Filter class to be used.
+     * @param <T> A Servlet Filter class.
+     * @return A FilterConfig used to map a String path to this configuration.
+     * @since 1.4
+     */
+    protected static <T extends Filter> FilterConfig<T> filterConfig(Key<T> baseKey, String configValue) {
+        return new FilterConfig<T>(baseKey, configValue);
+    }
+
+    /**
+     * Builds a FilterConfig from a Filer and configuration String
+     * @param baseKey The Key of the Filter class to be used.
+     * @param <T> A Servlet Filter class.
+     * @return A FilterConfig used to map a String path to this configuration.
+     * @since 1.4
+     */
+    protected static <T extends Filter> FilterConfig<T> filterConfig(Key<T> baseKey) {
+        return filterConfig(baseKey, "");
+    }
+
+    /**
+     * Builds a FilterConfig from a Filer and configuration String
+     * @param typeLiteral The TyleLiteral of the filter key to be used.
+     * @param configValue the configuration used.
+     * @param <T> A Servlet Filter class.
+     * @return A FilterConfig used to map a String path to this configuration.
+     * @since 1.4
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    protected static <T extends Filter> FilterConfig<T> filterConfig(TypeLiteral<T> typeLiteral, String configValue) {
+        return filterConfig(Key.get(typeLiteral), configValue);
+    }
+
+    /**
+     * Builds a FilterConfig from a Filer and configuration String
+     * @param type The filter to be used.
+     * @param configValue the configuration used.
+     * @param <T> A Servlet Filter class.
+     * @return A FilterConfig used to map a String path to this configuration.
+     * @since 1.4
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    protected static <T extends Filter> FilterConfig<T> filterConfig(Class<T> type, String configValue) {
+        return filterConfig(Key.get(type), configValue);
+    }
+
+
+    /**
+     * Filter configuration which pairs a Filter class with its configuration used on a path.
+     * @param <T> The Servlet Filter class.
+     * @since 1.4
+     */
+    public static class FilterConfig<T extends Filter> {
+        private Key<T> key;
+        private String configValue;
+
+        private FilterConfig(Key<T> key, String configValue) {
+            super();
+            this.key = key;
+            this.configValue = configValue;
+        }
+
+        public Key<T> getKey() {
+            return key;
+        }
+
+        public String getConfigValue() {
+            return configValue;
+        }
+    }
+
+
+
+
+
+
+
+    // legacy methods
+
+
+    static boolean isGuiceVersion3() {
+        try {
+            Class.forName("com.google.inject.multibindings.MapKey");
+            return false;
+        } catch (ClassNotFoundException e) {
+            return true;
+        }
+    }
+
+    private void addLegacyFilterChain(String pattern, FilterConfigKey filterConfigKey) {
+
+        FilterConfig<Filter> filterConfig = new FilterConfig<Filter>(filterConfigKey.getKey(), filterConfigKey.getConfigValue());
+        addFilterChain(pattern, filterConfig);
+    }
+
     /**
      * Adds a filter chain to the shiro configuration.
      * <p/>
@@ -228,24 +374,52 @@ public abstract class ShiroWebModule extends ShiroModule {
      * @param keys
      */
     @SuppressWarnings({"UnusedDeclaration"})
+    @Deprecated
     protected final void addFilterChain(String pattern, Key<? extends Filter>... keys) {
-        filterChains.put(pattern, keys);
+
+        // We need to extract the keys and FilterConfigKey and convert to the new format.
+
+        FilterConfig[] filterConfigs = new FilterConfig[keys.length];
+        for (int ii = 0; ii < keys.length; ii++) {
+            Key<? extends Filter> key = keys[ii];
+            // If this is a path matching filter, we need to remember the config
+            if (key instanceof FilterConfigKey) {
+                // legacy config
+                FilterConfigKey legacyKey = (FilterConfigKey) key;
+                filterConfigs[ii] = new FilterConfig(legacyKey.getKey(), legacyKey.getConfigValue());
+            }
+            else {
+                // Some other type of Filter key, no config
+                filterConfigs[ii] = new FilterConfig(key, "");
+            }
+        }
+
+        filterChains.put(pattern, filterConfigs);
     }
 
+    @Deprecated
     protected static <T extends PathMatchingFilter> Key<T> config(Key<T> baseKey, String configValue) {
+
+        if( !isGuiceVersion3()) {
+            throw new ConfigurationException("Method ShiroWebModule.config(Key<? extends PathMatchingFilter>, String configValue), is not supported when using Guice 4+");
+        }
+
         return new FilterConfigKey<T>(baseKey, configValue);
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
+    @Deprecated
     protected static <T extends PathMatchingFilter> Key<T> config(TypeLiteral<T> typeLiteral, String configValue) {
         return config(Key.get(typeLiteral), configValue);
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
+    @Deprecated
     protected static <T extends PathMatchingFilter> Key<T> config(Class<T> type, String configValue) {
         return config(Key.get(type), configValue);
     }
 
+    @Deprecated
     private static class FilterConfigKey<T extends PathMatchingFilter> extends Key<T> {
         private Key<T> key;
         private String configValue;
@@ -264,4 +438,5 @@ public abstract class ShiroWebModule extends ShiroModule {
             return configValue;
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
----------------------------------------------------------------------
diff --git a/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java b/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
index 4ff8b56..eee6230 100644
--- a/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
+++ b/support/guice/src/main/java/org/apache/shiro/guice/web/SimpleFilterChain.java
@@ -44,4 +44,13 @@ class SimpleFilterChain implements FilterChain {
             originalChain.doFilter(request, response);
         }
     }
+
+    /**
+     * Exposed for testing, not part of public API.
+     * @return an Iterater of filters.
+     */
+    Iterator<? extends Filter> getFilters() {
+        return chain;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java
----------------------------------------------------------------------
diff --git a/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java b/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java
index 4507076..526f4f7 100644
--- a/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java
+++ b/support/guice/src/test/java/org/apache/shiro/guice/ShiroModuleTest.java
@@ -28,6 +28,10 @@ import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authc.SimpleAuthenticationInfo;
 import org.apache.shiro.env.Environment;
+import org.apache.shiro.event.EventBus;
+import org.apache.shiro.event.EventBusAware;
+import org.apache.shiro.event.Subscribe;
+import org.apache.shiro.event.support.DefaultEventBus;
 import org.apache.shiro.mgt.DefaultSecurityManager;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.realm.Realm;
@@ -37,11 +41,13 @@ import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.Destroyable;
 import org.junit.Test;
 
+import java.lang.reflect.Field;
 import java.util.Collection;
+import java.util.Map;
 
 import static org.easymock.EasyMock.*;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
 
 public class ShiroModuleTest {
 
@@ -204,6 +210,82 @@ public class ShiroModuleTest {
         verify(myDestroyable);
     }
 
+    /**
+     * @since 1.4
+     * @throws Exception
+     */
+    @Test
+    public void testEventListener() throws Exception {
+
+        final MockRealm mockRealm = createMock(MockRealm.class);
+        final EventBus eventBus = createMock(EventBus.class);
+
+        // expect both objects to be registered
+        eventBus.register(anyObject(MockEventListener1.class));
+        eventBus.register(anyObject(MockEventListener2.class));
+        replay(eventBus);
+
+        final ShiroModule shiroModule = new ShiroModule() {
+            @Override
+            protected void configureShiro() {
+                bindRealm().to(MockRealm.class);
+
+                // bind our event listeners
+                binder().bind(MockEventListener1.class).asEagerSingleton();
+                binder().bind(MockEventListener2.class).asEagerSingleton();
+            }
+
+            @Override
+            protected void bindEventBus(AnnotatedBindingBuilder<EventBus> bind) {
+                bind.toInstance(eventBus);
+            }
+
+            @Provides
+            public MockRealm createRealm() {
+                return mockRealm;
+            }
+
+        };
+        Guice.createInjector(shiroModule);
+
+        verify(eventBus);
+
+    }
+
+    /**
+     * @since 1.4
+     * @throws Exception
+     */
+    @Test
+    public void testEventBusAware() throws Exception {
+
+        final MockRealm mockRealm = createMock(MockRealm.class);
+
+        final ShiroModule shiroModule = new ShiroModule() {
+            @Override
+            protected void configureShiro() {
+                bindRealm().to(MockRealm.class);
+
+                binder().bind(MockEventBusAware.class).asEagerSingleton();
+                expose(MockEventBusAware.class);
+            }
+
+            @Provides
+            public MockRealm createRealm() {
+                return mockRealm;
+            }
+
+        };
+        Injector injector = Guice.createInjector(shiroModule);
+        EventBus eventBus = injector.getInstance(EventBus.class);
+        SecurityManager securityManager = injector.getInstance(SecurityManager.class);
+
+        MockEventBusAware eventBusAware = injector.getInstance(MockEventBusAware.class);
+
+        assertSame(eventBus, eventBusAware.eventBus);
+        assertSame(eventBus, ((DefaultSecurityManager)securityManager).getEventBus());
+    }
+
     public static interface MockRealm extends Realm {
 
     }
@@ -227,4 +309,27 @@ public class ShiroModuleTest {
 
     public static interface MyDestroyable extends Destroyable {
     }
+
+    public static class MockEventListener1 {
+        @Subscribe
+        public void listenToAllAndDoNothing(Object o) {}
+    }
+
+    public static class MockEventListener2 {
+        @Subscribe
+        public void listenToAllAndDoNothing(Object o) {}
+    }
+
+    public static class MockEventBusAware implements EventBusAware {
+        private EventBus eventBus;
+
+        public EventBus getEventBus() {
+            return eventBus;
+        }
+
+        @Override
+        public void setEventBus(EventBus eventBus) {
+            this.eventBus = eventBus;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java
----------------------------------------------------------------------
diff --git a/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java b/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java
index 98add89..c1b3c32 100644
--- a/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java
+++ b/support/guice/src/test/java/org/apache/shiro/guice/web/FilterConfigTest.java
@@ -45,7 +45,8 @@ public class FilterConfigTest {
                 bindRealm().to(ShiroModuleTest.MockRealm.class);
 
                 addFilterChain("/index.html", AUTHC_BASIC);
-                addFilterChain("/index2.html", config(PERMS, "permission"));
+//                addFilterChain("/index2.html", config(PERMS, "permission"));
+                addFilterChain("/index2.html", filterConfig(PERMS, "permission"));
             }
 
             @Provides

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java
----------------------------------------------------------------------
diff --git a/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java b/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java
index a3a3f76..ff50d0f 100644
--- a/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java
+++ b/support/guice/src/test/java/org/apache/shiro/guice/web/ShiroWebModuleTest.java
@@ -21,6 +21,7 @@ package org.apache.shiro.guice.web;
 import com.google.inject.Guice;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.Key;
 import com.google.inject.Provides;
 import com.google.inject.binder.AnnotatedBindingBuilder;
 import org.apache.shiro.guice.ShiroModuleTest;
@@ -28,21 +29,38 @@ import org.apache.shiro.env.Environment;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.realm.Realm;
 import org.apache.shiro.session.mgt.SessionManager;
+import org.apache.shiro.web.env.EnvironmentLoader;
 import org.apache.shiro.web.env.WebEnvironment;
+import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
+import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
+import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
+import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
 import org.apache.shiro.web.filter.mgt.FilterChainResolver;
 import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
 import org.apache.shiro.web.mgt.WebSecurityManager;
 import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
 import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
+import org.easymock.EasyMock;
+import org.junit.Assume;
 import org.junit.Test;
 
 import javax.inject.Named;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
 import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
 import java.util.Collection;
+import java.util.Iterator;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+import static org.hamcrest.Matchers.*;
 
-import static org.easymock.EasyMock.createMock;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
 public class ShiroWebModuleTest {
 
@@ -146,6 +164,162 @@ public class ShiroWebModuleTest {
         assertTrue( environment == webEnvironment );
     }
 
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void testAddFilterChainGuice3and4() {
+
+        final ShiroModuleTest.MockRealm mockRealm = createMock(ShiroModuleTest.MockRealm.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+
+        servletContext.setAttribute(eq(EnvironmentLoader.ENVIRONMENT_ATTRIBUTE_KEY), EasyMock.anyObject());
+        expect(request.getAttribute("javax.servlet.include.context_path")).andReturn("").anyTimes();
+        expect(request.getCharacterEncoding()).andReturn("UTF-8").anyTimes();
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_authc");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_custom_filter");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_authc_basic");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_perms");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/multiple_configs");
+        replay(servletContext, request);
+
+        Injector injector = Guice.createInjector(new ShiroWebModule(servletContext) {
+            @Override
+            protected void configureShiroWeb() {
+                bindRealm().to(ShiroModuleTest.MockRealm.class);
+                expose(FilterChainResolver.class);
+                this.addFilterChain("/test_authc/**", filterConfig(AUTHC));
+                this.addFilterChain("/test_custom_filter/**", Key.get(CustomFilter.class));
+                this.addFilterChain("/test_authc_basic/**", AUTHC_BASIC);
+                this.addFilterChain("/test_perms/**", filterConfig(PERMS, "remote:invoke:lan,wan"));
+                this.addFilterChain("/multiple_configs/**", filterConfig(AUTHC), filterConfig(ROLES, "b2bClient"), filterConfig(PERMS, "remote:invoke:lan,wan"));
+            }
+
+            @Provides
+            public ShiroModuleTest.MockRealm createRealm() {
+                return mockRealm;
+            }
+        });
+
+        FilterChainResolver resolver = injector.getInstance(FilterChainResolver.class);
+        assertThat(resolver, instanceOf(SimpleFilterChainResolver.class));
+        SimpleFilterChainResolver simpleFilterChainResolver = (SimpleFilterChainResolver) resolver;
+
+        // test the /test_authc resource
+        FilterChain filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        Filter nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(FormAuthenticationFilter.class));
+
+        // test the /test_custom_filter resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(CustomFilter.class));
+
+        // test the /test_authc_basic resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(BasicHttpAuthenticationFilter.class));
+
+        // test the /test_perms resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(PermissionsAuthorizationFilter.class));
+
+        // test the /multiple_configs resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(FormAuthenticationFilter.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(RolesAuthorizationFilter.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(PermissionsAuthorizationFilter.class));
+
+        verify(servletContext, request);
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void testAddFilterChainGuice3Only() {
+
+        Assume.assumeTrue("This test only runs agains Guice 3.x", ShiroWebModule.isGuiceVersion3());
+
+        final ShiroModuleTest.MockRealm mockRealm = createMock(ShiroModuleTest.MockRealm.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+
+        servletContext.setAttribute(eq(EnvironmentLoader.ENVIRONMENT_ATTRIBUTE_KEY), EasyMock.anyObject());
+        expect(request.getAttribute("javax.servlet.include.context_path")).andReturn("").anyTimes();
+        expect(request.getCharacterEncoding()).andReturn("UTF-8").anyTimes();
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_authc");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_custom_filter");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/test_perms");
+        expect(request.getAttribute("javax.servlet.include.request_uri")).andReturn("/multiple_configs");
+        replay(servletContext, request);
+
+        Injector injector = Guice.createInjector(new ShiroWebModule(servletContext) {
+            @Override
+            protected void configureShiroWeb() {
+                bindRealm().to(ShiroModuleTest.MockRealm.class);
+                expose(FilterChainResolver.class);
+                this.addFilterChain("/test_authc/**", AUTHC);
+                this.addFilterChain("/test_custom_filter/**", Key.get(CustomFilter.class));
+                this.addFilterChain("/test_perms/**", config(PERMS, "remote:invoke:lan,wan"));
+                this.addFilterChain("/multiple_configs/**", AUTHC, config(ROLES, "b2bClient"), config(PERMS, "remote:invoke:lan,wan"));
+            }
+
+            @Provides
+            public ShiroModuleTest.MockRealm createRealm() {
+                return mockRealm;
+            }
+        });
+
+        FilterChainResolver resolver = injector.getInstance(FilterChainResolver.class);
+        assertThat(resolver, instanceOf(SimpleFilterChainResolver.class));
+        SimpleFilterChainResolver simpleFilterChainResolver = (SimpleFilterChainResolver) resolver;
+
+        // test the /test_authc resource
+        FilterChain filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        Filter nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(FormAuthenticationFilter.class));
+
+        // test the /test_custom_filter resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(CustomFilter.class));
+
+        // test the /test_perms resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        nextFilter = getNextFilter((SimpleFilterChain) filterChain);
+        assertThat(nextFilter, instanceOf(PermissionsAuthorizationFilter.class));
+
+        // test the /multiple_configs resource
+        filterChain = simpleFilterChainResolver.getChain(request, null, null);
+        assertThat(filterChain, instanceOf(SimpleFilterChain.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(FormAuthenticationFilter.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(RolesAuthorizationFilter.class));
+        assertThat(getNextFilter((SimpleFilterChain) filterChain), instanceOf(PermissionsAuthorizationFilter.class));
+
+        verify(servletContext, request);
+    }
+
+    private Filter getNextFilter(SimpleFilterChain filterChain) {
+
+        Iterator<? extends Filter> filters = filterChain.getFilters();
+        if (filters.hasNext()) {
+            return filters.next();
+        }
+
+        return null;
+    }
+
     public static class MyDefaultWebSecurityManager extends DefaultWebSecurityManager {
         @Inject
         public MyDefaultWebSecurityManager(Collection<Realm> realms) {
@@ -162,4 +336,16 @@ public class ShiroWebModuleTest {
             super(filterChainResolver, servletContext, securityManager);
         }
     }
+
+    public static class CustomFilter implements Filter {
+
+        @Override
+        public void init(FilterConfig filterConfig) throws ServletException {}
+
+        @Override
+        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {}
+
+        @Override
+        public void destroy() {}
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/support/guice/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/support/guice/src/test/resources/log4j.properties b/support/guice/src/test/resources/log4j.properties
new file mode 100644
index 0000000..bbb023d
--- /dev/null
+++ b/support/guice/src/test/resources/log4j.properties
@@ -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.
+#
+
+log4j.rootLogger=TRACE, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m %n
+
+# Pattern to output: date priority [category] - message
+log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
+
+# General Apache libraries is WARN
+log4j.logger.org.apache=WARN
+
+log4j.logger.org.apache.shiro=TRACE
+log4j.logger.org.apache.shiro.util.ThreadContext=WARN
\ No newline at end of file


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

Posted by bd...@apache.org.
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();
+    }
+}


[17/20] shiro git commit: SHIRO-593 - Moved 'defaultBeans' to IniFactorySupport

Posted by bd...@apache.org.
SHIRO-593 - Moved 'defaultBeans' to IniFactorySupport


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

Branch: refs/heads/1.4.x
Commit: 48887a595eb524d3b7fdf7f72472d511615d467c
Parents: f48a8de
Author: Brian Demers <bd...@apache.org>
Authored: Mon Sep 26 21:30:52 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 .../apache/shiro/config/IniFactorySupport.java  | 25 ++++++++++++++++++++
 .../shiro/config/IniSecurityManagerFactory.java |  6 +++++
 .../config/IniFilterChainResolverFactory.java   |  9 ++++---
 3 files changed, 35 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/48887a59/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java b/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
index ad91ee7..959996d 100644
--- a/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
+++ b/core/src/main/java/org/apache/shiro/config/IniFactorySupport.java
@@ -25,6 +25,9 @@ import org.apache.shiro.util.Factory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Base support class for {@link Factory} implementations that generate their instance(s) based on
  * {@link Ini} configuration.
@@ -39,6 +42,8 @@ public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
 
     private Ini ini;
 
+    private Map<String, ?> defaultBeans;
+
     protected IniFactorySupport() {
     }
 
@@ -55,6 +60,26 @@ public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
     }
 
     /**
+     * Returns a mapping of String to bean representing the default set of object used by the factory.
+     * These beans can be used by this factory in conjunction with objects parsed from the INI configuration.
+     * @return A Map of default objects, or <code>null</code>.
+     * @since 1.4
+     */
+    protected Map<String, ?> getDefaults() {
+        return defaultBeans;
+    }
+
+    /**
+     * Sets the default objects used by this factory. These defaults may be used in conjunction with the INI
+     * configuration.
+     * @param defaultBeans String to object mapping used for default configuration in this factory.
+     * @since 1.4
+     */
+    public void setDefaults(Map<String, ?> defaultBeans) {
+        this.defaultBeans = defaultBeans;
+    }
+
+    /**
      * Returns a new Ini instance created from the default {@code classpath:shiro.ini} file, or {@code null} if
      * the file does not exist.
      *

http://git-wip-us.apache.org/repos/asf/shiro/blob/48887a59/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java b/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
index 6a30f0a..6ff6e64 100644
--- a/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
+++ b/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
@@ -159,6 +159,12 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
             }
         }
 
+        // The values from 'getDefaults()' will override the above.
+        Map<String, ?> defaultBeans = getDefaults();
+        if (!CollectionUtils.isEmpty(defaultBeans)) {
+            defaults.putAll(defaultBeans);
+        }
+
         return defaults;
     }
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/48887a59/web/src/main/java/org/apache/shiro/web/config/IniFilterChainResolverFactory.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/shiro/web/config/IniFilterChainResolverFactory.java b/web/src/main/java/org/apache/shiro/web/config/IniFilterChainResolverFactory.java
index ad7e7f0..fb9f822 100644
--- a/web/src/main/java/org/apache/shiro/web/config/IniFilterChainResolverFactory.java
+++ b/web/src/main/java/org/apache/shiro/web/config/IniFilterChainResolverFactory.java
@@ -49,8 +49,6 @@ public class IniFilterChainResolverFactory extends IniFactorySupport<FilterChain
 
     private FilterConfig filterConfig;
 
-    private Map<String, ?> defaultBeans;
-
     public IniFilterChainResolverFactory() {
         super();
     }
@@ -61,7 +59,7 @@ public class IniFilterChainResolverFactory extends IniFactorySupport<FilterChain
 
     public IniFilterChainResolverFactory(Ini ini, Map<String, ?> defaultBeans) {
         this(ini);
-        this.defaultBeans = defaultBeans;
+        this.setDefaults(defaultBeans);
     }
 
     public FilterConfig getFilterConfig() {
@@ -113,8 +111,9 @@ public class IniFilterChainResolverFactory extends IniFactorySupport<FilterChain
         }
         //User-provided objects must come _after_ the default filters - to allow the user-provided
         //ones to override the default filters if necessary.
-        if (!CollectionUtils.isEmpty(this.defaultBeans)) {
-            defaults.putAll(this.defaultBeans);
+        Map<String, ?> defaultBeans = getDefaults();
+        if (!CollectionUtils.isEmpty(defaultBeans)) {
+            defaults.putAll(defaultBeans);
         }
 
         Map<String, Filter> filters = getFilters(section, defaults);


[03/20] shiro git commit: SHIRO-589 - Adding servlet-fragment and sample

Posted by bd...@apache.org.
SHIRO-589 - Adding servlet-fragment and sample

Copied from web sample and adjusted, embedded jetty IT fixed.


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

Branch: refs/heads/1.4.x
Commit: b05a48ff3fa2da3288760a13977f53318f6414a8
Parents: 1915802
Author: Brian Demers <bd...@apache.org>
Authored: Fri Sep 30 09:42:06 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 pom.xml                                         |  32 +++-
 samples/pom.xml                                 |   1 +
 samples/servlet-plugin/pom.xml                  | 128 ++++++++++++++++
 .../src/main/resources/log4j.properties         |  49 +++++++
 .../src/main/webapp/WEB-INF/shiro.ini           |  54 +++++++
 .../src/main/webapp/WEB-INF/web.xml             |  29 ++++
 .../src/main/webapp/account/index.jsp           |  36 +++++
 samples/servlet-plugin/src/main/webapp/home.jsp |  69 +++++++++
 .../servlet-plugin/src/main/webapp/include.jsp  |  22 +++
 .../servlet-plugin/src/main/webapp/index.jsp    |  21 +++
 .../servlet-plugin/src/main/webapp/login.jsp    | 110 ++++++++++++++
 .../servlet-plugin/src/main/webapp/style.css    |  47 ++++++
 .../apache/shiro/test/AbstractContainerIT.java  | 145 +++++++++++++++++++
 .../shiro/test/ContainerIntegrationIT.java      |  57 ++++++++
 support/pom.xml                                 |   1 +
 support/servlet-plugin/pom.xml                  |  65 +++++++++
 .../main/resources/META-INF/web-fragment.xml    |  42 ++++++
 17 files changed, 907 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 02f837a..1a3d9d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -399,11 +399,36 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
-                <version>2.12</version>
+                <version>2.19.1</version>
                 <configuration>
                     <printSummary>true</printSummary>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>2.19.1</version>
+                <configuration>
+                    <includes>
+                        <include>**/*IT.java</include>
+                        <include>**/*IT.groovy</include>
+                        <include>**/*ITCase.java</include>
+                        <include>**/*ITCase.groovy</include>
+                    </includes>
+                    <excludes>
+                        <exclude>**/*ManualIT.java</exclude>
+                        <exclude>**/*ManualIT.groovy</exclude>
+                    </excludes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
                 <plugin>
                     <groupId>org.jacoco</groupId>
                     <artifactId>jacoco-maven-plugin</artifactId>
@@ -558,6 +583,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-servlet-plugin</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-ehcache</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index c48092a..29c5369 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -42,6 +42,7 @@
         <module>spring-boot-web</module>
         <module>guice</module>
         <module>quickstart-guice</module>
+        <module>servlet-plugin</module>
     </modules>
 
     <reporting>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/pom.xml b/samples/servlet-plugin/pom.xml
new file mode 100644
index 0000000..b969768
--- /dev/null
+++ b/samples/servlet-plugin/pom.xml
@@ -0,0 +1,128 @@
+<?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">
+
+    <parent>
+        <groupId>org.apache.shiro.samples</groupId>
+        <artifactId>shiro-samples</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>samples-servlet-plugin</artifactId>
+    <name>Apache Shiro :: Samples :: Servlet Plugin</name>
+    <packaging>war</packaging>
+
+    <properties>
+        <jetty.version>9.3.0.M1</jetty.version>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkMode>never</forkMode>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <configuration>
+                    <contextPath>/</contextPath>
+                    <httpConnector>
+                        <port>9080</port>
+                        <idleTimeout>60000</idleTimeout>
+                    </httpConnector>
+                    <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+                        <filename>./target/yyyy_mm_dd.request.log</filename>
+                        <retainDays>90</retainDays>
+                        <append>true</append>
+                        <extended>false</extended>
+                        <logTimeZone>GMT</logTimeZone>
+                    </requestLog>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-servlet-plugin</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jstl</artifactId>
+            <version>1.2</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/resources/log4j.properties b/samples/servlet-plugin/src/main/resources/log4j.properties
new file mode 100644
index 0000000..51c6848
--- /dev/null
+++ b/samples/servlet-plugin/src/main/resources/log4j.properties
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+# This file is used to format all logging output
+log4j.rootLogger=INFO, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c]: %m%n
+
+# =============================================================================
+# 3rd Party Libraries
+# OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL
+# =============================================================================
+# ehcache caching manager:
+log4j.logger.net.sf.ehcache=WARN
+
+# Most all Apache libs:
+log4j.logger.org.apache=WARN
+
+# Quartz Enterprise Scheular (java 'cron' utility)
+log4j.logger.org.quartz=WARN
+
+# =============================================================================
+# Apache Shiro
+# =============================================================================
+# Shiro security framework
+log4j.logger.org.apache.shiro=TRACE
+#log4j.logger.org.apache.shiro.realm.text.PropertiesRealm=INFO
+#log4j.logger.org.apache.shiro.cache.ehcache.EhCache=INFO
+#log4j.logger.org.apache.shiro.io=INFO
+#log4j.logger.org.apache.shiro.web.servlet=INFO
+log4j.logger.org.apache.shiro.util.ThreadContext=INFO

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/WEB-INF/shiro.ini
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/WEB-INF/shiro.ini b/samples/servlet-plugin/src/main/webapp/WEB-INF/shiro.ini
new file mode 100644
index 0000000..33c7586
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/WEB-INF/shiro.ini
@@ -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.
+
+# INI configuration is very powerful and flexible, while still remaining succinct.
+# Please http://shiro.apache.org/configuration.html and
+# http://shiro.apache.org/web.html for more.
+
+[main]
+listener = org.apache.shiro.config.event.LoggingBeanEventListener
+
+shiro.loginUrl = /login.jsp
+
+# We need to set the cipherKey, if you want the rememberMe cookie to work after restarting or on multiple nodes.
+# YOU MUST SET THIS TO A UNIQUE STRING
+#securityManager.rememberMeManager.cipherKey = kPH+bIxk5D2deZiIxcaaaA==
+
+[users]
+# format: username = password, role1, role2, ..., roleN
+root = secret,admin
+guest = guest,guest
+presidentskroob = 12345,president
+darkhelmet = ludicrousspeed,darklord,schwartz
+lonestarr = vespa,goodguy,schwartz
+
+[roles]
+# format: roleName = permission1, permission2, ..., permissionN
+admin = *
+schwartz = lightsaber:*
+goodguy = winnebago:drive:eagle5
+
+[urls]
+# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
+# the 'authc' filter must still be specified for it so it can process that url's
+# login submissions. It is 'smart' enough to allow those requests through as specified by the
+# shiro.loginUrl above.
+/login.jsp = authc
+/logout = logout
+/account/** = authc
+/remoting/** = authc, roles[b2bClient], perms["remote:invoke:lan,wan"]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/WEB-INF/web.xml b/samples/servlet-plugin/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..368fd60
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?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.
+  -->
+<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
+         version="3.1">
+
+    <welcome-file-list>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/account/index.jsp
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/account/index.jsp b/samples/servlet-plugin/src/main/webapp/account/index.jsp
new file mode 100644
index 0000000..4f6c9d8
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/account/index.jsp
@@ -0,0 +1,36 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="../include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Users only</h2>
+
+<p>You are currently logged in.</p>
+
+<p><a href="<c:url value="/home.jsp"/>">Return to the home page.</a></p>
+
+<p><a href="<c:url value="/logout"/>">Log out.</a></p>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/home.jsp
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/home.jsp b/samples/servlet-plugin/src/main/webapp/home.jsp
new file mode 100644
index 0000000..61dee25
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/home.jsp
@@ -0,0 +1,69 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+    <title>Apache Shiro Quickstart</title>
+</head>
+<body>
+
+<h1>Apache Shiro Quickstart</h1>
+
+<p>Hi <shiro:guest>Guest</shiro:guest><shiro:user><shiro:principal/></shiro:user>!
+    ( <shiro:user><a href="<c:url value="/logout"/>">Log out</a></shiro:user>
+    <shiro:guest><a href="<c:url value="/login.jsp"/>">Log in</a> (sample accounts provided)</shiro:guest> )
+</p>
+
+<p>Welcome to the Apache Shiro Quickstart sample application.
+    This page represents the home page of any web application.</p>
+
+<shiro:user><p>Visit your <a href="<c:url value="/account"/>">account page</a>.</p></shiro:user>
+<shiro:guest><p>If you want to access the user-only <a href="<c:url value="/account"/>">account page</a>,
+    you will need to log-in first.</p></shiro:guest>
+
+<h2>Roles</h2>
+
+<p>To show some taglibs, here are the roles you have and don't have. Log out and log back in under different user
+    accounts to see different roles.</p>
+
+<h3>Roles you have</h3>
+
+<p>
+    <shiro:hasRole name="admin">admin<br/></shiro:hasRole>
+    <shiro:hasRole name="president">president<br/></shiro:hasRole>
+    <shiro:hasRole name="darklord">darklord<br/></shiro:hasRole>
+    <shiro:hasRole name="goodguy">goodguy<br/></shiro:hasRole>
+    <shiro:hasRole name="schwartz">schwartz<br/></shiro:hasRole>
+</p>
+
+<h3>Roles you DON'T have</h3>
+
+<p>
+    <shiro:lacksRole name="admin">admin<br/></shiro:lacksRole>
+    <shiro:lacksRole name="president">president<br/></shiro:lacksRole>
+    <shiro:lacksRole name="darklord">darklord<br/></shiro:lacksRole>
+    <shiro:lacksRole name="goodguy">goodguy<br/></shiro:lacksRole>
+    <shiro:lacksRole name="schwartz">schwartz<br/></shiro:lacksRole>
+</p>
+
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/include.jsp
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/include.jsp b/samples/servlet-plugin/src/main/webapp/include.jsp
new file mode 100644
index 0000000..fddd239
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/include.jsp
@@ -0,0 +1,22 @@
+<%--
+  ~ 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.
+  --%>
+<%@ page import="org.apache.shiro.SecurityUtils" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/index.jsp b/samples/servlet-plugin/src/main/webapp/index.jsp
new file mode 100644
index 0000000..9dedd19
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/index.jsp
@@ -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.
+  --%>
+
+<%-- Forward the user to the home page --%>
+<jsp:forward page="home.jsp"/>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/login.jsp
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/login.jsp b/samples/servlet-plugin/src/main/webapp/login.jsp
new file mode 100644
index 0000000..c80ee54
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/login.jsp
@@ -0,0 +1,110 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Please Log in</h2>
+
+<shiro:guest>
+    <p>Here are a few sample accounts to play with in the default text-based Realm (used for this
+        demo and test installs only). Do you remember the movie these names came from? ;)</p>
+
+
+    <style type="text/css">
+        table.sample {
+            border-width: 1px;
+            border-style: outset;
+            border-color: blue;
+            border-collapse: separate;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample th {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample td {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+    </style>
+
+
+    <table class="sample">
+        <thead>
+        <tr>
+            <th>Username</th>
+            <th>Password</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr>
+            <td>root</td>
+            <td>secret</td>
+        </tr>
+        <tr>
+            <td>presidentskroob</td>
+            <td>12345</td>
+        </tr>
+        <tr>
+            <td>darkhelmet</td>
+            <td>ludicrousspeed</td>
+        </tr>
+        <tr>
+            <td>lonestarr</td>
+            <td>vespa</td>
+        </tr>
+        </tbody>
+    </table>
+    <br/><br/>
+</shiro:guest>
+
+<form name="loginform" action="" method="post">
+    <table align="left" border="0" cellspacing="0" cellpadding="3">
+        <tr>
+            <td>Username:</td>
+            <td><input type="text" name="username" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td>Password:</td>
+            <td><input type="password" name="password" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="left"><input type="checkbox" name="rememberMe"><font size="2">Remember Me</font></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td>
+        </tr>
+    </table>
+</form>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/main/webapp/style.css
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/main/webapp/style.css b/samples/servlet-plugin/src/main/webapp/style.css
new file mode 100644
index 0000000..1308e3f
--- /dev/null
+++ b/samples/servlet-plugin/src/main/webapp/style.css
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+body {
+    margin: 15px 0 0 15px;
+    padding: 1px; /*background: #2370cf;*/
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+table, td {
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+h1 {
+    font: 24px;
+}
+
+img {
+    border: thin black solid;
+}
+
+#contentBox {
+    text-align: center;
+    width: 50%;
+    margin: auto;
+    margin-top: 50px;
+    color: black;
+    background: #eee;
+    border: thick black solid;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
new file mode 100644
index 0000000..f5b44f7
--- /dev/null
+++ b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
@@ -0,0 +1,145 @@
+/*
+ * 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.test;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+
+public abstract class AbstractContainerIT {
+
+    private static EmbeddedJetty jetty;
+
+    private static int port = 0;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        String warDir = warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(warDir)
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+        port = jetty.getPort();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + port + "/";
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/samples/servlet-plugin/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
new file mode 100644
index 0000000..4cef226
--- /dev/null
+++ b/samples/servlet-plugin/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.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.test;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index b30b471..9f12c69 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -41,6 +41,7 @@
         <module>features</module>
         <module>cas</module>
         <module>spring-boot</module>
+        <module>servlet-plugin</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/support/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/support/servlet-plugin/pom.xml b/support/servlet-plugin/pom.xml
new file mode 100644
index 0000000..4087cce
--- /dev/null
+++ b/support/servlet-plugin/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2012 Stormpath, Inc.
+  ~
+  ~ Licensed 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-support</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>shiro-servlet-plugin</artifactId>
+    <name>Apache Shiro :: Support :: Servlet Plugin</name>
+    <description>
+        Automatically deploys Shiro in a servlet container-based web application.
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>xml-maven-plugin</artifactId>
+                <version>1.0.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>validate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <validationSets>
+                        <validationSet>
+                            <dir>src/main/resources/META-INF/</dir>
+                        </validationSet>
+                    </validationSets>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/b05a48ff/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml b/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
new file mode 100644
index 0000000..dd478c3
--- /dev/null
+++ b/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~
+  ~ Licensed 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.
+  -->
+<web-fragment metadata-complete="true"
+              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd"
+              version="3.1">
+
+    <name>ApacheShiro</name>
+
+    <listener>
+        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>ShiroFilter</filter-name>
+        <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>ShiroFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+        <dispatcher>FORWARD</dispatcher>
+        <dispatcher>INCLUDE</dispatcher>
+        <dispatcher>ERROR</dispatcher>
+    </filter-mapping>
+
+</web-fragment>
\ No newline at end of file


[10/20] shiro git commit: SHIRO-593 - Added getFrameworkIni() method to IniWebEnvironment

Posted by bd...@apache.org.
SHIRO-593 - Added getFrameworkIni() method to IniWebEnvironment

Which will allow downstream integrations to provide default configuration that will be
merged with the existing configuration.  Default functionality is unchanged.


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

Branch: refs/heads/1.4.x
Commit: 808cb1f12077cb85c6359e2440b383945b054a60
Parents: 48887a5
Author: Brian Demers <bd...@apache.org>
Authored: Fri Sep 30 16:40:56 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 .../main/java/org/apache/shiro/config/Ini.java  |  51 ++++++++++
 .../java/org/apache/shiro/config/IniTest.java   | 102 +++++++++++++++++++
 .../apache/shiro/web/env/IniWebEnvironment.java |  84 ++++++++++++++-
 .../shiro/web/env/IniWebEnvironmentTest.groovy  |  56 +++++++++-
 4 files changed, 284 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/808cb1f1/core/src/main/java/org/apache/shiro/config/Ini.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/Ini.java b/core/src/main/java/org/apache/shiro/config/Ini.java
index a71bc20..46bdce4 100644
--- a/core/src/main/java/org/apache/shiro/config/Ini.java
+++ b/core/src/main/java/org/apache/shiro/config/Ini.java
@@ -303,6 +303,57 @@ public class Ini implements Map<String, Ini.Section> {
         }
     }
 
+    /**
+     * Merges the contents of <code>m</code>'s {@link Section} objects into self.
+     * This differs from {@link Ini#putAll(Map)}, in that each section is merged with the existing one.
+     * For example the following two ini blocks are merged and the result is the third<BR/>
+     * <p>
+     * Initial:
+     * <pre>
+     * <code>[section1]
+     * key1 = value1
+     *
+     * [section2]
+     * key2 = value2
+     * </code> </pre>
+     *
+     * To be merged:
+     * <pre>
+     * <code>[section1]
+     * foo = bar
+     *
+     * [section2]
+     * key2 = new value
+     * </code> </pre>
+     *
+     * Result:
+     * <pre>
+     * <code>[section1]
+     * key1 = value1
+     * foo = bar
+     *
+     * [section2]
+     * key2 = new value
+     * </code> </pre>
+     *
+     * </p>
+     *
+     * @param m map to be merged
+     * @since 1.4
+     */
+    public void merge(Map<String, Section> m) {
+
+        if (m != null) {
+            for (Entry<String, Section> entry : m.entrySet()) {
+                Section section = this.getSection(entry.getKey());
+                if (section == null) {
+                    section = addSection(entry.getKey());
+                }
+                section.putAll(entry.getValue());
+            }
+        }
+    }
+
     private void addSection(String name, StringBuilder content) {
         if (content.length() > 0) {
             String contentString = content.toString();

http://git-wip-us.apache.org/repos/asf/shiro/blob/808cb1f1/core/src/test/java/org/apache/shiro/config/IniTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/shiro/config/IniTest.java b/core/src/test/java/org/apache/shiro/config/IniTest.java
index 36fd17c..5d07bc0 100644
--- a/core/src/test/java/org/apache/shiro/config/IniTest.java
+++ b/core/src/test/java/org/apache/shiro/config/IniTest.java
@@ -23,6 +23,8 @@ import org.junit.Test;
 
 import java.util.Scanner;
 
+import static org.hamcrest.Matchers.*;
+
 /**
  * Unit test for the {@link Ini} class.
  *
@@ -160,4 +162,104 @@ public class IniTest {
         assertEquals("value 4", section.get("prop4"));
         assertEquals("some long value", section.get("prop5"));
     }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void testPutAll() {
+
+        Ini ini1 = new Ini();
+        ini1.setSectionProperty("section1", "key1", "value1");
+
+        Ini ini2 = new Ini();
+        ini2.setSectionProperty("section2", "key2", "value2");
+
+        ini1.putAll(ini2);
+
+        assertThat(ini1.getSectionNames(), allOf(
+                hasItem("section1"),
+                hasItem("section2")
+        ));
+
+        // two sections each with one property
+        assertThat(ini1.getSectionNames(), hasSize(2));
+        assertThat(ini1.getSection("section2"), aMapWithSize(1));
+        assertThat(ini1.getSection("section1"), aMapWithSize(1));
+
+        // adding a value directly to ini2's section will update ini1
+        ini2.setSectionProperty("section2", "key2.2", "value2.2");
+        assertThat(ini1.getSection("section2"), aMapWithSize(2));
+
+        Ini ini3 = new Ini();
+        ini3.setSectionProperty("section1", "key1.3", "value1.3");
+
+        // this will replace the whole section
+        ini1.putAll(ini3);
+        assertThat(ini1.getSection("section1"), aMapWithSize(1));
+
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void testMerge() {
+
+        Ini ini1 = new Ini();
+        ini1.setSectionProperty("section1", "key1", "value1");
+
+        Ini ini2 = new Ini();
+        ini2.setSectionProperty("section2", "key2", "value2");
+
+        ini1.merge(ini2);
+
+        assertThat(ini1.getSectionNames(), allOf(
+                hasItem("section1"),
+                hasItem("section2")
+        ));
+
+        // two sections each with one property
+        assertThat(ini1.getSectionNames(), hasSize(2));
+        assertThat(ini1.getSection("section2"), aMapWithSize(1));
+        assertThat(ini1.getSection("section1"), aMapWithSize(1));
+
+        // updating the original ini2, will NOT effect ini1
+        ini2.setSectionProperty("section2", "key2.2", "value2.2");
+        assertThat(ini1.getSection("section2"), aMapWithSize(1));
+
+        Ini ini3 = new Ini();
+        ini3.setSectionProperty("section1", "key1.3", "value1.3");
+
+        // after merging the section will contain 2 values
+        ini1.merge(ini3);
+        assertThat(ini1.getSection("section1"), aMapWithSize(2));
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void testCreateWithDefaults() {
+
+        Ini ini1 = new Ini();
+        ini1.setSectionProperty("section1", "key1", "value1");
+
+        Ini ini2 = new Ini(ini1);
+        ini2.setSectionProperty("section2", "key2", "value2");
+
+        assertThat(ini2.getSectionNames(), allOf(
+                hasItem("section1"),
+                hasItem("section2")
+        ));
+
+        // two sections each with one property
+        assertThat(ini2.getSectionNames(), hasSize(2));
+        assertThat(ini2.getSection("section2"), aMapWithSize(1));
+        assertThat(ini2.getSection("section1"), aMapWithSize(1));
+
+        // updating the original ini1, will NOT effect ini2
+        ini1.setSectionProperty("section1", "key1.1", "value1.1");
+        assertThat(ini2.getSection("section1"), allOf(aMapWithSize(1), hasEntry("key1", "value1")));
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/808cb1f1/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
index afb15ba..f07406a 100644
--- a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
+++ b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
@@ -60,6 +60,20 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
      * configuration and calling {@link #configure() configure} for actual instance configuration.
      */
     public void init() {
+
+        setIni(parseConfig());
+
+        configure();
+    }
+
+    /**
+     * Loads configuration {@link Ini} from {@link #getConfigLocations()} if set, otherwise falling back
+     * to the {@link #getDefaultConfigLocations()}. Finally any Ini objects will be merged with the value returned
+     * from {@link #getFrameworkIni()}
+     * @return Ini configuration to be used by this Environment.
+     * @since 1.4
+     */
+    protected Ini parseConfig() {
         Ini ini = getIni();
 
         String[] configLocations = getConfigLocations();
@@ -82,14 +96,15 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
             ini = getDefaultIni();
         }
 
+        // Allow for integrations to provide default that will be merged other configuration.
+        // to retain backwards compatibility this must be a different method then 'getDefaultIni()'
+        ini = mergeIni(getFrameworkIni(), ini);
+
         if (CollectionUtils.isEmpty(ini)) {
             String msg = "Shiro INI configuration was either not found or discovered to be empty/unconfigured.";
             throw new ConfigurationException(msg);
         }
-
-        setIni(ini);
-
-        configure();
+        return ini;
     }
 
     protected void configure() {
@@ -105,6 +120,50 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
         }
     }
 
+    /**
+     * Extension point to allow subclasses to provide an {@link Ini} configuration that will be merged into the
+     * users configuration.  The users configuration will override anything set here.
+     * <p>
+     * <strong>NOTE:</strong> Framework developers should use with caution. It is possible a user could provide
+     * configuration that would conflict with the frameworks configuration.  For example: if this method returns an
+     * Ini object with the following configuration:
+     * <pre><code>
+     *     [main]
+     *     realm = com.myco.FoobarRealm
+     *     realm.foobarSpecificField = A string
+     * </code></pre>
+     * And the user provides a similar configuration:
+     * <pre><code>
+     *     [main]
+     *     realm = net.differentco.MyCustomRealm
+     * </code></pre>
+     *
+     * This would merge into:
+     * <pre><code>
+     *     [main]
+     *     realm = net.differentco.MyCustomRealm
+     *     realm.foobarSpecificField = A string
+     * </code></pre>
+     *
+     * This may cause a configuration error if <code>MyCustomRealm</code> does not contain the field <code>foobarSpecificField</code>.
+     * This can be avoided if the Framework Ini uses more unique names, such as <code>foobarRealm</code>. which would result
+     * in a merged configuration that looks like:
+     * <pre><code>
+     *     [main]
+     *     foobarRealm = com.myco.FoobarRealm
+     *     foobarRealm.foobarSpecificField = A string
+     *     realm = net.differentco.MyCustomRealm
+     * </code></pre>
+     *
+     * </p>
+     *
+     * @return Ini configuration used by the framework integrations.
+     * @since 1.4
+     */
+    protected Ini getFrameworkIni() {
+        return null;
+    }
+
     protected Ini getSpecifiedIni(String[] configLocations) throws ConfigurationException {
 
         Ini ini = null;
@@ -124,6 +183,23 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
         return ini;
     }
 
+    protected Ini mergeIni(Ini ini1, Ini ini2) {
+
+        if (ini1 == null) {
+            return ini2;
+        }
+
+        if (ini2 == null) {
+            return ini1;
+        }
+
+        // at this point we have two valid ini objects, create a new one and merge the contents of 2 into 1
+        Ini iniResult = new Ini(ini1);
+        iniResult.merge(ini2);
+
+        return iniResult;
+    }
+
     protected Ini getDefaultIni() {
 
         Ini ini = null;

http://git-wip-us.apache.org/repos/asf/shiro/blob/808cb1f1/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
----------------------------------------------------------------------
diff --git a/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy b/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
index 08b2bc0..84b698d 100644
--- a/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
+++ b/web/src/test/groovy/org/apache/shiro/web/env/IniWebEnvironmentTest.groovy
@@ -18,18 +18,25 @@
  */
 package org.apache.shiro.web.env
 
+import org.apache.shiro.config.CompositeBean
 import org.apache.shiro.config.Ini
+import org.apache.shiro.config.SimpleBean
 import org.apache.shiro.web.filter.mgt.DefaultFilter
+import org.junit.Test
+
+import static org.junit.Assert.*
 
 /**
  * Unit tests for the {@link IniWebEnvironment} implementation.
- * 
+ *
  * @since 1.2
  */
-class IniWebEnvironmentTest extends GroovyTestCase {
-    
-    
-    //asserts SHIRO-306
+class IniWebEnvironmentTest {
+
+    /**
+     * asserts SHIRO-306
+     */
+    @Test
     void testObjectsAfterSecurityManagerCreation() {
         
         def ini = new Ini()
@@ -48,4 +55,43 @@ class IniWebEnvironmentTest extends GroovyTestCase {
         assertNotNull env.objects['securityManager']
         assertNotNull env.objects['compositeBean']
     }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    void testFrameworkConfigAdded() {
+
+        def ini = new Ini()
+        ini.load("""
+        [main]
+        compositeBean = org.apache.shiro.config.CompositeBean
+        compositeBean.simpleBean = \$simpleBean
+        """)
+
+        def env = new IniWebEnvironment() {
+            @Override
+            protected Ini getFrameworkIni() {
+                def frameworkIni = new Ini()
+                frameworkIni.setSectionProperty("main", "simpleBean", "org.apache.shiro.config.SimpleBean")
+                return frameworkIni;
+            }
+        }
+        env.ini = ini
+        env.init()
+
+        assertNotNull env.objects
+        //asserts that the objects size = securityManager (1) + the event bus (1) + filterChainResolverFactory (1) + num custom objects + num default filters
+        def expectedSize = 5 + DefaultFilter.values().length
+        assertEquals expectedSize, env.objects.size()
+        assertNotNull env.objects['securityManager']
+
+        def compositeBean = (CompositeBean) env.objects['compositeBean']
+        def simpleBean = (SimpleBean) env.objects['simpleBean']
+
+        assertNotNull compositeBean
+        assertNotNull simpleBean
+
+        assertSame(compositeBean.simpleBean, simpleBean)
+    }
 }


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

Posted by bd...@apache.org.
http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/java/org/apache/shiro/spring/config/OptionalComponentsTestConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/test/java/org/apache/shiro/spring/config/OptionalComponentsTestConfiguration.java b/support/spring/src/test/java/org/apache/shiro/spring/config/OptionalComponentsTestConfiguration.java
new file mode 100644
index 0000000..2f71751
--- /dev/null
+++ b/support/spring/src/test/java/org/apache/shiro/spring/config/OptionalComponentsTestConfiguration.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;
+
+import org.apache.shiro.authz.Permission;
+import org.apache.shiro.authz.permission.PermissionResolver;
+import org.apache.shiro.authz.permission.RolePermissionResolver;
+import org.apache.shiro.authz.permission.WildcardPermission;
+import org.apache.shiro.authz.permission.WildcardPermissionResolver;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.cache.MemoryConstrainedCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Collection;
+import java.util.Collections;
+
+@Configuration
+public class OptionalComponentsTestConfiguration {
+
+    @Bean
+    CacheManager cacheManager() {
+        return new MemoryConstrainedCacheManager();
+    }
+
+    @Bean
+    RolePermissionResolver rolePermissionResolver() {
+        return new RolePermissionResolver() {
+            @Override
+            public Collection<Permission> resolvePermissionsInRole(String roleString) {
+                return Collections.emptySet();
+            }
+        };
+    }
+
+    @Bean
+    PermissionResolver permissionResolver() {
+        // this permission always resolves to false
+        return new WildcardPermissionResolver();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/java/org/apache/shiro/spring/config/RealmTestConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/test/java/org/apache/shiro/spring/config/RealmTestConfiguration.java b/support/spring/src/test/java/org/apache/shiro/spring/config/RealmTestConfiguration.java
new file mode 100644
index 0000000..55d7164
--- /dev/null
+++ b/support/spring/src/test/java/org/apache/shiro/spring/config/RealmTestConfiguration.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.TextConfigurationRealm;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+@Configuration
+public class RealmTestConfiguration {
+
+    @Bean
+//    @DependsOn("lifecycleBeanPostProcessor")
+    @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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/support/spring/src/test/java/org/apache/shiro/spring/web/config/CacheManagerConfiguration.java
----------------------------------------------------------------------
diff --git a/support/spring/src/test/java/org/apache/shiro/spring/web/config/CacheManagerConfiguration.java b/support/spring/src/test/java/org/apache/shiro/spring/web/config/CacheManagerConfiguration.java
new file mode 100644
index 0000000..afaf00b
--- /dev/null
+++ b/support/spring/src/test/java/org/apache/shiro/spring/web/config/CacheManagerConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * 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.web.config;
+
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.cache.MemoryConstrainedCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class CacheManagerConfiguration {
+
+    @Bean
+    CacheManager getCacheManager() {
+        return new MemoryConstrainedCacheManager();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/cd3dde8a/test-coverage/pom.xml
----------------------------------------------------------------------
diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml
new file mode 100644
index 0000000..f088f32
--- /dev/null
+++ b/test-coverage/pom.xml
@@ -0,0 +1,97 @@
+<?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-test-coverage</artifactId>
+    <name>Apache Shiro :: Test Coverage</name>
+    <packaging>pom</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-aspectj</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-cas</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-ehcache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-guice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring-boot-web-starter</artifactId>
+        </dependency>
+    </dependencies>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <reportSets>
+                    <reportSet>
+                        <id>aggregate-jacoco</id>
+                        <reports>
+                            <report>report</report>
+                            <report>report-integration</report>
+                            <report>report-aggregate</report>
+                        </reports>
+                    </reportSet>
+                </reportSets>
+            </plugin>
+        </plugins>
+    </reporting>
+
+</project>
+


[18/20] shiro git commit: Cleaning up jetty dependencies in tests

Posted by bd...@apache.org.
Cleaning up jetty dependencies in tests

Removing org.mortbay, while it would be nice to run tests against older versions, the maven plugin doesn't stop the container consistently


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

Branch: refs/heads/1.4.x
Commit: db46b11c4649bbbac7b4f35256ae5c5f9d0ab792
Parents: a76b1ee
Author: Brian Demers <bd...@apache.org>
Authored: Mon Oct 10 14:50:20 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 pom.xml                                         |   5 +-
 samples/guice/pom.xml                           |  89 ++++++------
 .../samples/guice/AbstractContainerIT.java      | 142 ++++++++++++++++++
 .../samples/guice/AbstractContainerTest.java    |  89 ------------
 .../samples/guice/ContainerIntegrationIT.java   |  79 ++++++++++
 .../samples/guice/ContainerIntegrationTest.java |  79 ----------
 samples/servlet-plugin/pom.xml                  |   5 -
 samples/web/pom.xml                             | 142 ++++++------------
 .../apache/shiro/test/AbstractContainerIT.java  | 145 +++++++++++++++++++
 .../shiro/test/ContainerIntegrationIT.java      |   7 +-
 10 files changed, 460 insertions(+), 322 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 69da491..8706e6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,7 +85,7 @@
         <hazelcast.version>2.4.1</hazelcast.version>
         <hsqldb.version>1.8.0.7</hsqldb.version>
         <jdk.version>1.6</jdk.version>
-        <jetty.version>6.1.26</jetty.version>
+        <jetty.version>9.3.0.M1</jetty.version>
         <!-- Don't change this version without also changing the shiro-quartz and shiro-features
              modules' OSGi metadata: -->
         <quartz.version>1.6.1</quartz.version>
@@ -540,6 +540,7 @@
             <groupId>org.hamcrest</groupId>
             <artifactId>java-hamcrest</artifactId>
             <version>2.0.0.0</version>
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.easymock</groupId>
@@ -742,7 +743,7 @@
             <dependency>
                 <groupId>javax.servlet</groupId>
                 <artifactId>jstl</artifactId>
-                <version>1.1.2</version>
+                <version>1.2</version>
                 <scope>provided</scope>
             </dependency>
             <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/guice/pom.xml
----------------------------------------------------------------------
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index ff6b52c..ce9d56c 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -38,27 +38,25 @@
 	                <forkMode>never</forkMode>
 	            </configuration>
 	        </plugin>
-	        <plugin>
-	            <groupId>org.mortbay.jetty</groupId>
-	            <artifactId>maven-jetty-plugin</artifactId>
-	            <version>${jetty.version}</version>
-	            <configuration>
-	                <contextPath>/</contextPath>
-	                <connectors>
-	                    <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-	                        <port>9080</port>
-	                        <maxIdleTime>60000</maxIdleTime>
-	                    </connector>
-	                </connectors>
-	                <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
-	                    <filename>./target/yyyy_mm_dd.request.log</filename>
-	                    <retainDays>90</retainDays>
-	                    <append>true</append>
-	                    <extended>false</extended>
-	                    <logTimeZone>GMT</logTimeZone>
-	                </requestLog>
-	            </configuration>
-	        </plugin>
+			<plugin>
+				<groupId>org.eclipse.jetty</groupId>
+				<artifactId>jetty-maven-plugin</artifactId>
+				<version>${jetty.version}</version>
+				<configuration>
+					<contextPath>/</contextPath>
+					<httpConnector>
+						<port>9080</port>
+						<idleTimeout>60000</idleTimeout>
+					</httpConnector>
+					<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+						<filename>./target/yyyy_mm_dd.request.log</filename>
+						<retainDays>90</retainDays>
+						<append>true</append>
+						<extended>false</extended>
+						<logTimeZone>GMT</logTimeZone>
+					</requestLog>
+				</configuration>
+			</plugin>
 	    </plugins>
 	</build>
 
@@ -66,6 +64,7 @@
 	    <dependency>
 	        <groupId>javax.servlet</groupId>
 	        <artifactId>jstl</artifactId>
+			<scope>compile</scope>
 	    </dependency>
 	    <dependency>
 	        <groupId>javax.servlet</groupId>
@@ -83,12 +82,6 @@
 	        <scope>runtime</scope>
 	    </dependency>
 	    <dependency>
-	        <groupId>net.sourceforge.htmlunit</groupId>
-	        <artifactId>htmlunit</artifactId>
-	        <version>2.6</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
 	        <groupId>org.apache.shiro</groupId>
 	        <artifactId>shiro-core</artifactId>
 	    </dependency>
@@ -105,26 +98,36 @@
 			<artifactId>guice-servlet</artifactId>
 		</dependency>
 	    <dependency>
-	        <groupId>org.mortbay.jetty</groupId>
-	        <artifactId>jetty</artifactId>
-	        <version>${jetty.version}</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
-	        <groupId>org.mortbay.jetty</groupId>
-	        <artifactId>jsp-2.1-jetty</artifactId>
-	        <version>${jetty.version}</version>
-	        <scope>test</scope>
-	    </dependency>
-	    <dependency>
-	        <groupId>taglibs</groupId>
-	        <artifactId>standard</artifactId>
-	    </dependency>
-	    <dependency>
 	        <groupId>org.slf4j</groupId>
 	        <artifactId>jcl-over-slf4j</artifactId>
 	        <scope>runtime</scope>
 	    </dependency>
+
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
+        </dependency>
 	</dependencies>
 
 </project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
new file mode 100644
index 0000000..dcd47e1
--- /dev/null
+++ b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
@@ -0,0 +1,142 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    protected static EmbeddedJetty jetty;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + jetty.getPort() + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
deleted file mode 100644
index 0806fcc..0000000
--- a/samples/guice/src/test/java/org/apache/shiro/samples/guice/AbstractContainerTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.samples.guice;
-
-import com.gargoylesoftware.htmlunit.WebClient;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-import java.net.BindException;
-
-import static org.junit.Assert.assertTrue;
-
-public abstract class AbstractContainerTest {
-    public static final int MAX_PORT = 9200;
-
-    protected static PauseableServer server;
-
-    private static int port = 9180;
-
-    protected final WebClient webClient = new WebClient();
-
-    @BeforeClass
-    public static void startContainer() throws Exception {
-        while (server == null && port < MAX_PORT) {
-            try {
-                server = createAndStartServer(port);
-            } catch (BindException e) {
-                System.err.printf("Unable to listen on port %d.  Trying next port.", port);
-                port++;
-            }
-        }
-        assertTrue(server.isStarted());
-    }
-
-    private static PauseableServer createAndStartServer(final int port) throws Exception {
-        PauseableServer server = new PauseableServer();
-        Connector connector = new SelectChannelConnector();
-        connector.setPort(port);
-        server.setConnectors(new Connector[]{connector});
-        server.setHandler(new WebAppContext("src/main/webapp", "/"));
-        server.start();
-        return server;
-    }
-
-    protected static String getBaseUri() {
-        return "http://localhost:" + port + "/";
-    }
-
-    @Before
-    public void beforeTest() {
-        webClient.setThrowExceptionOnFailingStatusCode(true);
-    }
-
-    public void pauseServer(boolean paused) {
-        if (server != null) server.pause(paused);
-    }
-
-    public static class PauseableServer extends Server {
-        public synchronized void pause(boolean paused) {
-            try {
-                if (paused) for (Connector connector : getConnectors())
-                    connector.stop();
-                else for (Connector connector : getConnectors())
-                    connector.start();
-            } catch (Exception e) {
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
new file mode 100644
index 0000000..4ebc6c7
--- /dev/null
+++ b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
@@ -0,0 +1,79 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.WebAssert;
+import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+
+    @Test
+    public void logInAndRememberMe() throws Exception {
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
+        checkbox.setChecked(true);
+        page = form.<HtmlInput>getInputByName("submit").click();
+        jetty.stop();
+        jetty.start();
+        page = webClient.getPage(getBaseUri());
+        // page.getAnchorByHref("/logout");
+        WebAssert.assertLinkPresentWithText(page, "Log out");
+        page = page.getAnchorByHref("/account").click();
+        // login page should be shown again - user remembered but not authenticated
+        WebAssert.assertFormPresent(page, "loginform");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java b/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
deleted file mode 100644
index 2694b3a..0000000
--- a/samples/guice/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.samples.guice;
-
-import com.gargoylesoftware.htmlunit.ElementNotFoundException;
-import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
-import com.gargoylesoftware.htmlunit.WebAssert;
-import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlInput;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-public class ContainerIntegrationTest extends AbstractContainerTest {
-
-    @Before
-    public void logOut() throws IOException {
-        // Make sure we are logged out
-        final HtmlPage homePage = webClient.getPage(getBaseUri());
-        try {
-            homePage.getAnchorByHref("/logout").click();
-        }
-        catch (ElementNotFoundException e) {
-            //Ignore
-        }
-    }
-
-    @Test
-    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
-
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        page = form.<HtmlInput>getInputByName("submit").click();
-        // This'll throw an expection if not logged in
-        page.getAnchorByHref("/logout");
-    }
-
-    @Test
-    public void logInAndRememberMe() throws Exception {
-        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
-        HtmlForm form = page.getFormByName("loginform");
-        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
-        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
-        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
-        checkbox.setChecked(true);
-        page = form.<HtmlInput>getInputByName("submit").click();
-        server.stop();
-        server.start();
-        page = webClient.getPage(getBaseUri());
-        // page.getAnchorByHref("/logout");
-        WebAssert.assertLinkPresentWithText(page, "Log out");
-        page = page.getAnchorByHref("/account").click();
-        // login page should be shown again - user remembered but not authenticated
-        WebAssert.assertFormPresent(page, "loginform");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/samples/servlet-plugin/pom.xml b/samples/servlet-plugin/pom.xml
index b969768..75c7cb6 100644
--- a/samples/servlet-plugin/pom.xml
+++ b/samples/servlet-plugin/pom.xml
@@ -31,10 +31,6 @@
     <name>Apache Shiro :: Samples :: Servlet Plugin</name>
     <packaging>war</packaging>
 
-    <properties>
-        <jetty.version>9.3.0.M1</jetty.version>
-    </properties>
-
     <build>
         <plugins>
             <plugin>
@@ -74,7 +70,6 @@
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>jstl</artifactId>
-            <version>1.2</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/web/pom.xml
----------------------------------------------------------------------
diff --git a/samples/web/pom.xml b/samples/web/pom.xml
index cf53c2b..8b045fd 100644
--- a/samples/web/pom.xml
+++ b/samples/web/pom.xml
@@ -38,40 +38,6 @@
     </properties>
 
     <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.mortbay.jetty</groupId>
-                    <artifactId>maven-jetty-plugin</artifactId>
-                    <version>${jetty.version}</version>
-                    <configuration>
-                        <contextPath>/</contextPath>
-                        <stopPort>8005</stopPort>
-                        <stopKey>STOP</stopKey>
-                        <connectors>
-                            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
-                                <port>${jetty.port}</port>
-                                <maxIdleTime>60000</maxIdleTime>
-                            </connector>
-                        </connectors>
-                        <requestLog implementation="org.mortbay.jetty.NCSARequestLog">
-                            <filename>./target/yyyy_mm_dd.request.log</filename>
-                            <retainDays>90</retainDays>
-                            <append>true</append>
-                            <extended>false</extended>
-                            <logTimeZone>GMT</logTimeZone>
-                        </requestLog>
-                    </configuration>
-                    <dependencies>
-                        <dependency>
-                            <groupId>org.mortbay.jetty</groupId>
-                            <artifactId>jsp-2.1-jetty</artifactId>
-                            <version>${jetty.version}</version>
-                        </dependency>
-                    </dependencies>
-                </plugin>
-            </plugins>
-        </pluginManagement>
         <plugins>
             <plugin>
                 <artifactId>maven-surefire-plugin</artifactId>
@@ -80,8 +46,23 @@
                 </configuration>
             </plugin>
             <plugin>
-                <groupId>org.mortbay.jetty</groupId>
-                <artifactId>maven-jetty-plugin</artifactId>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <configuration>
+                    <contextPath>/</contextPath>
+                    <httpConnector>
+                        <port>9080</port>
+                        <idleTimeout>60000</idleTimeout>
+                    </httpConnector>
+                    <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+                        <filename>./target/yyyy_mm_dd.request.log</filename>
+                        <retainDays>90</retainDays>
+                        <append>true</append>
+                        <extended>false</extended>
+                        <logTimeZone>GMT</logTimeZone>
+                    </requestLog>
+                </configuration>
             </plugin>
         </plugins>
     </build>
@@ -126,68 +107,33 @@
             <artifactId>jcl-over-slf4j</artifactId>
             <scope>runtime</scope>
         </dependency>
-    </dependencies>
 
-    <profiles>
-        <profile>
-            <id>run-ITs</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.mortbay.jetty</groupId>
-                        <artifactId>maven-jetty-plugin</artifactId>
-                        <executions>
-                            <!-- start jetty before ITs -->
-                            <execution>
-                                <id>start-jetty</id>
-                                <phase>pre-integration-test</phase>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                                <configuration>
-                                    <scanIntervalSeconds>0</scanIntervalSeconds>
-                                    <daemon>true</daemon>
-                                </configuration>
-                            </execution>
-                            <!-- Stop jetty after ITs -->
-                            <execution>
-                                <id>stop-jetty</id>
-                                <phase>post-integration-test</phase>
-                                <goals>
-                                    <goal>stop</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-antrun-plugin</artifactId>
-                        <version>1.8</version>
-                        <executions>
-                            <execution>
-                                <id>sleep-for-a-while</id>
-                                <phase>post-integration-test</phase>
-                                <configuration>
-                                    <target>
-                                        <!-- This is dirty looking, but this old version needs it or the shutdown
-                                        hook will print exceptions, the build will still pass, so it is mostly cosmetic.
-                                        -->
-                                        <echo>Waiting for Jetty to stop</echo>
-                                        <sleep seconds="${jetty.postIT.sleep}" />
-                                    </target>
-                                </configuration>
-                                <goals>
-                                    <goal>run</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java b/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
new file mode 100644
index 0000000..4e3e598
--- /dev/null
+++ b/samples/web/src/test/java/org/apache/shiro/test/AbstractContainerIT.java
@@ -0,0 +1,145 @@
+/*
+ * 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.test;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    private static EmbeddedJetty jetty;
+
+    private static int port = 0;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+        port = jetty.getPort();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + port + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/db46b11c/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
index e8f7b48..cd5ae7f 100644
--- a/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
+++ b/samples/web/src/test/java/org/apache/shiro/test/ContainerIntegrationIT.java
@@ -31,7 +31,7 @@ import java.io.IOException;
 import java.net.MalformedURLException;
 
 
-public class ContainerIntegrationIT {
+public class ContainerIntegrationIT extends AbstractContainerIT {
 
     protected final WebClient webClient = new WebClient();
 
@@ -47,11 +47,6 @@ public class ContainerIntegrationIT {
         }
     }
 
-    protected static String getBaseUri() {
-        String port = System.getProperty("jetty.port", "9080");
-        return "http://localhost:" + port + "/";
-    }
-
     @Test
     public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
 


[06/20] shiro git commit: SHIRO-296 - Typo fixes in javadoc and exceptions.

Posted by bd...@apache.org.
SHIRO-296 - Typo fixes in javadoc and exceptions.


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

Branch: refs/heads/1.4.x
Commit: d890bb3a5ac6782296418b544cec7a76e0065d11
Parents: fbd6970
Author: Bruce Mitchener <br...@gmail.com>
Authored: Sat May 14 19:45:48 2011 +0700
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 .../shiro/authc/AbstractAuthenticator.java      |  2 +-
 .../apache/shiro/authc/AuthenticationInfo.java  |  2 +-
 .../apache/shiro/authc/AuthenticationToken.java |  2 +-
 .../shiro/authc/UsernamePasswordToken.java      | 32 ++++++++++----------
 .../credential/HashedCredentialsMatcher.java    |  2 +-
 .../org/apache/shiro/authc/package-info.java    |  2 +-
 .../authc/pam/AtLeastOneSuccessfulStrategy.java |  2 +-
 .../shiro/authc/pam/AuthenticationStrategy.java |  2 +-
 .../authc/pam/ModularRealmAuthenticator.java    |  4 +--
 .../apache/shiro/authz/AuthorizationInfo.java   |  2 +-
 .../java/org/apache/shiro/authz/Authorizer.java |  8 ++---
 .../java/org/apache/shiro/authz/Permission.java |  4 +--
 .../shiro/authz/SimpleAuthorizationInfo.java    |  2 +-
 .../annotation/RequiresAuthentication.java      |  2 +-
 .../shiro/authz/annotation/RequiresRoles.java   |  2 +-
 .../shiro/authz/annotation/RequiresUser.java    |  2 +-
 .../shiro/authz/annotation/package-info.java    |  2 +-
 .../org/apache/shiro/authz/package-info.java    |  2 +-
 .../java/org/apache/shiro/codec/Base64.java     |  6 ++--
 .../main/java/org/apache/shiro/codec/Hex.java   | 16 +++++-----
 .../org/apache/shiro/io/DefaultSerializer.java  |  2 +-
 .../java/org/apache/shiro/io/ResourceUtils.java |  2 +-
 .../java/org/apache/shiro/io/Serializer.java    |  4 +--
 .../main/java/org/apache/shiro/realm/Realm.java |  6 ++--
 .../shiro/realm/text/PropertiesRealm.java       |  4 +--
 .../realm/text/TextConfigurationRealm.java      |  2 +-
 .../java/org/apache/shiro/session/Session.java  |  4 +--
 .../shiro/session/SessionListenerAdapter.java   |  6 ++--
 .../session/mgt/AbstractSessionManager.java     |  2 +-
 .../session/mgt/ValidatingSessionManager.java   |  2 +-
 .../org/apache/shiro/session/package-info.java  |  4 +--
 .../shiro/subject/PrincipalCollection.java      |  2 +-
 .../subject/SimplePrincipalCollection.java      |  4 +--
 .../java/org/apache/shiro/subject/Subject.java  |  4 +--
 .../org/apache/shiro/subject/package-info.java  |  2 +-
 .../org/apache/shiro/util/ThreadContext.java    |  4 +--
 .../org/apache/shiro/util/package-info.java     |  2 +-
 .../shiro/realm/AuthorizingRealmTest.java       |  4 +--
 .../quickstart/src/main/java/Quickstart.java    |  2 +-
 .../shiro/cache/ehcache/EhCacheManager.java     |  6 ++--
 .../QuartzSessionValidationScheduler.java       |  2 +-
 .../SecureRemoteInvocationExecutor.java         |  2 +-
 42 files changed, 85 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/AbstractAuthenticator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/AbstractAuthenticator.java b/core/src/main/java/org/apache/shiro/authc/AbstractAuthenticator.java
index f55a7d8..4a1c081 100644
--- a/core/src/main/java/org/apache/shiro/authc/AbstractAuthenticator.java
+++ b/core/src/main/java/org/apache/shiro/authc/AbstractAuthenticator.java
@@ -172,7 +172,7 @@ public abstract class AbstractAuthenticator implements Authenticator, LogoutAwar
      * authentication behavior.</li>
      * <li>If an {@code AuthenticationException} is thrown during {@code doAuthenticate},
      * {@link #notifyFailure(AuthenticationToken, AuthenticationException) notify} any registered
-     * {@link AuthenticationListener AuthenticationListener}s of the exception and then propogate the exception
+     * {@link AuthenticationListener AuthenticationListener}s of the exception and then propagate the exception
      * for the caller to handle.</li>
      * <li>If no exception is thrown (indicating a successful login),
      * {@link #notifySuccess(AuthenticationToken, AuthenticationInfo) notify} any registered

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/AuthenticationInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/AuthenticationInfo.java b/core/src/main/java/org/apache/shiro/authc/AuthenticationInfo.java
index 07fe3e6..f00920b 100644
--- a/core/src/main/java/org/apache/shiro/authc/AuthenticationInfo.java
+++ b/core/src/main/java/org/apache/shiro/authc/AuthenticationInfo.java
@@ -45,7 +45,7 @@ import java.io.Serializable;
  * <code>Account</code> interface for a given <code>Realm</code> is entirely based on your application's needs or your
  * preferences.
  * <p/>
- * <p><b>Pleae note:</b>  Since Shiro sometimes logs authentication operations, please ensure your AuthenticationInfo's
+ * <p><b>Please note:</b>  Since Shiro sometimes logs authentication operations, please ensure your AuthenticationInfo's
  * <code>toString()</code> implementation does <em>not</em> print out account credentials (password, etc), as these might be viewable to
  * someone reading your logs.  This is good practice anyway, and account credentials should rarely (if ever) be printed
  * out for any reason.  If you're using Shiro's default implementations of this interface, they only ever print the

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/AuthenticationToken.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/AuthenticationToken.java b/core/src/main/java/org/apache/shiro/authc/AuthenticationToken.java
index 7da053f..5f5b682 100644
--- a/core/src/main/java/org/apache/shiro/authc/AuthenticationToken.java
+++ b/core/src/main/java/org/apache/shiro/authc/AuthenticationToken.java
@@ -43,7 +43,7 @@ import java.io.Serializable;
  * {@link UsernamePasswordToken UsernamePasswordToken} class, as it is probably sufficient for your needs.
  * <p/>
  * <p>RememberMe services are enabled for a token if they implement a sub-interface of this one, called
- * {@link RememberMeAuthenticationToken RememberMeAuthenticationToken}.  Implement that interfac if you need
+ * {@link RememberMeAuthenticationToken RememberMeAuthenticationToken}.  Implement that interface if you need
  * RememberMe services (the <tt>UsernamePasswordToken</tt> already implements this interface).
  * <p/>
  * <p>If you are familiar with JAAS, an <tt>AuthenticationToken</tt> replaces the concept of a

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/UsernamePasswordToken.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/UsernamePasswordToken.java b/core/src/main/java/org/apache/shiro/authc/UsernamePasswordToken.java
index 25cf4c4..23768f2 100644
--- a/core/src/main/java/org/apache/shiro/authc/UsernamePasswordToken.java
+++ b/core/src/main/java/org/apache/shiro/authc/UsernamePasswordToken.java
@@ -23,7 +23,7 @@ package org.apache.shiro.authc;
  * class also implements the {@link RememberMeAuthenticationToken RememberMeAuthenticationToken} interface to support
  * &quot;Remember Me&quot; services across user sessions as well as the
  * {@link org.apache.shiro.authc.HostAuthenticationToken HostAuthenticationToken} interface to retain the host name
- * or IP address location from where the authentication attempt is occuring.</p>
+ * or IP address location from where the authentication attempt is occurring.</p>
  * <p/>
  * <p>&quot;Remember Me&quot; authentications are disabled by default, but if the application developer wishes to allow
  * it for a login attempt, all that is necessary is to call {@link #setRememberMe setRememberMe(true)}.  If the underlying
@@ -100,7 +100,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
      * during an authentication attempt, with a <tt>null</tt> {@link #getHost() host} and
      * a <tt>rememberMe</tt> default of <tt>false</tt>
      * <p/>
-     * <p>This is a convience constructor and maintains the password internally via a character
+     * <p>This is a convenience constructor and maintains the password internally via a character
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
      *
@@ -117,7 +117,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
      *
      * @param username the username submitted for authentication
      * @param password the password string submitted for authentication
-     * @param host     the host name or IP string from where the attempt is occuring
+     * @param host     the host name or IP string from where the attempt is occurring
      * @since 0.2
      */
     public UsernamePasswordToken(final String username, final char[] password, final String host) {
@@ -128,13 +128,13 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, the
      * inetAddress from where the attempt is occurring, and a default <tt>rememberMe</tt> value of <tt>false</tt>
      * <p/>
-     * <p>This is a convience constructor and maintains the password internally via a character
+     * <p>This is a convenience constructor and maintains the password internally via a character
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
      *
      * @param username the username submitted for authentication
      * @param password the password string submitted for authentication
-     * @param host     the host name or IP string from where the attempt is occuring
+     * @param host     the host name or IP string from where the attempt is occurring
      * @since 1.0
      */
     public UsernamePasswordToken(final String username, final String password, final String host) {
@@ -158,7 +158,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, as well as if the user
      * wishes their identity to be remembered across sessions.
      * <p/>
-     * <p>This is a convience constructor and maintains the password internally via a character
+     * <p>This is a convenience constructor and maintains the password internally via a character
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
      *
@@ -173,12 +173,12 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
 
     /**
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
-     * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
+     * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is occurring.
      *
      * @param username   the username submitted for authentication
      * @param password   the password character array submitted for authentication
      * @param rememberMe if the user wishes their identity to be remembered across sessions
-     * @param host       the host name or IP string from where the attempt is occuring
+     * @param host       the host name or IP string from where the attempt is occurring
      * @since 1.0
      */
     public UsernamePasswordToken(final String username, final char[] password,
@@ -193,16 +193,16 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
 
     /**
      * Constructs a new UsernamePasswordToken encapsulating the username and password submitted, if the user
-     * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is ocurring.
+     * wishes their identity to be remembered across sessions, and the inetAddress from where the attempt is occurring.
      * <p/>
-     * <p>This is a convience constructor and maintains the password internally via a character
+     * <p>This is a convenience constructor and maintains the password internally via a character
      * array, i.e. <tt>password.toCharArray();</tt>.  Note that storing a password as a String
      * in your code could have possible security implications as noted in the class JavaDoc.</p>
      *
      * @param username   the username submitted for authentication
      * @param password   the password string submitted for authentication
      * @param rememberMe if the user wishes their identity to be remembered across sessions
-     * @param host       the host name or IP string from where the attempt is occuring
+     * @param host       the host name or IP string from where the attempt is occurring
      * @since 1.0
      */
     public UsernamePasswordToken(final String username, final String password,
@@ -245,7 +245,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
     /**
      * Sets the password for submission during an authentication attempt.
      *
-     * @param password the password to be used for submission during an authentication attemp.
+     * @param password the password to be used for submission during an authentication attempt.
      */
     public void setPassword(char[] password) {
         this.password = password;
@@ -293,7 +293,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
      * <p>(Shiro's default Authenticator
      * allows <tt>null</tt> hosts to allow localhost and proxy server environments).</p>
      *
-     * @param host the host name or IP string from where the attempt is occuring
+     * @param host the host name or IP string from where the attempt is occurring
      * @since 1.0
      */
     public void setHost(String host) {
@@ -313,10 +313,10 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
     }
 
     /**
-     * Sets if the submitting user wishes their identity (pricipal(s)) to be remembered across sessions.  Unless
+     * Sets if the submitting user wishes their identity (principal(s)) to be remembered across sessions.  Unless
      * overridden, the default value is <tt>false</tt>, indicating <em>not</em> to be remembered across sessions.
      *
-     * @param rememberMe value inidicating if the user wishes their identity (principal(s)) to be remembered across
+     * @param rememberMe value indicating if the user wishes their identity (principal(s)) to be remembered across
      *                   sessions.
      * @since 0.9
      */
@@ -348,7 +348,7 @@ public class UsernamePasswordToken implements HostAuthenticationToken, RememberM
 
     /**
      * Returns the String representation.  It does not include the password in the resulting
-     * string for security reasons to prevent accidentially printing out a password
+     * string for security reasons to prevent accidentally printing out a password
      * that might be widely viewable).
      *
      * @return the String representation of the <tt>UsernamePasswordToken</tt>, omitting

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/credential/HashedCredentialsMatcher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/credential/HashedCredentialsMatcher.java b/core/src/main/java/org/apache/shiro/authc/credential/HashedCredentialsMatcher.java
index a08f6d8..274127d 100644
--- a/core/src/main/java/org/apache/shiro/authc/credential/HashedCredentialsMatcher.java
+++ b/core/src/main/java/org/apache/shiro/authc/credential/HashedCredentialsMatcher.java
@@ -128,7 +128,7 @@ public class HashedCredentialsMatcher extends SimpleCredentialsMatcher {
     private boolean storedCredentialsHexEncoded;
 
     /**
-     * JavaBeans-compatibile no-arg constructor intended for use in IoC/Dependency Injection environments.  If you
+     * JavaBeans-compatible no-arg constructor intended for use in IoC/Dependency Injection environments.  If you
      * use this constructor, you <em>MUST</em> also additionally set the
      * {@link #setHashAlgorithmName(String) hashAlgorithmName} property.
      */

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/package-info.java b/core/src/main/java/org/apache/shiro/authc/package-info.java
index 35b8b05..588a7f1 100644
--- a/core/src/main/java/org/apache/shiro/authc/package-info.java
+++ b/core/src/main/java/org/apache/shiro/authc/package-info.java
@@ -19,7 +19,7 @@
 /**
  * Core interfaces and exceptions concerning Authentication (the act of logging-in).
  * <p/>
- * Shiro abbreviates the word 'AuthentiCation' as <tt>authc</tt> to distinguish it seperately from
+ * Shiro abbreviates the word 'AuthentiCation' as <tt>authc</tt> to distinguish it separately from
  * 'AuthoriZation', abbreviated as <tt>authz</tt>.
  * <p/>
  * The primary item of interest in this package is the <tt>Authenticator</tt> interface, which acts as the

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/pam/AtLeastOneSuccessfulStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/pam/AtLeastOneSuccessfulStrategy.java b/core/src/main/java/org/apache/shiro/authc/pam/AtLeastOneSuccessfulStrategy.java
index 8744586..ebd990f 100644
--- a/core/src/main/java/org/apache/shiro/authc/pam/AtLeastOneSuccessfulStrategy.java
+++ b/core/src/main/java/org/apache/shiro/authc/pam/AtLeastOneSuccessfulStrategy.java
@@ -48,7 +48,7 @@ public class AtLeastOneSuccessfulStrategy extends AbstractAuthenticationStrategy
      * that none of the realms authenticated successfully.
      */
     public AuthenticationInfo afterAllAttempts(AuthenticationToken token, AuthenticationInfo aggregate) throws AuthenticationException {
-        //we know if one or more were able to succesfully authenticate if the aggregated account object does not
+        //we know if one or more were able to successfully authenticate if the aggregated account object does not
         //contain null or empty data:
         if (aggregate == null || CollectionUtils.isEmpty(aggregate.getPrincipals())) {
             throw new AuthenticationException("Authentication token of type [" + token.getClass() + "] " +

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/pam/AuthenticationStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/pam/AuthenticationStrategy.java b/core/src/main/java/org/apache/shiro/authc/pam/AuthenticationStrategy.java
index 0b2410e..e816e74 100644
--- a/core/src/main/java/org/apache/shiro/authc/pam/AuthenticationStrategy.java
+++ b/core/src/main/java/org/apache/shiro/authc/pam/AuthenticationStrategy.java
@@ -100,7 +100,7 @@ public interface AuthenticationStrategy {
 
     /**
      * Method invoked by the ModularAuthenticator signifying that all of its configured Realms have been consulted
-     * for account data, allowing post-proccessing after all realms have completed.
+     * for account data, allowing post-processing after all realms have completed.
      *
      * <p>Returns the final AuthenticationInfo object that will be returned from the Authenticator to the authenticate() caller.
      * This is most likely the aggregate AuthenticationInfo object that has been populated by many realms, but the actual return value is

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java b/core/src/main/java/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java
index 53a4f78..04e8e60 100644
--- a/core/src/main/java/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java
+++ b/core/src/main/java/org/apache/shiro/authc/pam/ModularRealmAuthenticator.java
@@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory;
 import java.util.Collection;
 
 /**
- * A {@code ModularRealmAuthenticator} delgates account lookups to a pluggable (modular) collection of
+ * A {@code ModularRealmAuthenticator} delegates account lookups to a pluggable (modular) collection of
  * {@link Realm}s.  This enables PAM (Pluggable Authentication Module) behavior in Shiro.
  * In addition to authorization duties, a Shiro Realm can also be thought of a PAM 'module'.
  * <p/>
@@ -50,7 +50,7 @@ import java.util.Collection;
  * <p/>
  * The strategy object provides callback methods that allow you to
  * determine what constitutes a success or failure in a multi-realm (PAM) scenario.  And because this only makes sense
- * in a mult-realm scenario, the strategy object is only utilized when more than one Realm is configured.
+ * in a multi-realm scenario, the strategy object is only utilized when more than one Realm is configured.
  * <p/>
  * As most multi-realm applications require at least one Realm authenticates successfully, the default
  * implementation is the {@link AtLeastOneSuccessfulStrategy}.

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/AuthorizationInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/AuthorizationInfo.java b/core/src/main/java/org/apache/shiro/authz/AuthorizationInfo.java
index 17b699c..cc35ef2 100644
--- a/core/src/main/java/org/apache/shiro/authz/AuthorizationInfo.java
+++ b/core/src/main/java/org/apache/shiro/authz/AuthorizationInfo.java
@@ -38,7 +38,7 @@ import java.util.Collection;
  * Both permission collections together represent the total aggregate collection of permissions.  You may use one
  * or both depending on your preference and needs.
  * <p/>
- * Because the act of authorization (access control) is orthoganal to authentication (log-in), this interface is
+ * Because the act of authorization (access control) is orthogonal to authentication (log-in), this interface is
  * intended to represent only the account data needed by Shiro during an access control check
  * (role, permission, etc).  Shiro also has a parallel
  * {@link org.apache.shiro.authc.AuthenticationInfo AuthenticationInfo} interface for use during the authentication

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/Authorizer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/Authorizer.java b/core/src/main/java/org/apache/shiro/authz/Authorizer.java
index f3f8b0e..9316af1 100644
--- a/core/src/main/java/org/apache/shiro/authz/Authorizer.java
+++ b/core/src/main/java/org/apache/shiro/authz/Authorizer.java
@@ -40,7 +40,7 @@ import java.util.List;
  * (Shiro's default implementations do String-to-Permission conversion for these methods using
  * {@link org.apache.shiro.authz.permission.PermissionResolver PermissionResolver}s.)
  *
- * <p>These overloaded *Permission methods <em>do</em> forego type-saftey for the benefit of convenience and simplicity,
+ * <p>These overloaded *Permission methods <em>do</em> forego type-safety for the benefit of convenience and simplicity,
  * so you should choose which ones to use based on your preferences and needs.
  *
  * @since 0.1
@@ -159,7 +159,7 @@ public interface Authorizer {
 
     /**
      * Ensures a subject/user {@link Permission#implies(Permission)} implies} the specified <tt>Permission</tt>.
-     * If the subject's exisiting associated permissions do not {@link Permission#implies(Permission)} imply}
+     * If the subject's existing associated permissions do not {@link Permission#implies(Permission)} imply}
      * the given permission, an {@link AuthorizationException} will be thrown.
      *
      * @param subjectPrincipal the application-specific subject/user identifier.
@@ -174,7 +174,7 @@ public interface Authorizer {
      * {@link Permission#implies(Permission) implies} all of the
      * specified permission strings.
      *
-     * If the subject's exisiting associated permissions do not
+     * If the subject's existing associated permissions do not
      * {@link Permission#implies(Permission) imply} all of the given permissions,
      * an {@link AuthorizationException} will be thrown.
      *
@@ -193,7 +193,7 @@ public interface Authorizer {
      * {@link Permission#implies(Permission) implies} all of the
      * specified permission strings.
      *
-     * If the subject's exisiting associated permissions do not
+     * If the subject's existing associated permissions do not
      * {@link Permission#implies(Permission) imply} all of the given permissions,
      * an {@link AuthorizationException} will be thrown.
      *

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/Permission.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/Permission.java b/core/src/main/java/org/apache/shiro/authz/Permission.java
index ea6d185..ab7082f 100644
--- a/core/src/main/java/org/apache/shiro/authz/Permission.java
+++ b/core/src/main/java/org/apache/shiro/authz/Permission.java
@@ -28,7 +28,7 @@ package org.apache.shiro.authz;
  * configuration, typically by assigning Permissions to users, roles and/or groups.
  * <p/>
  * Most typical systems are what the Shiro team calls <em>role-based</em> in nature, where a role represents
- * common behavior for certain user types.  For example, a system might have an <em>Aministrator</em> role, a
+ * common behavior for certain user types.  For example, a system might have an <em>Administrator</em> role, a
  * <em>User</em> or <em>Guest</em> roles, etc.
  * <p/>
  * But if you have a dynamic security model, where roles can be created and deleted at runtime, you can't hard-code
@@ -69,7 +69,7 @@ public interface Permission {
      * Returns {@code true} if this current instance <em>implies</em> all the functionality and/or resource access
      * described by the specified {@code Permission} argument, {@code false} otherwise.
      * <p/>
-     * <p>That is, this current instance must be exactly equal to or a <em>superset</em> of the functionalty
+     * <p>That is, this current instance must be exactly equal to or a <em>superset</em> of the functionality
      * and/or resource access described by the given {@code Permission} argument.  Yet another way of saying this
      * would be:
      * <p/>

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java b/core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java
index cb09c46..70ebef9 100644
--- a/core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java
+++ b/core/src/main/java/org/apache/shiro/authz/SimpleAuthorizationInfo.java
@@ -42,7 +42,7 @@ public class SimpleAuthorizationInfo implements AuthorizationInfo {
     protected Set<String> stringPermissions;
 
     /**
-     * Collection of all object-based permissions associaed with the account.
+     * Collection of all object-based permissions associated with the account.
      */
     protected Set<Permission> objectPermissions;
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresAuthentication.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresAuthentication.java b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresAuthentication.java
index b0a3bfb..c39edcf 100644
--- a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresAuthentication.java
+++ b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresAuthentication.java
@@ -33,7 +33,7 @@ import java.lang.annotation.Target;
  * <p/>
  * See the {@link RequiresUser RequiresUser} and
  * {@link org.apache.shiro.authc.RememberMeAuthenticationToken RememberMeAuthenticationToken} JavaDoc for an
- * explaination of why these two states are considered different.
+ * explanation of why these two states are considered different.
  *
  * @see RequiresUser
  * @see RequiresGuest

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresRoles.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresRoles.java b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresRoles.java
index b18a73b..8479c2c 100644
--- a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresRoles.java
+++ b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresRoles.java
@@ -55,7 +55,7 @@ import java.lang.annotation.Target;
 public @interface RequiresRoles {
 
     /**
-     * A single String role name or multiple comma-delimitted role names required in order for the method
+     * A single String role name or multiple comma-delimited role names required in order for the method
      * invocation to be allowed.
      */
     String[] value();

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresUser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresUser.java b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresUser.java
index e773bc0..ca4f742 100644
--- a/core/src/main/java/org/apache/shiro/authz/annotation/RequiresUser.java
+++ b/core/src/main/java/org/apache/shiro/authz/annotation/RequiresUser.java
@@ -38,7 +38,7 @@ import java.lang.annotation.Target;
  * </ul>
  * <p/>
  * See the {@link org.apache.shiro.authc.RememberMeAuthenticationToken RememberMeAuthenticationToken} JavaDoc for an
- * explaination of why these two states are considered different.
+ * explanation of why these two states are considered different.
  *
  * @see RequiresAuthentication
  * @see RequiresGuest

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/annotation/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/annotation/package-info.java b/core/src/main/java/org/apache/shiro/authz/annotation/package-info.java
index 550f666..3fa8d23 100644
--- a/core/src/main/java/org/apache/shiro/authz/annotation/package-info.java
+++ b/core/src/main/java/org/apache/shiro/authz/annotation/package-info.java
@@ -20,7 +20,7 @@
  * Annotations used to restrict which classes, instances, or methods may be accessed or invoked depending on the
  * caller's access abilities or authentication state.
  * 
- * Since 1.1, all core annotations were extends to accept Target ElementType.TYPE in additon to ElementType.METHOD 
+ * Since 1.1, all core annotations were extends to accept Target ElementType.TYPE in addition to ElementType.METHOD 
  */
 package org.apache.shiro.authz.annotation;
 import java.lang.annotation.ElementType;

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/authz/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/authz/package-info.java b/core/src/main/java/org/apache/shiro/authz/package-info.java
index 3403023..cf2de7f 100644
--- a/core/src/main/java/org/apache/shiro/authz/package-info.java
+++ b/core/src/main/java/org/apache/shiro/authz/package-info.java
@@ -19,7 +19,7 @@
 /**
  * Core interfaces and exceptions supporting Authorization (access control).
  * <p/>
- * Shiro abbreviates the word 'AuthoriZation' as <tt>authz</tt> to distinguish it seperately from
+ * Shiro abbreviates the word 'AuthoriZation' as <tt>authz</tt> to distinguish it separately from
  * 'AuthentiCation', abbreviated as <tt>authc</tt>.
  * <p/>
  * This package's primary interface of interest, which is the core of Shiro authorization functionality,

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/codec/Base64.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/codec/Base64.java b/core/src/main/java/org/apache/shiro/codec/Base64.java
index 2d6cb08..da31059 100644
--- a/core/src/main/java/org/apache/shiro/codec/Base64.java
+++ b/core/src/main/java/org/apache/shiro/codec/Base64.java
@@ -26,7 +26,7 @@ package org.apache.shiro.codec;
  * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein.
  * <p/>
  * This class was borrowed from Apache Commons Codec SVN repository (rev. 618419) with modifications
- * to enable Base64 conversion without a full dependecny on Commons Codec.  We didn't want to reinvent the wheel of
+ * to enable Base64 conversion without a full dependency on Commons Codec.  We didn't want to reinvent the wheel of
  * great work they've done, but also didn't want to force every Shiro user to depend on the commons-codec.jar
  * <p/>
  * As per the Apache 2.0 license, the original copyright notice and all author and copyright information have
@@ -152,7 +152,7 @@ public class Base64 {
     }
 
     /**
-     * Returns whether or not the <code>octect</code> is in the base 64 alphabet.
+     * Returns whether or not the <code>octet</code> is in the base 64 alphabet.
      *
      * @param octect The value to test
      * @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise.
@@ -415,7 +415,7 @@ public class Base64 {
     }
 
     /**
-     * Decodes Base64 data into octects
+     * Decodes Base64 data into octets
      *
      * @param base64Data Byte array containing Base64 data
      * @return Array containing decoded data.

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/codec/Hex.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/codec/Hex.java b/core/src/main/java/org/apache/shiro/codec/Hex.java
index eb41583..79e72ac 100644
--- a/core/src/main/java/org/apache/shiro/codec/Hex.java
+++ b/core/src/main/java/org/apache/shiro/codec/Hex.java
@@ -42,7 +42,7 @@ public class Hex {
     };
 
     /**
-     * Encodes the specifed byte array to a character array and then returns that character array
+     * Encodes the specified byte array to a character array and then returns that character array
      * as a String.
      *
      * @param bytes the byte array to Hex-encode.
@@ -54,12 +54,12 @@ public class Hex {
     }
 
     /**
-     * Converts an array of bytes into an array of characters representing the hexidecimal values of each byte in order.
+     * Converts an array of bytes into an array of characters representing the hexadecimal values of each byte in order.
      * The returned array will be double the length of the passed array, as it takes two characters to represent any
      * given byte.
      *
      * @param data byte[] to convert to Hex characters
-     * @return A char[] containing hexidecimal characters
+     * @return A char[] containing hexadecimal characters
      */
     public static char[] encode(byte[] data) {
 
@@ -77,13 +77,13 @@ public class Hex {
     }
 
     /**
-     * Converts an array of character bytes representing hexidecimal values into an
+     * Converts an array of character bytes representing hexadecimal values into an
      * array of bytes of those same values. The returned array will be half the
      * length of the passed array, as it takes two characters to represent any
      * given byte. An exception is thrown if the passed char array has an odd
      * number of elements.
      *
-     * @param array An array of character bytes containing hexidecimal digits
+     * @param array An array of character bytes containing hexadecimal digits
      * @return A byte array containing binary data decoded from
      *         the supplied byte array (representing characters).
      * @throws IllegalArgumentException Thrown if an odd number of characters is supplied
@@ -108,13 +108,13 @@ public class Hex {
     }
 
     /**
-     * Converts an array of characters representing hexidecimal values into an
+     * Converts an array of characters representing hexadecimal values into an
      * array of bytes of those same values. The returned array will be half the
      * length of the passed array, as it takes two characters to represent any
      * given byte. An exception is thrown if the passed char array has an odd
      * number of elements.
      *
-     * @param data An array of characters containing hexidecimal digits
+     * @param data An array of characters containing hexadecimal digits
      * @return A byte array containing binary data decoded from
      *         the supplied char array.
      * @throws IllegalArgumentException if an odd number or illegal of characters
@@ -153,7 +153,7 @@ public class Hex {
     protected static int toDigit(char ch, int index) throws IllegalArgumentException {
         int digit = Character.digit(ch, 16);
         if (digit == -1) {
-            throw new IllegalArgumentException("Illegal hexadecimal charcter " + ch + " at index " + index);
+            throw new IllegalArgumentException("Illegal hexadecimal character " + ch + " at index " + index);
         }
         return digit;
     }

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/io/DefaultSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/io/DefaultSerializer.java b/core/src/main/java/org/apache/shiro/io/DefaultSerializer.java
index 6fa86b8..433a825 100644
--- a/core/src/main/java/org/apache/shiro/io/DefaultSerializer.java
+++ b/core/src/main/java/org/apache/shiro/io/DefaultSerializer.java
@@ -78,7 +78,7 @@ public class DefaultSerializer<T> implements Serializer<T> {
             ois.close();
             return deserialized;
         } catch (Exception e) {
-            String msg = "Unable to deserialze argument byte array.";
+            String msg = "Unable to deserialize argument byte array.";
             throw new SerializationException(msg, e);
         }
     }

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/io/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/io/ResourceUtils.java b/core/src/main/java/org/apache/shiro/io/ResourceUtils.java
index ae44d70..703689d 100644
--- a/core/src/main/java/org/apache/shiro/io/ResourceUtils.java
+++ b/core/src/main/java/org/apache/shiro/io/ResourceUtils.java
@@ -116,7 +116,7 @@ public class ResourceUtils {
      * {@link FileInputStream FileInputStream}.
      *
      * @param resourcePath the String path representing the resource to obtain.
-     * @return the InputStraem for the specified resource.
+     * @return the InputStream for the specified resource.
      * @throws IOException if there is a problem acquiring the resource at the specified path.
      */
     public static InputStream getInputStreamForPath(String resourcePath) throws IOException {

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/io/Serializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/io/Serializer.java b/core/src/main/java/org/apache/shiro/io/Serializer.java
index 10a5cfa..daead98 100644
--- a/core/src/main/java/org/apache/shiro/io/Serializer.java
+++ b/core/src/main/java/org/apache/shiro/io/Serializer.java
@@ -37,7 +37,7 @@ public interface Serializer<T> {
      *
      * @param o the Object to convert into a byte[] array.
      * @return a byte[] array representing the Object's state that can be restored later.
-     * @throws SerializationException if an error occurrs converting the Object into a byte[] array.
+     * @throws SerializationException if an error occurs converting the Object into a byte[] array.
      */
     byte[] serialize(T o) throws SerializationException;
 
@@ -47,7 +47,7 @@ public interface Serializer<T> {
      *
      * @param serialized the raw data resulting from a previous {@link #serialize(Object) serialize} call.
      * @return the Object that was previously serialized into the raw byte[] array.
-     * @throws SerializationException if an error occurrs converting the raw byte[] array back into an Object.
+     * @throws SerializationException if an error occurs converting the raw byte[] array back into an Object.
      */
     T deserialize(byte[] serialized) throws SerializationException;
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/realm/Realm.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/realm/Realm.java b/core/src/main/java/org/apache/shiro/realm/Realm.java
index 13f15e1..2f534ed 100644
--- a/core/src/main/java/org/apache/shiro/realm/Realm.java
+++ b/core/src/main/java/org/apache/shiro/realm/Realm.java
@@ -26,8 +26,8 @@ import org.apache.shiro.authc.AuthenticationToken;
  * A <tt>Realm</tt> is a security component that can access application-specific security entities
  * such as users, roles, and permissions to determine authentication and authorization operations.
  *
- * <p><tt>Realm</tt>s usually have a 1-to-1 correspondance with a datasource such as a relational database,
- * file sysetem, or other similar resource.  As such, implementations of this interface use datasource-specific APIs to
+ * <p><tt>Realm</tt>s usually have a 1-to-1 correspondence with a datasource such as a relational database,
+ * file system, or other similar resource.  As such, implementations of this interface use datasource-specific APIs to
  * determine authorization data (roles, permissions, etc), such as JDBC, File IO, Hibernate or JPA, or any other
  * Data Access API.  They are essentially security-specific
  * <a href="http://en.wikipedia.org/wiki/Data_Access_Object" target="_blank">DAO</a>s.
@@ -98,7 +98,7 @@ public interface Realm {
      *         or <tt>null</tt> if no account could be found.
      * @throws org.apache.shiro.authc.AuthenticationException
      *          if there is an error obtaining or constructing an AuthenticationInfo object based on the
-     *          specified <tt>token</tt> or implementation-specifc login behavior fails.
+     *          specified <tt>token</tt> or implementation-specific login behavior fails.
      */
     AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/realm/text/PropertiesRealm.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/realm/text/PropertiesRealm.java b/core/src/main/java/org/apache/shiro/realm/text/PropertiesRealm.java
index cbdb31d..3e47193 100644
--- a/core/src/main/java/org/apache/shiro/realm/text/PropertiesRealm.java
+++ b/core/src/main/java/org/apache/shiro/realm/text/PropertiesRealm.java
@@ -124,7 +124,7 @@ public class PropertiesRealm extends TextConfigurationRealm implements Destroyab
 
     /**
      * Sets the path of the properties file to load user, role, and permission information from.  The properties
-     * file will be loaded using {@link ResourceUtils#getInputStreamForPath(String)} so any convention recongized
+     * file will be loaded using {@link ResourceUtils#getInputStreamForPath(String)} so any convention recognized
      * by that method is accepted here.  For example, to load a file from the classpath use
      * {@code classpath:myfile.properties}; to load a file from disk simply specify the full path; to load
      * a file from a URL use {@code url:www.mysite.com/myfile.properties}.
@@ -138,7 +138,7 @@ public class PropertiesRealm extends TextConfigurationRealm implements Destroyab
     /**
      * Sets the interval in seconds at which the property file will be checked for changes and reloaded.  If this is
      * set to zero or less, property file reloading will be disabled.  If it is set to 1 or greater, then a
-     * separate thread will be created to monitor the propery file for changes and reload the file if it is updated.
+     * separate thread will be created to monitor the property file for changes and reload the file if it is updated.
      *
      * @param reloadIntervalSeconds the interval in seconds at which the property file should be examined for changes.
      *                              If set to zero or less, reloading is disabled.

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/realm/text/TextConfigurationRealm.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/realm/text/TextConfigurationRealm.java b/core/src/main/java/org/apache/shiro/realm/text/TextConfigurationRealm.java
index 51c2ce2..5b56291 100644
--- a/core/src/main/java/org/apache/shiro/realm/text/TextConfigurationRealm.java
+++ b/core/src/main/java/org/apache/shiro/realm/text/TextConfigurationRealm.java
@@ -104,7 +104,7 @@ public class TextConfigurationRealm extends SimpleAccountRealm {
      * <p/>
      * <p>where <em>permissionDefinition</em> is an arbitrary String, but must people will want to use
      * Strings that conform to the {@link org.apache.shiro.authz.permission.WildcardPermission WildcardPermission}
-     * format for ease of use and flexibility.  Note that if an individual <em>permissionDefnition</em> needs to
+     * format for ease of use and flexibility.  Note that if an individual <em>permissionDefinition</em> needs to
      * be internally comma-delimited (e.g. <code>printer:5thFloor:print,info</code>), you will need to surround that
      * definition with double quotes (&quot;) to avoid parsing errors (e.g.
      * <code>&quot;printer:5thFloor:print,info&quot;</code>).

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/session/Session.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/session/Session.java b/core/src/main/java/org/apache/shiro/session/Session.java
index 7abe2ed..4535051 100644
--- a/core/src/main/java/org/apache/shiro/session/Session.java
+++ b/core/src/main/java/org/apache/shiro/session/Session.java
@@ -116,7 +116,7 @@ public interface Session {
      * automatically as a result of an incoming web request or remote procedure call/method invocation.
      * <p/>
      * However, this method is particularly useful when supporting rich-client applications such as
-     * Java Web Start appp, Java or Flash applets, etc.  Although rare, it is possible in a rich-client
+     * Java Web Start app, Java or Flash applets, etc.  Although rare, it is possible in a rich-client
      * environment that a user continuously interacts with the client-side application without a
      * server-side method call ever being invoked.  If this happens over a long enough period of
      * time, the user's server-side session could time-out.  Again, such cases are rare since most
@@ -183,7 +183,7 @@ public interface Session {
     Object getAttribute(Object key) throws InvalidSessionException;
 
     /**
-     * Binds the specified {@code value} to this session, uniquely identified by the specifed
+     * Binds the specified {@code value} to this session, uniquely identified by the specified
      * {@code key} name.  If there is already an object bound under the {@code key} name, that
      * existing object will be replaced by the new {@code value}.
      * <p/>

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/session/SessionListenerAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/session/SessionListenerAdapter.java b/core/src/main/java/org/apache/shiro/session/SessionListenerAdapter.java
index 24d5860..5e46af7 100644
--- a/core/src/main/java/org/apache/shiro/session/SessionListenerAdapter.java
+++ b/core/src/main/java/org/apache/shiro/session/SessionListenerAdapter.java
@@ -27,7 +27,7 @@ package org.apache.shiro.session;
 public class SessionListenerAdapter implements SessionListener {
 
     /**
-     * Adapter no-op implemenation - does nothing and returns immediately.
+     * Adapter no-op implementation - does nothing and returns immediately.
      *
      * @param session the session that has started.
      */
@@ -36,7 +36,7 @@ public class SessionListenerAdapter implements SessionListener {
     }
 
     /**
-     * Adapter no-op implemenation - does nothing and returns immediately.
+     * Adapter no-op implementation - does nothing and returns immediately.
      *
      * @param session the session that has stopped.
      */
@@ -45,7 +45,7 @@ public class SessionListenerAdapter implements SessionListener {
     }
 
     /**
-     * Adapter no-op implemenation - does nothing and returns immediately.
+     * Adapter no-op implementation - does nothing and returns immediately.
      *
      * @param session the session that has expired.
      */

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/session/mgt/AbstractSessionManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/session/mgt/AbstractSessionManager.java b/core/src/main/java/org/apache/shiro/session/mgt/AbstractSessionManager.java
index 5a296c1..f3815b5 100644
--- a/core/src/main/java/org/apache/shiro/session/mgt/AbstractSessionManager.java
+++ b/core/src/main/java/org/apache/shiro/session/mgt/AbstractSessionManager.java
@@ -79,7 +79,7 @@ public abstract class AbstractSessionManager implements SessionManager {
      * <p/>
      * Unless overridden by calling this method, the default value is {@link #DEFAULT_GLOBAL_SESSION_TIMEOUT}.
      *
-     * @param globalSessionTimeout the time in milliseconds that any session may remain idel before expiring.
+     * @param globalSessionTimeout the time in milliseconds that any session may remain idle before expiring.
      */
     public void setGlobalSessionTimeout(long globalSessionTimeout) {
         this.globalSessionTimeout = globalSessionTimeout;

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/session/mgt/ValidatingSessionManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/session/mgt/ValidatingSessionManager.java b/core/src/main/java/org/apache/shiro/session/mgt/ValidatingSessionManager.java
index ba2c0b4..6430324 100644
--- a/core/src/main/java/org/apache/shiro/session/mgt/ValidatingSessionManager.java
+++ b/core/src/main/java/org/apache/shiro/session/mgt/ValidatingSessionManager.java
@@ -41,7 +41,7 @@ public interface ValidatingSessionManager extends SessionManager {
      * This is obvious in the case of web applications due to the HTTP protocol, but it is
      * equally true of remote client applications making remote method invocations.  The server
      * essentially sits idle and only &quot;works&quot; when responding to client requests and/or
-     * method invocations.  This type of model is particularly efficent since it means the
+     * method invocations.  This type of model is particularly efficient since it means the
      * security system only has to validate a session during those cases.  Such
      * &quot;lazy&quot; behavior enables the system to lie stateless and/or idle and only incur
      * overhead for session validation when necessary.

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/session/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/session/package-info.java b/core/src/main/java/org/apache/shiro/session/package-info.java
index 4489231..35dfab8 100644
--- a/core/src/main/java/org/apache/shiro/session/package-info.java
+++ b/core/src/main/java/org/apache/shiro/session/package-info.java
@@ -21,12 +21,12 @@
  * interacts with an application.
  * <p/>
  * Sessions in Shiro are completely POJO-based and do not <em>require</em> an application to use Web-based
- * or EJB-based session management infrastructure - the client and/or server technoloy is irrelevent in
+ * or EJB-based session management infrastructure - the client and/or server technology is irrelevant in
  * Shiro's architecture, allowing session management to be employed in the smallest standalone application
  * to the largest enterprise deployments.
  * <p/>
  * This design decision opens up a new world to Java applications - most notably the ability to participate in
- * a session regardless if the client is using HTTP, custom sockets, web services, or even non-Java progamming
+ * a session regardless if the client is using HTTP, custom sockets, web services, or even non-Java programming
  * languages. Aside from Shiro, there is currently no technology in Java today allows this heterogenous
  * client-session capability.
  * <p/>

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/subject/PrincipalCollection.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/subject/PrincipalCollection.java b/core/src/main/java/org/apache/shiro/subject/PrincipalCollection.java
index adfd273..75da30c 100644
--- a/core/src/main/java/org/apache/shiro/subject/PrincipalCollection.java
+++ b/core/src/main/java/org/apache/shiro/subject/PrincipalCollection.java
@@ -62,7 +62,7 @@ public interface PrincipalCollection extends Iterable, Serializable {
      * Shiro's default implementations of this interface make this
      * assumption by usually simply returning {@link #iterator()}.{@link java.util.Iterator#next() next()}, which just
      * returns the first returned principal obtained from the first consulted/configured {@code Realm} during the
-     * authentication attempt.  This means in a multi-{@code Realm} application, {@code Realm} configuraiton order
+     * authentication attempt.  This means in a multi-{@code Realm} application, {@code Realm} configuration order
      * matters if you want to retain this default heuristic.
      * <p/>
      * If this heuristic is not sufficient, most Shiro end-users will need to implement a custom

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/subject/SimplePrincipalCollection.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/subject/SimplePrincipalCollection.java b/core/src/main/java/org/apache/shiro/subject/SimplePrincipalCollection.java
index 9b17f2a..8332759 100644
--- a/core/src/main/java/org/apache/shiro/subject/SimplePrincipalCollection.java
+++ b/core/src/main/java/org/apache/shiro/subject/SimplePrincipalCollection.java
@@ -264,7 +264,7 @@ public class SimplePrincipalCollection implements MutablePrincipalCollection {
      * Serialization write support.
      * <p/>
      * NOTE: Don't forget to change the serialVersionUID constant at the top of this class
-     * if you make any backwards-incompatible serializatoin changes!!!
+     * if you make any backwards-incompatible serialization changes!!!
      * (use the JDK 'serialver' program for this)
      *
      * @param out output stream provided by Java serialization
@@ -284,7 +284,7 @@ public class SimplePrincipalCollection implements MutablePrincipalCollection {
      * input stream.
      * <p/>
      * NOTE: Don't forget to change the serialVersionUID constant at the top of this class
-     * if you make any backwards-incompatible serializatoin changes!!!
+     * if you make any backwards-incompatible serialization changes!!!
      * (use the JDK 'serialver' program for this)
      *
      * @param in input stream provided by

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/subject/Subject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/subject/Subject.java b/core/src/main/java/org/apache/shiro/subject/Subject.java
index eb2f5dc..45e1945 100644
--- a/core/src/main/java/org/apache/shiro/subject/Subject.java
+++ b/core/src/main/java/org/apache/shiro/subject/Subject.java
@@ -53,7 +53,7 @@ import java.util.concurrent.Callable;
  * type-safe method.  (Shiro's default implementations do String-to-Permission conversion for these methods using
  * {@link org.apache.shiro.authz.permission.PermissionResolver PermissionResolver}s.)
  * <p/>
- * These overloaded *Permission methods forgo type-saftey for the benefit of convenience and simplicity,
+ * These overloaded *Permission methods forgo type-safety for the benefit of convenience and simplicity,
  * so you should choose which ones to use based on your preferences and needs.
  *
  * @since 0.1
@@ -558,7 +558,7 @@ public interface Subject {
      * Releases the current 'run as' (assumed) identity and reverts back to the previous 'pre run as'
      * identity that existed before {@code #runAs runAs} was called.
      * <p/>
-     * This method returne 'run as' (assumed) identity being released or {@code null} if this {@code Subject} is not
+     * This method returns 'run as' (assumed) identity being released or {@code null} if this {@code Subject} is not
      * operating under an assumed identity.
      *
      * @return the 'run as' (assumed) identity being released or {@code null} if this {@code Subject} is not operating

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/subject/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/subject/package-info.java b/core/src/main/java/org/apache/shiro/subject/package-info.java
index 6995f78..996431a 100644
--- a/core/src/main/java/org/apache/shiro/subject/package-info.java
+++ b/core/src/main/java/org/apache/shiro/subject/package-info.java
@@ -20,7 +20,7 @@
  * Components supporting the {@link org.apache.shiro.subject.Subject Subject} interface, the most important concept in
  * Shiro's API.
  * <p/>
- * A <code>Subject</code> is <em>the</em> primary component when using Shiro programatically for single-user
+ * A <code>Subject</code> is <em>the</em> primary component when using Shiro programmatically for single-user
  * security operations, and it is the handle to any accessible user security data.  All single-user
  * authentication, authorization and session operations are performed via a <code>Subject</code> instance.
  */

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/util/ThreadContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/util/ThreadContext.java b/core/src/main/java/org/apache/shiro/util/ThreadContext.java
index a020955..28488a3 100644
--- a/core/src/main/java/org/apache/shiro/util/ThreadContext.java
+++ b/core/src/main/java/org/apache/shiro/util/ThreadContext.java
@@ -249,7 +249,7 @@ public abstract class ThreadContext {
      * Convenience method that simplifies removal of the application's SecurityManager instance from the thread.
      * <p/>
      * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
-     * merely a conveient wrapper for the following:
+     * merely a convenient wrapper for the following:
      * <p/>
      * <code>return (SecurityManager)remove( SECURITY_MANAGER_KEY );</code>
      * <p/>
@@ -307,7 +307,7 @@ public abstract class ThreadContext {
      * Convenience method that simplifies removal of a thread-local Subject from the thread.
      * <p/>
      * The implementation just helps reduce casting and remembering of the ThreadContext key name, i.e it is
-     * merely a conveient wrapper for the following:
+     * merely a convenient wrapper for the following:
      * <p/>
      * <code>return (Subject)remove( SUBJECT_KEY );</code>
      * <p/>

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/main/java/org/apache/shiro/util/package-info.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/util/package-info.java b/core/src/main/java/org/apache/shiro/util/package-info.java
index 742d86d..620db7d 100644
--- a/core/src/main/java/org/apache/shiro/util/package-info.java
+++ b/core/src/main/java/org/apache/shiro/util/package-info.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 /**
- * Your run-of-the-mill 'util' pacakge for components and logic widely used across the framework that can't
+ * Your run-of-the-mill 'util' package for components and logic widely used across the framework that can't
  * find their home into a proper OO hierarchy (or, most likely for things used across many hierarchies).
  */
 package org.apache.shiro.util;

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/core/src/test/java/org/apache/shiro/realm/AuthorizingRealmTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/shiro/realm/AuthorizingRealmTest.java b/core/src/test/java/org/apache/shiro/realm/AuthorizingRealmTest.java
index 13f447d..32c50df 100644
--- a/core/src/test/java/org/apache/shiro/realm/AuthorizingRealmTest.java
+++ b/core/src/test/java/org/apache/shiro/realm/AuthorizingRealmTest.java
@@ -40,7 +40,7 @@ import java.util.*;
 /**
  * Simple test case for AuthorizingRealm.
  * <p/>
- * TODO - this could/should be expaned to be more robust end to end test for the AuthorizingRealm
+ * TODO - this could/should be expanded to be more robust end to end test for the AuthorizingRealm
  */
 public class AuthorizingRealmTest {
 
@@ -252,4 +252,4 @@ public class AuthorizingRealmTest {
 
     }
 
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/samples/quickstart/src/main/java/Quickstart.java
----------------------------------------------------------------------
diff --git a/samples/quickstart/src/main/java/Quickstart.java b/samples/quickstart/src/main/java/Quickstart.java
index 95f60ea..463342b 100644
--- a/samples/quickstart/src/main/java/Quickstart.java
+++ b/samples/quickstart/src/main/java/Quickstart.java
@@ -103,7 +103,7 @@ public class Quickstart {
         }
 
         //test a typed permission (not instance-level)
-        if (currentUser.isPermitted("lightsaber:weild")) {
+        if (currentUser.isPermitted("lightsaber:wield")) {
             log.info("You may use a lightsaber ring.  Use it wisely.");
         } else {
             log.info("Sorry, lightsaber rings are for schwartz masters only.");

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/support/ehcache/src/main/java/org/apache/shiro/cache/ehcache/EhCacheManager.java
----------------------------------------------------------------------
diff --git a/support/ehcache/src/main/java/org/apache/shiro/cache/ehcache/EhCacheManager.java b/support/ehcache/src/main/java/org/apache/shiro/cache/ehcache/EhCacheManager.java
index ce1a637..64f68bb 100644
--- a/support/ehcache/src/main/java/org/apache/shiro/cache/ehcache/EhCacheManager.java
+++ b/support/ehcache/src/main/java/org/apache/shiro/cache/ehcache/EhCacheManager.java
@@ -37,7 +37,7 @@ import java.io.InputStream;
  * This class can {@link #setCacheManager(net.sf.ehcache.CacheManager) accept} a manually configured
  * {@link net.sf.ehcache.CacheManager net.sf.ehcache.CacheManager} instance,
  * or an {@code ehcache.xml} path location can be specified instead and one will be constructed. If neither are
- * specified, Shiro's failsafe <code><a href="./ehcache.xml">ehcache.xml</a>} file will be used by default.
+ * specified, Shiro's failsafe <code><a href="./ehcache.xml">ehcache.xml</a></code> file will be used by default.
  * <p/>
  * This implementation requires EhCache 1.2 and above. Make sure EhCache 1.1 or earlier
  * is not in the classpath or it will not work.
@@ -180,7 +180,7 @@ public class EhCacheManager implements CacheManager, Initializable, Destroyable
      * Initializes this instance.
      * <p/>
      * If a {@link #setCacheManager CacheManager} has been
-     * explicitly set (e.g. via Dependency Injection or programatically) prior to calling this
+     * explicitly set (e.g. via Dependency Injection or programmatically) prior to calling this
      * method, this method does nothing.
      * <p/>
      * However, if no {@code CacheManager} has been set, the default Ehcache singleton will be initialized, where
@@ -229,7 +229,7 @@ public class EhCacheManager implements CacheManager, Initializable, Destroyable
      * Shuts-down the wrapped Ehcache CacheManager <b>only if implicitly created</b>.
      * <p/>
      * If another component injected
-     * a non-null CacheManager into this instace before calling {@link #init() init}, this instance expects that same
+     * a non-null CacheManager into this instance before calling {@link #init() init}, this instance expects that same
      * component to also destroy the CacheManager instance, and it will not attempt to do so.
      */
     public void destroy() {

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/support/quartz/src/main/java/org/apache/shiro/session/mgt/quartz/QuartzSessionValidationScheduler.java
----------------------------------------------------------------------
diff --git a/support/quartz/src/main/java/org/apache/shiro/session/mgt/quartz/QuartzSessionValidationScheduler.java b/support/quartz/src/main/java/org/apache/shiro/session/mgt/quartz/QuartzSessionValidationScheduler.java
index 4ef3102..6445cc2 100644
--- a/support/quartz/src/main/java/org/apache/shiro/session/mgt/quartz/QuartzSessionValidationScheduler.java
+++ b/support/quartz/src/main/java/org/apache/shiro/session/mgt/quartz/QuartzSessionValidationScheduler.java
@@ -64,7 +64,7 @@ public class QuartzSessionValidationScheduler implements SessionValidationSchedu
 
     /**
      * The configured Quartz scheduler to use to schedule the Quartz job.  If no scheduler is
-     * configured, the schedular will be retrieved by calling {@link StdSchedulerFactory#getDefaultScheduler()}
+     * configured, the scheduler will be retrieved by calling {@link StdSchedulerFactory#getDefaultScheduler()}
      */
     private Scheduler scheduler;
 

http://git-wip-us.apache.org/repos/asf/shiro/blob/d890bb3a/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java
----------------------------------------------------------------------
diff --git a/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java b/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java
index 92d2321..4613d40 100644
--- a/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java
+++ b/support/spring/src/main/java/org/apache/shiro/spring/remoting/SecureRemoteInvocationExecutor.java
@@ -96,7 +96,7 @@ public class SecureRemoteInvocationExecutor extends DefaultRemoteInvocationExecu
                 if (log.isTraceEnabled()) {
                     log.trace("RemoteInvocation did not contain a Shiro Session id attribute under " +
                             "key [" + SecureRemoteInvocationFactory.SESSION_ID_KEY + "].  A Subject based " +
-                            "on an existing Session will not be available during the method invocatin.");
+                            "on an existing Session will not be available during the method invocation.");
                 }
             }
 


[02/20] shiro git commit: SHIRO-301 - Call permissionResolver directly in AuthorizingRealm

Posted by bd...@apache.org.
SHIRO-301 - Call permissionResolver directly in AuthorizingRealm

It was already available in the method


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

Branch: refs/heads/1.4.x
Commit: fbd69702387fce0be93a5aae90b7a7f21c09718d
Parents: ea2b483
Author: Brian Demers <bd...@apache.org>
Authored: Wed Oct 5 14:48:51 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:50 2016 -0400

----------------------------------------------------------------------
 core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/fbd69702/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java b/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
index 11c5f85..766aa94 100644
--- a/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
+++ b/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
@@ -431,7 +431,7 @@ public abstract class AuthorizingRealm extends AuthenticatingRealm
         if (resolver != null && !CollectionUtils.isEmpty(stringPerms)) {
             perms = new LinkedHashSet<Permission>(stringPerms.size());
             for (String strPermission : stringPerms) {
-                Permission permission = getPermissionResolver().resolvePermission(strPermission);
+                Permission permission = resolver.resolvePermission(strPermission);
                 perms.add(permission);
             }
         }


[14/20] shiro git commit: SHIRO-392 Added JAX-RS support module

Posted by bd...@apache.org.
SHIRO-392 Added JAX-RS support module

Based on the work of: Stig Inge Lea Bj�rnsen on the Apache licensed project silb/shiro-jersey


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

Branch: refs/heads/1.4.x
Commit: 4bf2e4ed273d3af4aad07e59f7ed50f2308817f0
Parents: 9513183
Author: Brian Demers <bd...@apache.org>
Authored: Tue Oct 11 14:50:22 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 pom.xml                                         |  17 +-
 samples/jaxrs/pom.xml                           | 204 +++++++++++++++++++
 .../shiro/sample/jaxrs/SampleApplication.java   |  50 +++++
 .../sample/jaxrs/resources/HelloResource.java   |  37 ++++
 .../sample/jaxrs/resources/SecureResource.java  |  75 +++++++
 samples/jaxrs/src/main/resources/logback.xml    |  33 +++
 samples/jaxrs/src/main/resources/shiro.ini      |  43 ++++
 .../jaxrs/src/main/webapp/WEB-INF/web.cxf.xml   |  41 ++++
 .../web/jaxrs/ContainerIntegrationIT.groovy     | 132 ++++++++++++
 .../shiro/web/jaxrs/AbstractContainerIT.java    | 148 ++++++++++++++
 samples/pom.xml                                 |   1 +
 support/jaxrs/pom.xml                           |  62 ++++++
 .../jaxrs/AnnotationAuthorizationFilter.java    |  82 ++++++++
 .../apache/shiro/web/jaxrs/ExceptionMapper.java |  48 +++++
 .../web/jaxrs/ShiroAnnotationFilterFeature.java |  71 +++++++
 .../apache/shiro/web/jaxrs/ShiroFeature.java    |  61 ++++++
 .../shiro/web/jaxrs/ShiroSecurityContext.java   | 121 +++++++++++
 .../jaxrs/SubjectPrincipalRequestFilter.java    |  41 ++++
 .../shiro/web/jaxrs/ExceptionMapperTest.groovy  |  64 ++++++
 .../web/jaxrs/ShiroSecurityContextTest.groovy   | 204 +++++++++++++++++++
 .../SubjectPrincipalRequestFilterTest.groovy    |  50 +++++
 support/pom.xml                                 |   1 +
 22 files changed, 1585 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8706e6a..ea94c99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,7 +89,7 @@
         <!-- Don't change this version without also changing the shiro-quartz and shiro-features
              modules' OSGi metadata: -->
         <quartz.version>1.6.1</quartz.version>
-        <slf4j.version>1.6.4</slf4j.version>
+        <slf4j.version>1.7.21</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>
@@ -211,6 +211,11 @@
         <pluginManagement>
             <plugins>
                 <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-war-plugin</artifactId>
+                    <version>3.0.0</version>
+                </plugin>
+                <plugin>
                     <groupId>org.apache.felix</groupId>
                     <artifactId>maven-bundle-plugin</artifactId>
                     <version>2.1.0</version>
@@ -619,6 +624,11 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.shiro</groupId>
+                <artifactId>shiro-jaxrs</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shiro</groupId>
                 <artifactId>shiro-all</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -692,6 +702,11 @@
                 <version>${crowd.version}</version>
             </dependency>
             <dependency>
+                <groupId>ch.qos.logback</groupId>
+                <artifactId>logback-classic</artifactId>
+                <version>1.1.7</version>
+            </dependency>
+            <dependency>
                 <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-api</artifactId>
                 <version>${slf4j.version}</version>

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/pom.xml
----------------------------------------------------------------------
diff --git a/samples/jaxrs/pom.xml b/samples/jaxrs/pom.xml
new file mode 100644
index 0000000..c2ef72f
--- /dev/null
+++ b/samples/jaxrs/pom.xml
@@ -0,0 +1,204 @@
+<?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">
+
+    <parent>
+        <groupId>org.apache.shiro.samples</groupId>
+        <artifactId>shiro-samples</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>samples-jaxrs</artifactId>
+    <name>Apache Shiro :: Samples :: JAX-RS</name>
+    <packaging>war</packaging>
+
+
+    <properties>
+        <jetty.version>9.3.0.M1</jetty.version>
+    </properties>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.eclipse.jetty</groupId>
+                    <artifactId>jetty-maven-plugin</artifactId>
+                    <version>${jetty.version}</version>
+                    <configuration>
+                        <contextPath>/</contextPath>
+                        <httpConnector>
+                            <port>9080</port>
+                            <idleTimeout>60000</idleTimeout>
+                        </httpConnector>
+                        <requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
+                            <filename>./target/yyyy_mm_dd.request.log</filename>
+                            <retainDays>90</retainDays>
+                            <append>true</append>
+                            <extended>false</extended>
+                            <logTimeZone>GMT</logTimeZone>
+                        </requestLog>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <forkMode>never</forkMode>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-servlet-plugin</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-jaxrs</artifactId>
+        </dependency>
+
+        <dependency>
+            <!-- Required for any libraries that expect to call the commons logging APIs -->
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <version>0.4.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.jayway.restassured</groupId>
+            <artifactId>rest-assured</artifactId>
+            <version>2.8.0</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>jersey</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <properties>
+                <jersey.version>2.23.2</jersey.version>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.glassfish.jersey.containers</groupId>
+                    <artifactId>jersey-container-grizzly2-servlet</artifactId>
+                    <version>${jersey.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>resteasy</id>
+            <properties>
+                <resteasy.version>3.0.19.Final</resteasy.version>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-jaxrs</artifactId>
+                    <version>${resteasy.version}</version>
+                </dependency>
+
+                <dependency>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-servlet-initializer</artifactId>
+                    <version>${resteasy.version}</version>
+                </dependency>
+
+                <dependency>
+                    <groupId>org.jboss.resteasy</groupId>
+                    <artifactId>resteasy-jackson2-provider</artifactId>
+                    <version>${resteasy.version}</version>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>cxf</id>
+            <properties>
+                <cxf.version>3.1.7</cxf.version>
+            </properties>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.cxf</groupId>
+                    <artifactId>cxf-rt-rs-http-sci</artifactId>
+                    <version>${cxf.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.cxf</groupId>
+                    <artifactId>cxf-rt-frontend-jaxws</artifactId>
+                    <version>${cxf.version}</version>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.eclipse.jetty</groupId>
+                        <artifactId>jetty-maven-plugin</artifactId>
+                        <configuration>
+                            <webApp>
+                                <descriptor>src/main/webapp/WEB-INF/web.cxf.xml</descriptor>
+                            </webApp>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-war-plugin</artifactId>
+                        <configuration>
+                            <webXml>src/main/webapp/WEB-INF/web.cxf.xml</webXml>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/SampleApplication.java
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/SampleApplication.java b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/SampleApplication.java
new file mode 100644
index 0000000..9400af0
--- /dev/null
+++ b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/SampleApplication.java
@@ -0,0 +1,50 @@
+/*
+ * 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.sample.jaxrs;
+
+import org.apache.shiro.sample.jaxrs.resources.HelloResource;
+import org.apache.shiro.sample.jaxrs.resources.SecureResource;
+import org.apache.shiro.web.jaxrs.ShiroFeature;
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Simple JAX-RS {@link Application} that is implementation agnostic.
+ * @since 1.4
+ */
+@ApplicationPath("/")
+public class SampleApplication extends Application {
+
+    @Override
+    public Set<Class<?>> getClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+
+        // register Shiro
+        classes.add(ShiroFeature.class);
+
+        // register resources
+        classes.add(HelloResource.class);
+        classes.add(SecureResource.class);
+
+        return classes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/HelloResource.java
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/HelloResource.java b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/HelloResource.java
new file mode 100644
index 0000000..458fda5
--- /dev/null
+++ b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/HelloResource.java
@@ -0,0 +1,37 @@
+/*
+ * 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.sample.jaxrs.resources;
+
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+@Path("say")
+public class HelloResource {
+
+
+    @Produces({"application/json","plain/text"})
+    @GET
+    public String saySomething(@QueryParam("words") @DefaultValue("Hello!") String words) {
+        return words;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/SecureResource.java
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/SecureResource.java b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/SecureResource.java
new file mode 100644
index 0000000..59650ee
--- /dev/null
+++ b/samples/jaxrs/src/main/java/org/apache/shiro/sample/jaxrs/resources/SecureResource.java
@@ -0,0 +1,75 @@
+/*
+ * 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.sample.jaxrs.resources;
+
+
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresGuest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.authz.annotation.RequiresUser;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+
+@Path("secure")
+@Produces({"application/json","plain/text"})
+public class SecureResource {
+
+
+    @RequiresPermissions("lightsaber:requiresPermissions")
+    @Path("RequiresPermissions")
+    @GET
+    public String protectedByRequiresPermissions() {
+        return "protected";
+    }
+
+    @RequiresRoles("admin")
+    @Path("RequiresRoles")
+    @GET
+    public String protectedByRequiresRoles() {
+        return "protected";
+    }
+
+    @RequiresUser
+    @Path("RequiresUser")
+    @GET
+    public String protectedByRequiresUser() {
+        return "protected";
+    }
+
+    @RequiresGuest
+    @Path("RequiresGuest")
+    @GET
+    public String protectedByRequiresGuest() {
+        return "not protected";
+    }
+
+    @RequiresAuthentication
+    @Path("RequiresAuthentication")
+    @GET
+    public String protectedByRequiresAuthentication() {
+        return "protected";
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/resources/logback.xml
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/resources/logback.xml b/samples/jaxrs/src/main/resources/logback.xml
new file mode 100644
index 0000000..a627407
--- /dev/null
+++ b/samples/jaxrs/src/main/resources/logback.xml
@@ -0,0 +1,33 @@
+<?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.
+  -->
+<configuration>
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+    </root>
+
+    <logger name="org.apache.shiro.web.jaxrs" level="DEBUG"/>
+</configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/resources/shiro.ini
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/resources/shiro.ini b/samples/jaxrs/src/main/resources/shiro.ini
new file mode 100644
index 0000000..54fa949
--- /dev/null
+++ b/samples/jaxrs/src/main/resources/shiro.ini
@@ -0,0 +1,43 @@
+#
+# 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.
+
+[main]
+cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
+
+sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
+sessionManager.sessionIdUrlRewritingEnabled = false
+
+securityManager.sessionManager = $sessionManager
+securityManager.cacheManager = $cacheManager
+
+[urls]
+/** = authcBasic[permissive]
+
+[users]
+# format: username = password, role1, role2, ..., roleN
+root = secret,admin
+guest = guest,guest
+presidentskroob = 12345,president
+darkhelmet = ludicrousspeed,darklord,schwartz
+lonestarr = vespa,goodguy,schwartz
+
+[roles]
+# format: roleName = permission1, permission2, ..., permissionN
+admin = *
+schwartz = lightsaber:*
+goodguy = winnebago:drive:eagle5

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/main/webapp/WEB-INF/web.cxf.xml
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/main/webapp/WEB-INF/web.cxf.xml b/samples/jaxrs/src/main/webapp/WEB-INF/web.cxf.xml
new file mode 100644
index 0000000..f39600f
--- /dev/null
+++ b/samples/jaxrs/src/main/webapp/WEB-INF/web.cxf.xml
@@ -0,0 +1,41 @@
+<?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.
+  -->
+
+<web-app version="3.1"
+         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
+
+    <servlet>
+        <servlet-name>CXFServlet</servlet-name>
+        <display-name>CXF Servlet</display-name>
+        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.apache.shiro.sample.jaxrs.SampleApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CXFServlet</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy b/samples/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
new file mode 100644
index 0000000..6fb66c0
--- /dev/null
+++ b/samples/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ContainerIntegrationIT.groovy
@@ -0,0 +1,132 @@
+/*
+ * 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.web.jaxrs
+
+import org.junit.Test;
+
+import static com.jayway.restassured.RestAssured.*
+import static org.hamcrest.Matchers.*
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Test
+    void testNoAuthResource() {
+
+        get(getBaseUri() + "say")
+            .then()
+                .assertThat()
+                .statusCode(is(200)).and()
+                .body(equalTo("Hello!"))
+    }
+
+    @Test
+    void testSecuredRequiresAuthentication() {
+
+        get(getBaseUri() + "secure/RequiresAuthentication")
+            .then()
+                .assertThat().statusCode(is(401))
+
+        given()
+            .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresAuthentication")
+        .then()
+            .assertThat()
+                .statusCode(is(200)).and()
+                .body(equalTo("protected"))
+    }
+
+    @Test
+    void testSecuredRequiresUser() {
+
+        get(getBaseUri() + "secure/RequiresUser")
+            .then()
+                .assertThat().statusCode(is(401))
+
+        given()
+            .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresUser")
+        .then()
+            .assertThat()
+                .statusCode(is(200)).and()
+                .body(equalTo("protected"))
+    }
+
+    @Test
+    void testSecuredRequiresRoles() {
+
+        get(getBaseUri() + "secure/RequiresRoles")
+            .then()
+                .assertThat().statusCode(is(401))
+
+        given()
+                .header("Authorization", getBasicAuthorizationHeaderValue("guest", "guest"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresRoles")
+        .then()
+            .assertThat()
+                .statusCode(is(403)).and()
+
+        given()
+            .header("Authorization", getBasicAuthorizationHeaderValue("root", "secret"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresRoles")
+        .then()
+            .assertThat()
+                .statusCode(is(200)).and()
+                .body(equalTo("protected"))
+    }
+
+    @Test
+    void testSecuredRequiresPermissions() {
+
+        get(getBaseUri() + "secure/RequiresPermissions")
+            .then()
+                .assertThat().statusCode(is(401))
+
+        given()
+            .header("Authorization", getBasicAuthorizationHeaderValue("guest", "guest"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresPermissions")
+        .then()
+            .assertThat()
+                .statusCode(is(403)).and()
+
+        given()
+            .header("Authorization", getBasicAuthorizationHeaderValue("lonestarr", "vespa"))
+        .when()
+            .get(getBaseUri() + "secure/RequiresPermissions")
+        .then()
+            .assertThat()
+                .statusCode(is(200)).and()
+                .body(equalTo("protected"))
+    }
+
+    @Test
+    void testSecuredRequiresGuest() {
+
+        get(getBaseUri() + "secure/RequiresGuest")
+            .then()
+                .assertThat()
+                    .statusCode(is(200)).and()
+                    .body(equalTo("not protected"))
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/jaxrs/src/test/java/org/apache/shiro/web/jaxrs/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/samples/jaxrs/src/test/java/org/apache/shiro/web/jaxrs/AbstractContainerIT.java b/samples/jaxrs/src/test/java/org/apache/shiro/web/jaxrs/AbstractContainerIT.java
new file mode 100644
index 0000000..192f9e3
--- /dev/null
+++ b/samples/jaxrs/src/test/java/org/apache/shiro/web/jaxrs/AbstractContainerIT.java
@@ -0,0 +1,148 @@
+/*
+ * 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.web.jaxrs;
+
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.apache.shiro.codec.Base64;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.UnsupportedEncodingException;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    private static EmbeddedJetty jetty;
+
+    private static int port = 0;
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+        port = jetty.getPort();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + port + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+
+    protected static String getBasicAuthorizationHeaderValue(String username, String password) throws UnsupportedEncodingException {
+        String authorizationHeader = username + ":" + password;
+        byte[] valueBytes;
+        valueBytes = authorizationHeader.getBytes("UTF-8");
+        authorizationHeader = new String(Base64.encode(valueBytes));
+        return "Basic " + authorizationHeader;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 29c5369..7bd9e83 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -43,6 +43,7 @@
         <module>guice</module>
         <module>quickstart-guice</module>
         <module>servlet-plugin</module>
+        <module>jaxrs</module>
     </modules>
 
     <reporting>

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/pom.xml
----------------------------------------------------------------------
diff --git a/support/jaxrs/pom.xml b/support/jaxrs/pom.xml
new file mode 100644
index 0000000..0c51641
--- /dev/null
+++ b/support/jaxrs/pom.xml
@@ -0,0 +1,62 @@
+<?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-jaxrs</artifactId>
+    <name>Apache Shiro :: Support :: JAX-RS</name>
+    <packaging>jar</packaging>
+
+
+    <dependencies>
+
+        <!-- Shiro Deps -->
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+
+        <!-- Test Deps -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/AnnotationAuthorizationFilter.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/AnnotationAuthorizationFilter.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/AnnotationAuthorizationFilter.java
new file mode 100644
index 0000000..14c9183
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/AnnotationAuthorizationFilter.java
@@ -0,0 +1,82 @@
+/*
+ * 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.web.jaxrs;
+
+
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresGuest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.authz.annotation.RequiresUser;
+import org.apache.shiro.authz.aop.AuthenticatedAnnotationHandler;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
+import org.apache.shiro.authz.aop.GuestAnnotationHandler;
+import org.apache.shiro.authz.aop.PermissionAnnotationHandler;
+import org.apache.shiro.authz.aop.RoleAnnotationHandler;
+import org.apache.shiro.authz.aop.UserAnnotationHandler;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A filter that grants or denies access to a JAX-RS resource based on the Shiro annotations on it.
+ *
+ * @see org.apache.shiro.authz.annotation
+ * @since 1.4
+ */
+public class AnnotationAuthorizationFilter implements ContainerRequestFilter {
+
+    private final Map<AuthorizingAnnotationHandler, Annotation> authzChecks;
+
+    public AnnotationAuthorizationFilter(Collection<Annotation> authzSpecs) {
+        Map<AuthorizingAnnotationHandler, Annotation> authChecks = new HashMap<AuthorizingAnnotationHandler, Annotation>(authzSpecs.size());
+        for (Annotation authSpec : authzSpecs) {
+            authChecks.put(createHandler(authSpec), authSpec);
+        }
+        this.authzChecks = Collections.unmodifiableMap(authChecks);
+    }
+
+    private static AuthorizingAnnotationHandler createHandler(Annotation annotation) {
+        Class<?> t = annotation.annotationType();
+        if (RequiresPermissions.class.equals(t)) return new PermissionAnnotationHandler();
+        else if (RequiresRoles.class.equals(t)) return new RoleAnnotationHandler();
+        else if (RequiresUser.class.equals(t)) return new UserAnnotationHandler();
+        else if (RequiresGuest.class.equals(t)) return new GuestAnnotationHandler();
+        else if (RequiresAuthentication.class.equals(t)) return new AuthenticatedAnnotationHandler();
+        else throw new IllegalArgumentException("Cannot create a handler for the unknown for annotation " + t);
+    }
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+
+        for (Map.Entry<AuthorizingAnnotationHandler, Annotation> authzCheck : authzChecks.entrySet()) {
+            AuthorizingAnnotationHandler handler = authzCheck.getKey();
+            Annotation authzSpec = authzCheck.getValue();
+            handler.assertAuthorized(authzSpec);
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ExceptionMapper.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ExceptionMapper.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ExceptionMapper.java
new file mode 100644
index 0000000..ec6fb64
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ExceptionMapper.java
@@ -0,0 +1,48 @@
+/*
+ * 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.web.jaxrs;
+
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.UnauthorizedException;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+/**
+ * JAX-RS exception mapper used to map Shiro {@link AuthorizationExceptions} to HTTP status codes.
+ * {@link UnauthorizedException} will be mapped to 403, all others 401.
+ * @since 1.4
+ */
+public class ExceptionMapper implements javax.ws.rs.ext.ExceptionMapper<AuthorizationException> {
+
+    @Override
+    public Response toResponse(AuthorizationException exception) {
+
+        Status status;
+
+        if (exception instanceof UnauthorizedException) {
+            status = Status.FORBIDDEN;
+        } else {
+            status = Status.UNAUTHORIZED;
+        }
+
+        return Response.status(status).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroAnnotationFilterFeature.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroAnnotationFilterFeature.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroAnnotationFilterFeature.java
new file mode 100644
index 0000000..9d23b7b
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroAnnotationFilterFeature.java
@@ -0,0 +1,71 @@
+/*
+ * 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.web.jaxrs;
+
+
+import org.apache.shiro.authz.annotation.RequiresAuthentication;
+import org.apache.shiro.authz.annotation.RequiresGuest;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.apache.shiro.authz.annotation.RequiresRoles;
+import org.apache.shiro.authz.annotation.RequiresUser;
+import org.apache.shiro.web.filter.authz.AuthorizationFilter;
+
+import javax.ws.rs.Priorities;
+import javax.ws.rs.container.DynamicFeature;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.FeatureContext;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Wraps {@link AuthorizationFilter filters} around JAX-RS resources that are annotated with Shiro annotations.
+ * @since 1.4
+ */
+public class ShiroAnnotationFilterFeature implements DynamicFeature {
+
+    private static List<Class<? extends Annotation>> shiroAnnotations = Collections.unmodifiableList(Arrays.asList(
+            RequiresPermissions.class,
+            RequiresRoles.class,
+            RequiresAuthentication.class,
+            RequiresUser.class,
+            RequiresGuest.class));
+
+    @Override
+    public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+
+        List<Annotation> authzSpecs = new ArrayList<Annotation>();
+
+        for (Class<? extends Annotation> annotationClass : shiroAnnotations) {
+            // XXX What is the performance of getAnnotation vs getAnnotations?
+            Annotation classAuthzSpec = resourceInfo.getResourceClass().getAnnotation(annotationClass);
+            Annotation methodAuthzSpec = resourceInfo.getResourceMethod().getAnnotation(annotationClass);
+
+            if (classAuthzSpec != null) authzSpecs.add(classAuthzSpec);
+            if (methodAuthzSpec != null) authzSpecs.add(methodAuthzSpec);
+        }
+
+        if (!authzSpecs.isEmpty()) {
+            context.register(new AnnotationAuthorizationFilter(authzSpecs), Priorities.AUTHORIZATION);
+        }
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroFeature.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroFeature.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroFeature.java
new file mode 100644
index 0000000..0a4718b
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroFeature.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.web.jaxrs;
+
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Feature;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.Provider;
+
+
+/**
+ * Shiro JAX-RS feature which includes {@link ExceptionMapper}, {@link SubjectPrincipalRequestFilter}, and
+ * {@link ShiroAnnotationFilterFeature}.
+ *
+ * Typically a JAX-RS {@link Application} class will include this Feature class in the
+ * classes returned from {@link Application#getClasses()} method, for example:
+ * <blockquote><pre>
+ *     public class SampleApplication extends Application {
+ *
+ *         @Override
+ *         public Set<Class<?>> getClasses() {
+ *             Set<Class<?>> classes = new HashSet<Class<?>>();
+ *
+ *             // register Shiro
+ *             classes.add(ShiroFeature.class);
+ *             ...
+ *             return classes;
+ *         }
+ *     }
+ * </pre></blockquote>
+ * @since 1.4
+ */
+@Provider // NOTE: Apache CXF requires this annotation on this feature (jersey and resteasy do not)
+public class ShiroFeature implements Feature {
+
+    @Override
+    public boolean configure(FeatureContext context) {
+
+        context.register(ExceptionMapper.class);
+        context.register(SubjectPrincipalRequestFilter.class);
+        context.register(ShiroAnnotationFilterFeature.class);
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
new file mode 100644
index 0000000..867ce48
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/ShiroSecurityContext.java
@@ -0,0 +1,121 @@
+/*
+ * 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.web.jaxrs;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.PrincipalCollection;
+import org.apache.shiro.subject.Subject;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.SecurityContext;
+import java.security.Principal;
+
+/**
+ * A Shiro based {@link SecurityContext} that exposes the current Shiro {@link Subject} as a {@link Principal}.
+ * The {@link #isUserInRole(String)} method returns the result of {@link Subject#hasRole(String)}.
+ *
+ * @since 1.4
+ */
+public class ShiroSecurityContext implements SecurityContext {
+
+    final private ContainerRequestContext containerRequestContext;
+
+    public ShiroSecurityContext(ContainerRequestContext containerRequestContext) {
+        this.containerRequestContext = containerRequestContext;
+    }
+
+    @Override
+    public Principal getUserPrincipal() {
+
+        Principal result;
+
+        Subject subject = getSubject();
+        PrincipalCollection shiroPrincipals = subject.getPrincipals();
+        if (shiroPrincipals != null) {
+            result = shiroPrincipals.oneByType(Principal.class);
+
+            if (result == null) {
+                result = new ObjectPrincipal(shiroPrincipals.getPrimaryPrincipal());
+            }
+        }
+        else {
+            result = containerRequestContext.getSecurityContext().getUserPrincipal();
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean isUserInRole(String role) {
+        return getSubject().hasRole(role);
+    }
+
+    @Override
+    public boolean isSecure() {
+        return containerRequestContext.getSecurityContext().isSecure();
+    }
+
+    @Override
+    public String getAuthenticationScheme() {
+        return containerRequestContext.getSecurityContext().getAuthenticationScheme();
+    }
+
+    private Subject getSubject() {
+        return SecurityUtils.getSubject();
+    }
+
+
+    /**
+     * Java Principal wrapper around any Shiro Principal object.s
+     */
+    private class ObjectPrincipal implements Principal {
+        private Object object = null;
+
+        public ObjectPrincipal(Object object) {
+            this.object = object;
+        }
+
+        public Object getObject() {
+            return object;
+        }
+
+        public String getName() {
+            return getObject().toString();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ObjectPrincipal that = (ObjectPrincipal) o;
+
+            return object.equals(that.object);
+
+        }
+
+        public int hashCode() {
+            return object.hashCode();
+        }
+
+        public String toString() {
+            return object.toString();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilter.java
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilter.java b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilter.java
new file mode 100644
index 0000000..4be8aba
--- /dev/null
+++ b/support/jaxrs/src/main/java/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.web.jaxrs;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+
+/**
+ * A {@link ContainerRequestFilter} that replaces the {@link javax.ws.rs.core.SecurityContext}
+ * with a {@link ShiroSecurityContext}.
+ * @since 1.4
+ */
+@Provider
+@PreMatching
+public class SubjectPrincipalRequestFilter implements ContainerRequestFilter {
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        requestContext.setSecurityContext(new ShiroSecurityContext(requestContext));
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
new file mode 100644
index 0000000..8aa3c18
--- /dev/null
+++ b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
@@ -0,0 +1,64 @@
+/*
+ * 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.web.jaxrs
+
+import org.apache.shiro.authz.AuthorizationException
+import org.apache.shiro.authz.UnauthorizedException
+import org.junit.Test
+
+import javax.ws.rs.core.Response
+import javax.ws.rs.ext.RuntimeDelegate
+
+import static org.junit.Assert.*
+import static org.easymock.EasyMock.*
+
+/**
+ * Tests for {@link ExceptionMapper}.
+ * @since 1.4
+ */
+class ExceptionMapperTest {
+
+    @Test
+    void testUnauthorizedException() {
+
+        doTest(new UnauthorizedException("expected test exception."), Response.Status.FORBIDDEN)
+        doTest(new AuthorizationException("expected test exception."), Response.Status.UNAUTHORIZED)
+        doTest(null, Response.Status.UNAUTHORIZED)
+    }
+
+    private void doTest(AuthorizationException exception , Response.StatusType expectedStatus) {
+        def runtimeDelegate = strictMock(RuntimeDelegate)
+
+        RuntimeDelegate.setInstance(runtimeDelegate)
+
+        def responseBuilder = strictMock(Response.ResponseBuilder)
+        def response = strictMock(Response)
+
+        expect(runtimeDelegate.createResponseBuilder()).andReturn(responseBuilder).anyTimes()
+        expect(responseBuilder.status((Response.StatusType) expectedStatus)).andReturn(responseBuilder)
+        expect(responseBuilder.build()).andReturn(response)
+
+        replay runtimeDelegate, responseBuilder
+
+        def responseResult = new ExceptionMapper().toResponse(exception)
+        assertSame response, responseResult
+
+        verify runtimeDelegate, responseBuilder
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ShiroSecurityContextTest.groovy
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ShiroSecurityContextTest.groovy b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ShiroSecurityContextTest.groovy
new file mode 100644
index 0000000..5d7e947
--- /dev/null
+++ b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ShiroSecurityContextTest.groovy
@@ -0,0 +1,204 @@
+/*
+ * 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.web.jaxrs
+
+import org.apache.shiro.subject.SimplePrincipalCollection
+import org.apache.shiro.subject.Subject
+import org.apache.shiro.util.ThreadContext
+import org.junit.After
+import org.junit.Test
+
+import javax.ws.rs.container.ContainerRequestContext
+import javax.ws.rs.core.SecurityContext
+import java.security.Principal
+
+import static org.easymock.EasyMock.*
+import static org.junit.Assert.*
+
+/**
+ * Tests for {@link ShiroSecurityContext}.
+ * @since 1.4
+ */
+class ShiroSecurityContextTest {
+
+    @Test
+    void testIsSecure() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(originalSecurityContext.isSecure()).andReturn(true)
+        replay requestContext, originalSecurityContext
+
+        assertTrue shrioContext.isSecure()
+
+        verify requestContext, originalSecurityContext
+    }
+
+    @Test
+    void testGetAuthenticationScheme() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(originalSecurityContext.getAuthenticationScheme()).andReturn("https")
+        replay requestContext, originalSecurityContext
+
+        assertEquals "https", shrioContext.getAuthenticationScheme()
+
+        verify requestContext, originalSecurityContext
+    }
+
+    @Test
+    void testGetUserPrincipalWithString() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.getPrincipals()).andReturn(new SimplePrincipalCollection("TestUser", "realm"))
+
+        replay requestContext, originalSecurityContext, subject
+
+        def resultPrincipal = shrioContext.getUserPrincipal()
+        assertSame "TestUser", resultPrincipal.getName()
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @Test
+    void testGetUserPrincipalNoPrincipal() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.getPrincipals()).andReturn(null)
+        expect(originalSecurityContext.getUserPrincipal()).andReturn(null)
+
+        replay requestContext, originalSecurityContext, subject
+
+        assertNull shrioContext.getUserPrincipal()
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @Test
+    void testGetUserPrincipalPrincipalObject() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.getPrincipals()).andReturn(new SimplePrincipalCollection(new TestPrincipal("Tester"), "test-realm"))
+
+        replay requestContext, originalSecurityContext, subject
+
+        def resultPrincipal = shrioContext.getUserPrincipal()
+        assertSame "Tester", resultPrincipal.getName()
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @Test
+    void testUserInRoleTrue() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.hasRole("test-role")).andReturn(true)
+
+        replay requestContext, originalSecurityContext, subject
+
+        assertTrue shrioContext.isUserInRole("test-role")
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @Test
+    void testUserInRoleFalse() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.hasRole("test-role")).andReturn(false)
+
+        replay requestContext, originalSecurityContext, subject
+
+        assertFalse shrioContext.isUserInRole("test-role")
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @Test
+    void testPrincipalEquals() {
+        def requestContext = mock(ContainerRequestContext)
+        def originalSecurityContext = mock(SecurityContext)
+        def shrioContext = new ShiroSecurityContext(requestContext)
+        def subject = mock(Subject)
+        ThreadContext.bind(subject)
+
+        expect(requestContext.getSecurityContext()).andReturn(originalSecurityContext).anyTimes()
+        expect(subject.getPrincipals()).andReturn(new SimplePrincipalCollection("Tester", "test-realm"))
+        expect(subject.getPrincipals()).andReturn(new SimplePrincipalCollection("Tester", "test-realm"))
+
+        replay requestContext, originalSecurityContext, subject
+
+        def result1Principal = shrioContext.getUserPrincipal()
+        def result2Principal = shrioContext.getUserPrincipal()
+
+        assertEquals result1Principal, result2Principal
+        assertNotSame result1Principal, result2Principal
+
+        verify requestContext, originalSecurityContext, subject
+    }
+
+    @After
+    void cleanUp() {
+        ThreadContext.remove()
+    }
+
+    class TestPrincipal implements Principal {
+
+        final String name;
+
+        TestPrincipal(String name) {
+            this.name = name
+        }
+
+        @Override
+        String getName() {
+            return name
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
----------------------------------------------------------------------
diff --git a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
new file mode 100644
index 0000000..7ae75cd
--- /dev/null
+++ b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/SubjectPrincipalRequestFilterTest.groovy
@@ -0,0 +1,50 @@
+/*
+ * 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.web.jaxrs
+
+import org.easymock.Capture
+import org.junit.Test
+
+import javax.ws.rs.container.ContainerRequestContext
+
+import static org.easymock.EasyMock.*
+import static org.junit.Assert.*
+
+/**
+ * Tests for {@link SubjectPrincipalRequestFilter}.
+ * @since 1.4
+ */
+class SubjectPrincipalRequestFilterTest {
+
+    @Test
+    void testWrapContext() {
+        def filter = new SubjectPrincipalRequestFilter()
+
+        def contextCapture = new Capture<ShiroSecurityContext>()
+        def requestContext = mock(ContainerRequestContext)
+        expect(requestContext.setSecurityContext(capture(contextCapture)))
+        replay requestContext
+
+        filter.filter(requestContext)
+
+        verify requestContext
+        assertSame requestContext, contextCapture.value.containerRequestContext
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/4bf2e4ed/support/pom.xml
----------------------------------------------------------------------
diff --git a/support/pom.xml b/support/pom.xml
index 9f12c69..8886f02 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -42,6 +42,7 @@
         <module>cas</module>
         <module>spring-boot</module>
         <module>servlet-plugin</module>
+        <module>jaxrs</module>
     </modules>
 
 </project>


[13/20] shiro git commit: SHIRO-501 - Add support for String interpolation

Posted by bd...@apache.org.
SHIRO-501 - Add support for String interpolation

If the optional dependency 'commons-configuration2' is on the classpath String interpolation will be available.
String prefixes 'sys', 'env' and 'const' which provide system properties, environment variables, and field constants respectively.


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

Branch: refs/heads/1.4.x
Commit: f48a8de807c8a42433585fdc2cbc544b244c33d2
Parents: d890bb3
Author: Brian Demers <bd...@apache.org>
Authored: Mon Oct 3 12:22:30 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 core/pom.xml                                    |  6 ++
 .../shiro/config/CommonsInterpolator.java       | 72 ++++++++++++++++++++
 .../shiro/config/DefaultInterpolator.java       | 39 +++++++++++
 .../org/apache/shiro/config/Interpolator.java   | 35 ++++++++++
 .../apache/shiro/config/ReflectionBuilder.java  | 17 ++++-
 .../shiro/config/CommonsInterpolatorTest.groovy | 57 ++++++++++++++++
 .../shiro/config/DefaultInterpolatorTest.groovy | 48 +++++++++++++
 .../shiro/config/ReflectionBuilderTest.groovy   | 58 ++++++++++++++++
 .../org/apache/shiro/config/SimpleBean.java     |  9 +++
 pom.xml                                         | 14 ++++
 10 files changed, 354 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 79f67fa..df61785 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -80,6 +80,12 @@
         </dependency>
         -->
 
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-configuration2</artifactId>
+            <optional>true</optional>
+        </dependency>
+
         <!-- Test dependencies -->
         <dependency>
             <groupId>org.slf4j</groupId>

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java b/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
new file mode 100644
index 0000000..0d1c7fc
--- /dev/null
+++ b/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
@@ -0,0 +1,72 @@
+/*
+ * 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.config;
+
+import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
+import org.apache.commons.configuration2.interpol.ConstantLookup;
+import org.apache.commons.configuration2.interpol.EnvironmentLookup;
+import org.apache.commons.configuration2.interpol.SystemPropertiesLookup;
+
+/**
+ * Commons-Config interpolation wrapper. This implementation uses a {@link ConfigurationInterpolator} with the default
+ * lookup: <code>sys</code> (system properties), <code>env</code> (environment variables>, and <code>const</code> (constants).
+ *
+ * <table>
+ *     <tr>
+ *         <th>lookup</th>
+ *         <th>example</th>
+ *         <th>value</th>
+ *     </tr>
+ *     <tr>
+ *         <td>sys</td>
+ *         <td>${sys:os.name}</td>
+ *         <td>mac os x</td>
+ *     </tr>
+ *     <tr>
+ *         <td>env</td>
+ *         <td>${env:EDITOR}</td>
+ *         <td>vi</td>
+ *     </tr>
+ *     <tr>
+ *         <td>const</td>
+ *         <td>${const:java.awt.event.KeyEvent.VK_ENTER}</td>
+ *         <td>\n</td>
+ *     </tr>
+ * </table>
+ *
+ * @see ConfigurationInterpolator
+ * @since 1.4
+ */
+public class CommonsInterpolator implements Interpolator {
+
+    final private ConfigurationInterpolator interpolator;
+
+    public CommonsInterpolator() {
+        this.interpolator = new ConfigurationInterpolator();
+
+        interpolator.registerLookup("const", new ConstantLookup());
+        interpolator.addDefaultLookup(new SystemPropertiesLookup());
+        interpolator.addDefaultLookup(new EnvironmentLookup());
+    }
+
+    @Override
+    public String interpolate(String value) {
+        return (String) interpolator.interpolate(value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/main/java/org/apache/shiro/config/DefaultInterpolator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/DefaultInterpolator.java b/core/src/main/java/org/apache/shiro/config/DefaultInterpolator.java
new file mode 100644
index 0000000..8addd2f
--- /dev/null
+++ b/core/src/main/java/org/apache/shiro/config/DefaultInterpolator.java
@@ -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.
+ */
+package org.apache.shiro.config;
+
+/**
+ * This {@link Interpolator} simply returns the original value.  This is implementation is useful when interpolation
+ * is not desired.
+ *
+ * @since 1.4
+ */
+public class DefaultInterpolator implements Interpolator {
+
+    /**
+     * Simply returns the original <code>value</code>.
+     *
+     * @param value value to be interpolated.
+     * @return Simply returns the original <code>value</code>.
+     */
+    @Override
+    public String interpolate(String value) {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/main/java/org/apache/shiro/config/Interpolator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/Interpolator.java b/core/src/main/java/org/apache/shiro/config/Interpolator.java
new file mode 100644
index 0000000..0de933e
--- /dev/null
+++ b/core/src/main/java/org/apache/shiro/config/Interpolator.java
@@ -0,0 +1,35 @@
+/*
+ * 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.config;
+
+/**
+ * Basic String interpolation interface.  Typically implementations will use the Maven/Ant like notation: ${key}, but
+ * This is up to the implementation.
+ *
+ * @since 1.4
+ */
+public interface Interpolator {
+
+    /**
+     * Interpolates <code>value</code> and returns the result.
+     * @param value the source text
+     * @return the String result of the interpolation, or <code>value</code>, if there was not change.
+     */
+    String interpolate(String value);
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java b/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
index d7f0d1a..9900459 100644
--- a/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
+++ b/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
@@ -83,6 +83,8 @@ public class ReflectionBuilder {
 
     private static final String EVENT_BUS_NAME = "eventBus";
 
+    private final Interpolator interpolator;
+
     private final Map<String, Object> objects;
     /**
      * @since 1.3
@@ -110,6 +112,9 @@ public class ReflectionBuilder {
     }
 
     public ReflectionBuilder(Map<String, ?> defaults) {
+
+        this.interpolator = createInterpolator();
+
         this.objects = createDefaultObjectMap();
         this.registeredEventSubscribers = new LinkedHashMap<String,Object>();
         apply(defaults);
@@ -247,7 +252,8 @@ public class ReflectionBuilder {
 
             for (Map.Entry<String, String> entry : kvPairs.entrySet()) {
                 String lhs = entry.getKey();
-                String rhs = entry.getValue();
+                String rhs = (String) interpolator.interpolate(entry.getValue());
+//                String rhs = entry.getValue();
 
                 String beanId = parseBeanId(lhs);
                 if (beanId != null) { //a beanId could be parsed, so the line is a bean instance definition
@@ -720,6 +726,15 @@ public class ReflectionBuilder {
         applyProperty(object, propertyName, value);
     }
 
+    private Interpolator createInterpolator() {
+
+        if (ClassUtils.isAvailable("org.apache.commons.configuration2.interpol.ConfigurationInterpolator")) {
+            return new CommonsInterpolator();
+        }
+
+        return new DefaultInterpolator();
+    }
+
     private class BeanConfigurationProcessor {
 
         private final List<Statement> statements = new ArrayList<Statement>();

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/test/groovy/org/apache/shiro/config/CommonsInterpolatorTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/groovy/org/apache/shiro/config/CommonsInterpolatorTest.groovy b/core/src/test/groovy/org/apache/shiro/config/CommonsInterpolatorTest.groovy
new file mode 100644
index 0000000..851aeb0
--- /dev/null
+++ b/core/src/test/groovy/org/apache/shiro/config/CommonsInterpolatorTest.groovy
@@ -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.config
+
+import org.junit.Test
+
+import static org.junit.Assert.*
+
+/**
+ * Tests for {@link CommonsInterpolator}.
+ * @since 1.4
+ */
+class CommonsInterpolatorTest {
+
+    @SuppressWarnings("unused")
+    public final static String TEST_ME = "success";
+
+    @Test
+    void testBasicOperation() {
+
+        def interpolator = new CommonsInterpolator();
+
+        assertNull interpolator.interpolate(null);
+
+        def sourceString = """
+            \${os.name}
+            \${foobar}
+            \${const:org.apache.shiro.config.CommonsInterpolatorTest.TEST_ME}
+            Some other text
+        """
+
+        def expectedResult = """
+            ${System.getProperty("os.name")}
+            \${foobar}
+            success
+            Some other text
+        """.toString()
+
+        assertEquals expectedResult, interpolator.interpolate(sourceString)
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/test/groovy/org/apache/shiro/config/DefaultInterpolatorTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/groovy/org/apache/shiro/config/DefaultInterpolatorTest.groovy b/core/src/test/groovy/org/apache/shiro/config/DefaultInterpolatorTest.groovy
new file mode 100644
index 0000000..4456068
--- /dev/null
+++ b/core/src/test/groovy/org/apache/shiro/config/DefaultInterpolatorTest.groovy
@@ -0,0 +1,48 @@
+/*
+ * 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.config
+
+import org.junit.Test
+
+import static org.junit.Assert.*
+
+/**
+ * Tests for {@link DefaultInterpolator}.
+ * @since 1.4
+ */
+public class DefaultInterpolatorTest {
+
+    @Test
+    void testBasicOperation() {
+
+        def interpolator = new DefaultInterpolator();
+
+        assertNull interpolator.interpolate(null);
+
+        def sourceString = """
+            \${sys:os.name}
+            \${foobar}
+            \${env:HOSTTYPE}
+            Some other text
+        """
+
+        assertSame sourceString, interpolator.interpolate(sourceString)
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy b/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
index 278efa2..44ec690 100644
--- a/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
+++ b/core/src/test/groovy/org/apache/shiro/config/ReflectionBuilderTest.groovy
@@ -27,6 +27,7 @@ import org.apache.shiro.util.CollectionUtils
 import org.junit.Test
 
 import static org.junit.Assert.*
+import static org.hamcrest.Matchers.*
 
 /**
  * Unit tests for the {@link ReflectionBuilder} implementation.
@@ -448,6 +449,63 @@ class ReflectionBuilderTest {
         assertDestroyedEvents("listenerTwo", objects, 3); //2 beans defined after it + its own destroyed event
     }
 
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    void testSimpleInterpolation() {
+
+        Map<String, String> defs = new LinkedHashMap<String, String>();
+        defs.put("simpleBeanFactory", "org.apache.shiro.config.SimpleBeanFactory");
+        defs.put("simpleBeanFactory.factoryInt", "5");
+        defs.put("simpleBeanFactory.factoryString", "\${os.name}");
+        defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+        defs.put("compositeBean.simpleBean", '$simpleBeanFactory');
+
+        ReflectionBuilder builder = new ReflectionBuilder();
+        Map objects = builder.buildObjects(defs);
+        assertFalse(CollectionUtils.isEmpty(objects));
+        CompositeBean compositeBean = (CompositeBean) objects.get("compositeBean");
+        SimpleBean bean = compositeBean.getSimpleBean();
+        assertNotNull(bean);
+        assertEquals(5, bean.getIntProp());
+        assertEquals(System.getProperty("os.name"), bean.getStringProp());
+
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    void testInterpolationForMapKeysAndLists() {
+
+        // using os.name and os.arch because they are available on every system
+
+        Map<String, String> defs = new LinkedHashMap<String, String>();
+        defs.put("simpleBean1", "org.apache.shiro.config.SimpleBean");
+        defs.put("simpleBean1.stringList", "\${os.name}, \${os.arch}");
+        defs.put("simpleBean2", "org.apache.shiro.config.SimpleBean");
+        defs.put("compositeBean", "org.apache.shiro.config.CompositeBean");
+        defs.put("compositeBean.simpleBeanMap", '\${os.name}:$simpleBean1, two:$simpleBean2');
+
+        ReflectionBuilder builder = new ReflectionBuilder();
+        Map objects = builder.buildObjects(defs);
+        assertFalse(CollectionUtils.isEmpty(objects));
+
+        CompositeBean compositeBean = (CompositeBean) objects.get("compositeBean");
+        assertNotNull(compositeBean);
+
+        def beanMap = compositeBean.getSimpleBeanMap()
+        assertNotNull(beanMap)
+        assertThat beanMap, allOf(hasKey(System.getProperty("os.name")), hasKey("two"), aMapWithSize(2))
+
+        def beanOne = beanMap.get(System.getProperty("os.name"))
+        assertThat beanOne.stringList, allOf(hasItem(System.getProperty("os.name")), hasItem(System.getProperty("os.arch")), hasSize(2))
+
+        assertNotNull(beanMap.get("two"))
+    }
+
     void assertInstantiatedEvents(String name, Map<String, ?> objects, int expected) {
         def bean = objects.get(name) as RecordingBeanListener
         def events = bean.getInstantiatedEvents()

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/core/src/test/java/org/apache/shiro/config/SimpleBean.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/shiro/config/SimpleBean.java b/core/src/test/java/org/apache/shiro/config/SimpleBean.java
index 03a3094..dd557c9 100644
--- a/core/src/test/java/org/apache/shiro/config/SimpleBean.java
+++ b/core/src/test/java/org/apache/shiro/config/SimpleBean.java
@@ -31,6 +31,7 @@ public class SimpleBean {
     private int intProp;
     private byte[] byteArrayProp = null;
 
+    private List<String> stringList;
     private List<SimpleBean> simpleBeans;
 
     public SimpleBean() {
@@ -79,4 +80,12 @@ public class SimpleBean {
     public void setSimpleBeans(List<SimpleBean> simpleBeans) {
         this.simpleBeans = simpleBeans;
     }
+
+    public List<String> getStringList() {
+        return stringList;
+    }
+
+    public void setStringList(List<String> stringList) {
+        this.stringList = stringList;
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/f48a8de8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1a3d9d6..69da491 100644
--- a/pom.xml
+++ b/pom.xml
@@ -670,6 +670,20 @@
                 <artifactId>aspectjweaver</artifactId>
                 <version>${aspectj.version}</version>
             </dependency>
+
+            <dependency>
+                <!-- optional dep for the reflection builder -->
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-configuration2</artifactId>
+                <version>2.1</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>commons-logging</groupId>
+                        <artifactId>commons-logging</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
             <dependency>
                 <!-- Used for Atlassian Crowd Realm - not required for the framework: -->
                 <groupId>com.atlassian.crowd</groupId>


[12/20] shiro git commit: SHIRO-445 - Expose get/set methods from IniWebEnvironment to ReflectionBuilder to allow configuring custom interpolation

Posted by bd...@apache.org.
SHIRO-445 - Expose get/set methods from IniWebEnvironment to ReflectionBuilder to allow configuring custom interpolation


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

Branch: refs/heads/1.4.x
Commit: a76b1ee9f3a45557d96cdd5e4abadd7a0e7640d0
Parents: 542a32e
Author: Brian Demers <bd...@apache.org>
Authored: Tue Oct 4 14:38:51 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 .../shiro/config/CommonsInterpolator.java       |  4 ++
 .../shiro/config/IniSecurityManagerFactory.java | 44 ++++++++++++++++----
 .../apache/shiro/config/ReflectionBuilder.java  | 20 +++++++--
 support/servlet-plugin/pom.xml                  | 23 +++++-----
 .../main/resources/META-INF/web-fragment.xml    | 22 ++++++----
 .../apache/shiro/web/env/IniWebEnvironment.java | 28 ++++++++++++-
 6 files changed, 108 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java b/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
index 0d1c7fc..03b472c 100644
--- a/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
+++ b/core/src/main/java/org/apache/shiro/config/CommonsInterpolator.java
@@ -69,4 +69,8 @@ public class CommonsInterpolator implements Interpolator {
     public String interpolate(String value) {
         return (String) interpolator.interpolate(value);
     }
+
+    public ConfigurationInterpolator getConfigurationInterpolator() {
+        return interpolator;
+    }
 }

http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java b/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
index 6ff6e64..9a0b609 100644
--- a/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
+++ b/core/src/main/java/org/apache/shiro/config/IniSecurityManagerFactory.java
@@ -59,9 +59,11 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
      * source will be resolved to use to build the instance.
      */
     public IniSecurityManagerFactory() {
+        this.builder = new ReflectionBuilder();
     }
 
     public IniSecurityManagerFactory(Ini config) {
+        this();
         setIni(config);
     }
 
@@ -74,13 +76,13 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
     }
 
     public void destroy() {
-        if(this.builder != null) {
-            builder.destroy();
+        if(getReflectionBuilder() != null) {
+            getReflectionBuilder().destroy();
         }
     }
 
     private SecurityManager getSecurityManagerBean() {
-        return builder.getBean(SECURITY_MANAGER_NAME, SecurityManager.class);
+        return getReflectionBuilder().getBean(SECURITY_MANAGER_NAME, SecurityManager.class);
     }
 
     protected SecurityManager createDefaultInstance() {
@@ -100,12 +102,17 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
     }
 
     private SecurityManager createSecurityManager(Ini ini) {
+        return createSecurityManager(ini, getConfigSection(ini));
+    }
+
+    private Ini.Section getConfigSection(Ini ini) {
+
         Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME);
         if (CollectionUtils.isEmpty(mainSection)) {
             //try the default:
             mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
         }
-        return createSecurityManager(ini, mainSection);
+        return mainSection;
     }
 
     protected boolean isAutoApplyRealms(SecurityManager securityManager) {
@@ -126,8 +133,8 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
     @SuppressWarnings({"unchecked"})
     private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
 
-        Map<String, ?> defaults = createDefaults(ini, mainSection);
-        Map<String, ?> objects = buildInstances(mainSection, defaults);
+        getReflectionBuilder().setObjects(createDefaults(ini, mainSection));
+        Map<String, ?> objects = buildInstances(mainSection);
 
         SecurityManager securityManager = getSecurityManagerBean();
 
@@ -168,9 +175,8 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
         return defaults;
     }
 
-    private Map<String, ?> buildInstances(Ini.Section section, Map<String, ?> defaults) {
-        this.builder = new ReflectionBuilder(defaults);
-        return this.builder.buildObjects(section);
+    private Map<String, ?> buildInstances(Ini.Section section) {
+        return getReflectionBuilder().buildObjects(section);
     }
 
     private void addToRealms(Collection<Realm> realms, RealmFactory factory) {
@@ -261,4 +267,24 @@ public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager
         realm.setIni(ini); //added for SHIRO-322
         return realm;
     }
+
+    /**
+     * Returns the ReflectionBuilder instance used to create SecurityManagers object graph.
+     * @return ReflectionBuilder instance used to create SecurityManagers object graph.
+     * @since 1.4
+     */
+    public ReflectionBuilder getReflectionBuilder() {
+        return builder;
+    }
+
+    /**
+     * Sets the ReflectionBuilder that will be used to create the SecurityManager based on the contents of
+     * the Ini configuration.
+     * @param builder The ReflectionBuilder used to parse the Ini configuration.
+     * @since 1.4
+     */
+    @SuppressWarnings("unused")
+    public void setReflectionBuilder(ReflectionBuilder builder) {
+        this.builder = builder;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java b/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
index 9900459..63d6d57 100644
--- a/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
+++ b/core/src/main/java/org/apache/shiro/config/ReflectionBuilder.java
@@ -83,9 +83,14 @@ public class ReflectionBuilder {
 
     private static final String EVENT_BUS_NAME = "eventBus";
 
-    private final Interpolator interpolator;
-
     private final Map<String, Object> objects;
+
+    /**
+     * Interpolation allows for ${key} substitution of values.
+     * @since 1.4
+     */
+    private Interpolator interpolator;
+
     /**
      * @since 1.3
      */
@@ -252,8 +257,7 @@ public class ReflectionBuilder {
 
             for (Map.Entry<String, String> entry : kvPairs.entrySet()) {
                 String lhs = entry.getKey();
-                String rhs = (String) interpolator.interpolate(entry.getValue());
-//                String rhs = entry.getValue();
+                String rhs = interpolator.interpolate(entry.getValue());
 
                 String beanId = parseBeanId(lhs);
                 if (beanId != null) { //a beanId could be parsed, so the line is a bean instance definition
@@ -735,6 +739,14 @@ public class ReflectionBuilder {
         return new DefaultInterpolator();
     }
 
+    /**
+     * Sets the {@link Interpolator} used when evaluating the right side of the expressions.
+     * @since 1.4
+     */
+    public void setInterpolator(Interpolator interpolator) {
+        this.interpolator = interpolator;
+    }
+
     private class BeanConfigurationProcessor {
 
         private final List<Statement> statements = new ArrayList<Statement>();

http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/support/servlet-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/support/servlet-plugin/pom.xml b/support/servlet-plugin/pom.xml
index 4087cce..4950cea 100644
--- a/support/servlet-plugin/pom.xml
+++ b/support/servlet-plugin/pom.xml
@@ -1,18 +1,21 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-  ~ Copyright 2012 Stormpath, Inc.
-  ~
-  ~ Licensed 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
+  ~ 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.
+  ~ 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">

http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
----------------------------------------------------------------------
diff --git a/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml b/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
index dd478c3..10c9673 100644
--- a/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
+++ b/support/servlet-plugin/src/main/resources/META-INF/web-fragment.xml
@@ -1,17 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~
-  ~ Licensed 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
+  ~ 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.
+  ~ 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.
   -->
 <web-fragment metadata-complete="true"
               xmlns="http://xmlns.jcp.org/xml/ns/javaee"

http://git-wip-us.apache.org/repos/asf/shiro/blob/a76b1ee9/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
index bff933a..6bef199 100644
--- a/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
+++ b/web/src/main/java/org/apache/shiro/web/env/IniWebEnvironment.java
@@ -54,6 +54,12 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
      */
     private Ini ini;
 
+    private WebIniSecurityManagerFactory factory;
+
+    public IniWebEnvironment() {
+        factory = new WebIniSecurityManagerFactory();
+    }
+
     /**
      * Initializes this instance by resolving any potential (explicit or resource-configured) {@link Ini}
      * configuration and calling {@link #configure() configure} for actual instance configuration.
@@ -273,7 +279,6 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
     }
 
     protected WebSecurityManager createWebSecurityManager() {
-        WebIniSecurityManagerFactory factory = new WebIniSecurityManagerFactory();
 
         Ini ini = getIni();
         if (!CollectionUtils.isEmpty(ini)) {
@@ -397,4 +402,25 @@ public class IniWebEnvironment extends ResourceBasedWebEnvironment implements In
         defaults.put(FILTER_CHAIN_RESOLVER_NAME, new IniFilterChainResolverFactory());
         return defaults;
     }
+
+    /**
+     * Returns the SecurityManager factory used by this WebEnvironment.
+     *
+     * @return the SecurityManager factory used by this WebEnvironment.
+     * @since 1.4
+     */
+    @SuppressWarnings("unused")
+    protected WebIniSecurityManagerFactory getSecurityManagerFactory() {
+        return factory;
+    }
+
+    /**
+     * Allows for setting the SecurityManager factory which will be used to create the SecurityManager.
+     *
+     * @param factory the SecurityManager factory to used.
+     * @since 1.4
+     */
+    protected void setSecurityManagerFactory(WebIniSecurityManagerFactory factory) {
+        this.factory = factory;
+    }
 }


[16/20] shiro git commit: SHIRO-591 - Allow BasicHttpAuthenticationFilter to be configured in permissive mode

Posted by bd...@apache.org.
SHIRO-591 - Allow BasicHttpAuthenticationFilter to be configured in permissive mode


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

Branch: refs/heads/1.4.x
Commit: 951318354a9005a7ccaba18effc3d2ea494e1e31
Parents: db46b11
Author: Brian Demers <bd...@apache.org>
Authored: Mon Oct 10 15:24:53 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 .../authc/BasicHttpAuthenticationFilter.java    | 24 ++++++-
 .../BasicHttpFilterAuthenticationTest.java      | 66 +++++++++++++++++++-
 2 files changed, 85 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/95131835/web/src/main/java/org/apache/shiro/web/filter/authc/BasicHttpAuthenticationFilter.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/shiro/web/filter/authc/BasicHttpAuthenticationFilter.java b/web/src/main/java/org/apache/shiro/web/filter/authc/BasicHttpAuthenticationFilter.java
index 9f9a7e3..8598c2e 100644
--- a/web/src/main/java/org/apache/shiro/web/filter/authc/BasicHttpAuthenticationFilter.java
+++ b/web/src/main/java/org/apache/shiro/web/filter/authc/BasicHttpAuthenticationFilter.java
@@ -28,7 +28,9 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.HashSet;
 import java.util.Locale;
+import java.util.Set;
 
 
 /**
@@ -197,10 +199,11 @@ public class BasicHttpAuthenticationFilter extends AuthenticatingFilter {
         // Check whether the current request's method requires authentication.
         // If no methods have been configured, then all of them require auth,
         // otherwise only the declared ones need authentication.
-        String[] methods = (String[]) (mappedValue == null ? new String[0] : mappedValue);
-        boolean authcRequired = methods.length == 0;
+
+        Set<String> methods = httpMethodsFromOptions((String[])mappedValue);
+        boolean authcRequired = methods.size() == 0;
         for (String m : methods) {
-            if (httpMethod.equalsIgnoreCase(m)) {
+            if (httpMethod.toUpperCase(Locale.ENGLISH).equals(m)) { // list of methods is in upper case
                 authcRequired = true;
                 break;
             }
@@ -214,6 +217,21 @@ public class BasicHttpAuthenticationFilter extends AuthenticatingFilter {
         }
     }
 
+    private Set<String> httpMethodsFromOptions(String[] options) {
+        Set<String> methods = new HashSet<String>();
+
+        if (options != null) {
+            for (String option : options) {
+                // to be backwards compatible with 1.3, we can ONLY check for known args
+                // ideally we would just validate HTTP methods, but someone could already be using this for webdav
+                if (!option.equalsIgnoreCase(PERMISSIVE)) {
+                    methods.add(option.toUpperCase(Locale.ENGLISH));
+                }
+            }
+        }
+        return methods;
+    }
+
     /**
      * Processes unauthenticated requests. It handles the two-stage request/challenge authentication protocol.
      *

http://git-wip-us.apache.org/repos/asf/shiro/blob/95131835/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
----------------------------------------------------------------------
diff --git a/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java b/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
index 3c32002..afdcbd6 100644
--- a/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
+++ b/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
@@ -177,7 +177,7 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
         
         HttpServletRequest request = createMock(HttpServletRequest.class);
         expect(request.getMethod()).andReturn("GET");
-        expect(request.getMethod()).andReturn("POST");
+        expect(request.getMethod()).andReturn("post");
         expect(request.getHeader("Authorization")).andReturn(createAuthorizationHeader("pedro", "")).anyTimes();
         expect(request.getRemoteHost()).andReturn("localhost").anyTimes();
         replay(request);
@@ -185,7 +185,7 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
         HttpServletResponse response = createMock(HttpServletResponse.class);
         replay(response);
         
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "post", "put", "delete" });
+        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "POST", "put", "delete" });
         assertTrue("Access not allowed for GET", accessAllowed);
         
         accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "post", "put", "delete" });
@@ -234,6 +234,68 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
         assertTrue("Access allowed for POST", !accessAllowed);
     }
 
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void permissiveEnabledWithLoginTest() {
+        testFilter = new BasicHttpAuthenticationFilter();
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        expect(request.getHeader("Authorization")).andReturn(createAuthorizationHeader("pedro", "")).anyTimes();
+        expect(request.getRemoteHost()).andReturn("localhost").anyTimes();
+        expect(request.getMethod()).andReturn("GET");
+        replay(request);
+
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        replay(response);
+
+        String[] mappedValue = {"permissive"};
+        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
+        assertTrue("Access allowed for GET", !accessAllowed); // login attempt should always be false
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void permissiveEnabledTest() {
+        testFilter = new BasicHttpAuthenticationFilter();
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        expect(request.getHeader("Authorization")).andReturn(null).anyTimes();
+        expect(request.getRemoteHost()).andReturn("localhost").anyTimes();
+        expect(request.getMethod()).andReturn("GET");
+        replay(request);
+
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        replay(response);
+
+        String[] mappedValue = {"permissive"};
+        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
+        assertTrue("Access should be allowed for GET", accessAllowed); // non-login attempt, return true
+    }
+
+    /**
+     * @since 1.4
+     */
+    @Test
+    public void httpMethodRequiresAuthenticationWithPermissive() throws Exception {
+        testFilter = new BasicHttpAuthenticationFilter();
+
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        expect(request.getHeader("Authorization")).andReturn(createAuthorizationHeader("pedro", ""));
+        expect(request.getRemoteHost()).andReturn("localhost");
+        expect(request.getMethod()).andReturn("POST");
+        replay(request);
+
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        replay(response);
+
+        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] {"permissive", "POST", "PUT", "DELETE" });
+        assertTrue("Access allowed for POST", !accessAllowed);
+    }
+
     private String createAuthorizationHeader(String username, String password) {
     	return "Basic " + new String(Base64.encode((username + ":" + password).getBytes()));
     }


[20/20] shiro git commit: SHIRO-493 - Adding new methods and deprecating old to ShiroWebModule to support Guice 4

Posted by bd...@apache.org.
SHIRO-493 - Adding new methods and deprecating old to ShiroWebModule to support Guice 4


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

Branch: refs/heads/1.4.x
Commit: a63e1d85f3e45d9976f61ebeb9fed49302e12956
Parents: f6b1a3c
Author: Brian Demers <bd...@apache.org>
Authored: Thu Jul 14 09:51:45 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:52 2016 -0400

----------------------------------------------------------------------
 integration-tests/guice3/pom.xml                | 117 ++++++++++
 .../guice/SampleShiroGuiceBootstrap.java        |  43 ++++
 .../samples/guice/SampleShiroServletModule.java |  92 ++++++++
 .../guice3/src/main/resources/log4j.properties  |  47 ++++
 .../guice3/src/main/webapp/WEB-INF/shiro.ini    |  53 +++++
 .../guice3/src/main/webapp/WEB-INF/web.xml      |  43 ++++
 .../guice3/src/main/webapp/account/index.jsp    |  36 +++
 .../guice3/src/main/webapp/home.jsp             |  69 ++++++
 .../guice3/src/main/webapp/include.jsp          |  22 ++
 .../guice3/src/main/webapp/index.jsp            |  21 ++
 .../guice3/src/main/webapp/login.jsp            | 110 +++++++++
 .../guice3/src/main/webapp/style.css            |  47 ++++
 .../samples/guice/AbstractContainerIT.java      | 142 ++++++++++++
 .../samples/guice/ContainerIntegrationIT.java   |  79 +++++++
 integration-tests/guice4/pom.xml                | 131 +++++++++++
 .../guice/SampleShiroGuiceBootstrap.java        |  43 ++++
 .../samples/guice/SampleShiroServletModule.java |  92 ++++++++
 .../guice4/src/main/resources/log4j.properties  |  47 ++++
 .../guice4/src/main/webapp/WEB-INF/shiro.ini    |  53 +++++
 .../guice4/src/main/webapp/WEB-INF/web.xml      |  43 ++++
 .../guice4/src/main/webapp/account/index.jsp    |  36 +++
 .../guice4/src/main/webapp/home.jsp             |  69 ++++++
 .../guice4/src/main/webapp/include.jsp          |  22 ++
 .../guice4/src/main/webapp/index.jsp            |  21 ++
 .../guice4/src/main/webapp/login.jsp            | 110 +++++++++
 .../guice4/src/main/webapp/style.css            |  47 ++++
 .../samples/guice/AbstractContainerIT.java      | 142 ++++++++++++
 .../samples/guice/ContainerIntegrationIT.java   |  79 +++++++
 integration-tests/pom.xml                       |  52 +++++
 pom.xml                                         |  60 +++--
 samples/guice/pom.xml                           |  21 --
 .../samples/guice/SampleShiroServletModule.java |   4 +-
 samples/jaxrs/pom.xml                           |   6 -
 samples/servlet-plugin/pom.xml                  |   6 -
 samples/web/pom.xml                             |   6 -
 support/guice/pom.xml                           |  27 ++-
 .../org/apache/shiro/guice/ShiroModule.java     |  61 +++++
 .../apache/shiro/guice/web/ShiroWebModule.java  | 229 ++++++++++++++++---
 .../shiro/guice/web/SimpleFilterChain.java      |   9 +
 .../org/apache/shiro/guice/ShiroModuleTest.java | 109 ++++++++-
 .../shiro/guice/web/FilterConfigTest.java       |   3 +-
 .../shiro/guice/web/ShiroWebModuleTest.java     | 192 +++++++++++++++-
 .../guice/src/test/resources/log4j.properties   |  34 +++
 43 files changed, 2584 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/pom.xml
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/pom.xml b/integration-tests/guice3/pom.xml
new file mode 100644
index 0000000..1f4b674
--- /dev/null
+++ b/integration-tests/guice3/pom.xml
@@ -0,0 +1,117 @@
+<?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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.shiro.integrationtests</groupId>
+		<artifactId>shiro-integration-tests</artifactId>
+		<version>1.4.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>shiro-its-guice3</artifactId>
+	<name>Apache Shiro :: ITs :: Guice 3</name>
+	<packaging>war</packaging>
+
+	<build>
+	    <plugins>
+			<plugin>
+				<groupId>org.eclipse.jetty</groupId>
+				<artifactId>jetty-maven-plugin</artifactId>
+			</plugin>
+	    </plugins>
+	</build>
+
+	<dependencies>
+	    <dependency>
+	        <groupId>javax.servlet</groupId>
+	        <artifactId>jstl</artifactId>
+			<scope>compile</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>javax.servlet</groupId>
+	        <artifactId>javax.servlet-api</artifactId>
+	        <scope>provided</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.slf4j</groupId>
+	        <artifactId>slf4j-log4j12</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>log4j</groupId>
+	        <artifactId>log4j</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.apache.shiro</groupId>
+	        <artifactId>shiro-core</artifactId>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.apache.shiro</groupId>
+	        <artifactId>shiro-web</artifactId>
+	    </dependency>
+		<dependency>
+		    <groupId>org.apache.shiro</groupId>
+		    <artifactId>shiro-guice</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.google.inject.extensions</groupId>
+			<artifactId>guice-servlet</artifactId>
+		</dependency>
+	    <dependency>
+	        <groupId>org.slf4j</groupId>
+	        <artifactId>jcl-over-slf4j</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+
+		<dependency>
+			<groupId>org.apache.shiro</groupId>
+			<artifactId>shiro-guice</artifactId>
+			<version>${project.version}</version>
+			<classifier>tests</classifier>
+		</dependency>
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <scope>test</scope>
+        </dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java b/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
new file mode 100644
index 0000000..ea9926f
--- /dev/null
+++ b/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
@@ -0,0 +1,43 @@
+/*
+ * 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.samples.guice;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import org.apache.shiro.guice.web.ShiroWebModule;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+public class SampleShiroGuiceBootstrap extends GuiceServletContextListener {
+
+    private ServletContext servletContext;
+
+    @Override
+    public void contextInitialized(final ServletContextEvent servletContextEvent) {
+        this.servletContext = servletContextEvent.getServletContext();
+        super.contextInitialized(servletContextEvent);
+    }
+
+    @Override
+    protected Injector getInjector() {
+        return Guice.createInjector(new SampleShiroServletModule(servletContext), ShiroWebModule.guiceFilterModule());
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java b/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
new file mode 100644
index 0000000..8b23855
--- /dev/null
+++ b/integration-tests/guice3/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
@@ -0,0 +1,92 @@
+/*
+ * 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.samples.guice;
+
+import com.google.inject.Provides;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+import com.google.inject.name.Names;
+import org.apache.shiro.codec.Base64;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.guice.web.ShiroWebModule;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.web.mgt.CookieRememberMeManager;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class SampleShiroServletModule extends ShiroWebModule {
+    private final ServletContext servletContext;
+
+    public SampleShiroServletModule(ServletContext servletContext) {
+        super(servletContext);
+
+        this.servletContext = servletContext;
+    }
+
+    @Override
+    protected void configureShiroWeb() {
+        bindConstant().annotatedWith(Names.named("shiro.loginUrl")).to("/login.jsp");
+        try {
+            this.bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
+        } catch (NoSuchMethodException e) {
+            addError("Could not locate proper constructor for IniRealm.", e);
+        }
+
+        this.addFilterChain("/login.jsp", AUTHC);
+        this.addFilterChain("/logout", LOGOUT);
+        this.addFilterChain("/account/**", AUTHC);
+
+        this.addFilterChain("/remoting/**", AUTHC, config(ROLES, "b2bClient"), config(PERMS, "remote:invoke:lan,wan"));
+    }
+
+    @Provides
+    @Singleton
+    Ini loadShiroIni() throws MalformedURLException {
+        URL iniUrl = servletContext.getResource("/WEB-INF/shiro.ini");
+        return Ini.fromResourcePath("url:" + iniUrl.toExternalForm());
+    }
+
+    @Override
+    protected void bindWebSecurityManager(AnnotatedBindingBuilder<? super WebSecurityManager> bind)
+    {
+        try
+        {
+            String cipherKey = loadShiroIni().getSectionProperty( "main", "securityManager.rememberMeManager.cipherKey" );
+
+            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+            CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
+            rememberMeManager.setCipherKey( Base64.decode( cipherKey ) );
+            securityManager.setRememberMeManager(rememberMeManager);
+            bind.toInstance(securityManager);
+        }
+        catch ( MalformedURLException e )
+        {
+            // for now just throw, you could just call
+            // super.bindWebSecurityManager(bind) if you do not need rememberMe functionality
+            throw new ConfigurationException( "securityManager.rememberMeManager.cipherKey must be set in shiro.ini." );
+        }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/resources/log4j.properties b/integration-tests/guice3/src/main/resources/log4j.properties
new file mode 100644
index 0000000..b10506b
--- /dev/null
+++ b/integration-tests/guice3/src/main/resources/log4j.properties
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+log4j.rootLogger=TRACE, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c]: %m%n
+
+# =============================================================================
+# 3rd Party Libraries
+# OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL
+# =============================================================================
+# ehcache caching manager:
+log4j.logger.net.sf.ehcache=WARN
+
+# Most all Apache libs:
+log4j.logger.org.apache=WARN
+
+# Quartz Enterprise Scheular (java 'cron' utility)
+log4j.logger.org.quartz=WARN
+
+# =============================================================================
+# Apache Shiro
+# =============================================================================
+# Shiro security framework
+log4j.logger.org.apache.shiro=TRACE
+#log4j.logger.org.apache.shiro.realm.text.PropertiesRealm=INFO
+#log4j.logger.org.apache.shiro.cache.ehcache.EhCache=INFO
+#log4j.logger.org.apache.shiro.io=INFO
+#log4j.logger.org.apache.shiro.web.servlet=INFO
+log4j.logger.org.apache.shiro.util.ThreadContext=INFO

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini b/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini
new file mode 100644
index 0000000..db453e7
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/WEB-INF/shiro.ini
@@ -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.
+#
+
+# INI configuration is very powerful and flexible, while still remaining succinct.
+# Please http://shiro.apache.org/configuration.html and
+# http://shiro.apache.org/web.html for more.
+
+[main]
+shiro.loginUrl = /login.jsp
+
+# We need to set the cipherKey, if you want the rememberMe cookie to work after restarting or on multiple nodes.
+# YOU MUST SET THIS TO A UNIQUE STRING
+securityManager.rememberMeManager.cipherKey = kPH+bIxk5D2deZiIxcaaaA==
+
+[users]
+# format: username = password, role1, role2, ..., roleN
+root = secret,admin
+guest = guest,guest
+presidentskroob = 12345,president
+darkhelmet = ludicrousspeed,darklord,schwartz
+lonestarr = vespa,goodguy,schwartz
+
+[roles]
+# format: roleName = permission1, permission2, ..., permissionN
+admin = *
+schwartz = lightsaber:*
+goodguy = winnebago:drive:eagle5
+
+[urls]
+# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
+# the 'authc' filter must still be specified for it so it can process that url's
+# login submissions. It is 'smart' enough to allow those requests through as specified by the
+# shiro.loginUrl above.
+/login.jsp = authc
+/logout = logout
+/account/** = authc
+/remoting/** = authc, roles[b2bClient], perms["remote:invoke:lan,wan"]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/WEB-INF/web.xml b/integration-tests/guice3/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..46567d4
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+<?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.
+  -->
+<web-app version="2.4"
+         xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+    <listener>
+        <listener-class>org.apache.shiro.samples.guice.SampleShiroGuiceBootstrap</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>GuiceFilter</filter-name>
+        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>GuiceFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <welcome-file-list>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/account/index.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/account/index.jsp b/integration-tests/guice3/src/main/webapp/account/index.jsp
new file mode 100644
index 0000000..4f6c9d8
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/account/index.jsp
@@ -0,0 +1,36 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="../include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Users only</h2>
+
+<p>You are currently logged in.</p>
+
+<p><a href="<c:url value="/home.jsp"/>">Return to the home page.</a></p>
+
+<p><a href="<c:url value="/logout"/>">Log out.</a></p>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/home.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/home.jsp b/integration-tests/guice3/src/main/webapp/home.jsp
new file mode 100644
index 0000000..61dee25
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/home.jsp
@@ -0,0 +1,69 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+    <title>Apache Shiro Quickstart</title>
+</head>
+<body>
+
+<h1>Apache Shiro Quickstart</h1>
+
+<p>Hi <shiro:guest>Guest</shiro:guest><shiro:user><shiro:principal/></shiro:user>!
+    ( <shiro:user><a href="<c:url value="/logout"/>">Log out</a></shiro:user>
+    <shiro:guest><a href="<c:url value="/login.jsp"/>">Log in</a> (sample accounts provided)</shiro:guest> )
+</p>
+
+<p>Welcome to the Apache Shiro Quickstart sample application.
+    This page represents the home page of any web application.</p>
+
+<shiro:user><p>Visit your <a href="<c:url value="/account"/>">account page</a>.</p></shiro:user>
+<shiro:guest><p>If you want to access the user-only <a href="<c:url value="/account"/>">account page</a>,
+    you will need to log-in first.</p></shiro:guest>
+
+<h2>Roles</h2>
+
+<p>To show some taglibs, here are the roles you have and don't have. Log out and log back in under different user
+    accounts to see different roles.</p>
+
+<h3>Roles you have</h3>
+
+<p>
+    <shiro:hasRole name="admin">admin<br/></shiro:hasRole>
+    <shiro:hasRole name="president">president<br/></shiro:hasRole>
+    <shiro:hasRole name="darklord">darklord<br/></shiro:hasRole>
+    <shiro:hasRole name="goodguy">goodguy<br/></shiro:hasRole>
+    <shiro:hasRole name="schwartz">schwartz<br/></shiro:hasRole>
+</p>
+
+<h3>Roles you DON'T have</h3>
+
+<p>
+    <shiro:lacksRole name="admin">admin<br/></shiro:lacksRole>
+    <shiro:lacksRole name="president">president<br/></shiro:lacksRole>
+    <shiro:lacksRole name="darklord">darklord<br/></shiro:lacksRole>
+    <shiro:lacksRole name="goodguy">goodguy<br/></shiro:lacksRole>
+    <shiro:lacksRole name="schwartz">schwartz<br/></shiro:lacksRole>
+</p>
+
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/include.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/include.jsp b/integration-tests/guice3/src/main/webapp/include.jsp
new file mode 100644
index 0000000..fddd239
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/include.jsp
@@ -0,0 +1,22 @@
+<%--
+  ~ 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.
+  --%>
+<%@ page import="org.apache.shiro.SecurityUtils" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/index.jsp b/integration-tests/guice3/src/main/webapp/index.jsp
new file mode 100644
index 0000000..9dedd19
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/index.jsp
@@ -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.
+  --%>
+
+<%-- Forward the user to the home page --%>
+<jsp:forward page="home.jsp"/>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/login.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/login.jsp b/integration-tests/guice3/src/main/webapp/login.jsp
new file mode 100644
index 0000000..c80ee54
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/login.jsp
@@ -0,0 +1,110 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Please Log in</h2>
+
+<shiro:guest>
+    <p>Here are a few sample accounts to play with in the default text-based Realm (used for this
+        demo and test installs only). Do you remember the movie these names came from? ;)</p>
+
+
+    <style type="text/css">
+        table.sample {
+            border-width: 1px;
+            border-style: outset;
+            border-color: blue;
+            border-collapse: separate;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample th {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample td {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+    </style>
+
+
+    <table class="sample">
+        <thead>
+        <tr>
+            <th>Username</th>
+            <th>Password</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr>
+            <td>root</td>
+            <td>secret</td>
+        </tr>
+        <tr>
+            <td>presidentskroob</td>
+            <td>12345</td>
+        </tr>
+        <tr>
+            <td>darkhelmet</td>
+            <td>ludicrousspeed</td>
+        </tr>
+        <tr>
+            <td>lonestarr</td>
+            <td>vespa</td>
+        </tr>
+        </tbody>
+    </table>
+    <br/><br/>
+</shiro:guest>
+
+<form name="loginform" action="" method="post">
+    <table align="left" border="0" cellspacing="0" cellpadding="3">
+        <tr>
+            <td>Username:</td>
+            <td><input type="text" name="username" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td>Password:</td>
+            <td><input type="password" name="password" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="left"><input type="checkbox" name="rememberMe"><font size="2">Remember Me</font></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td>
+        </tr>
+    </table>
+</form>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/main/webapp/style.css
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/main/webapp/style.css b/integration-tests/guice3/src/main/webapp/style.css
new file mode 100644
index 0000000..1308e3f
--- /dev/null
+++ b/integration-tests/guice3/src/main/webapp/style.css
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+body {
+    margin: 15px 0 0 15px;
+    padding: 1px; /*background: #2370cf;*/
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+table, td {
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+h1 {
+    font: 24px;
+}
+
+img {
+    border: thin black solid;
+}
+
+#contentBox {
+    text-align: center;
+    width: 50%;
+    margin: auto;
+    margin-top: 50px;
+    color: black;
+    background: #eee;
+    border: thick black solid;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java b/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
new file mode 100644
index 0000000..dcd47e1
--- /dev/null
+++ b/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
@@ -0,0 +1,142 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    protected static EmbeddedJetty jetty;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + jetty.getPort() + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java b/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
new file mode 100644
index 0000000..4ebc6c7
--- /dev/null
+++ b/integration-tests/guice3/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
@@ -0,0 +1,79 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.WebAssert;
+import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+
+    @Test
+    public void logInAndRememberMe() throws Exception {
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
+        checkbox.setChecked(true);
+        page = form.<HtmlInput>getInputByName("submit").click();
+        jetty.stop();
+        jetty.start();
+        page = webClient.getPage(getBaseUri());
+        // page.getAnchorByHref("/logout");
+        WebAssert.assertLinkPresentWithText(page, "Log out");
+        page = page.getAnchorByHref("/account").click();
+        // login page should be shown again - user remembered but not authenticated
+        WebAssert.assertFormPresent(page, "loginform");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/pom.xml
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/pom.xml b/integration-tests/guice4/pom.xml
new file mode 100644
index 0000000..da761ce
--- /dev/null
+++ b/integration-tests/guice4/pom.xml
@@ -0,0 +1,131 @@
+<?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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.shiro.integrationtests</groupId>
+		<artifactId>shiro-integration-tests</artifactId>
+		<version>1.4.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+	</parent>
+
+	<artifactId>shiro-its-guice4</artifactId>
+	<name>Apache Shiro :: ITs :: Guice 4</name>
+	<packaging>war</packaging>
+
+	<properties>
+		<guice.version>4.1.0</guice.version>
+	</properties>
+
+	<build>
+	    <plugins>
+			<plugin>
+				<groupId>org.eclipse.jetty</groupId>
+				<artifactId>jetty-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<dependenciesToScan>
+						<dependency>org.apache.shiro:shiro-guice</dependency>
+					</dependenciesToScan>
+				</configuration>
+			</plugin>
+	    </plugins>
+	</build>
+
+	<dependencies>
+	    <dependency>
+	        <groupId>javax.servlet</groupId>
+	        <artifactId>jstl</artifactId>
+			<scope>compile</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>javax.servlet</groupId>
+	        <artifactId>javax.servlet-api</artifactId>
+	        <scope>provided</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.slf4j</groupId>
+	        <artifactId>slf4j-log4j12</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>log4j</groupId>
+	        <artifactId>log4j</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.apache.shiro</groupId>
+	        <artifactId>shiro-core</artifactId>
+	    </dependency>
+	    <dependency>
+	        <groupId>org.apache.shiro</groupId>
+	        <artifactId>shiro-web</artifactId>
+	    </dependency>
+		<dependency>
+		    <groupId>org.apache.shiro</groupId>
+		    <artifactId>shiro-guice</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.google.inject.extensions</groupId>
+			<artifactId>guice-servlet</artifactId>
+		</dependency>
+	    <dependency>
+	        <groupId>org.slf4j</groupId>
+	        <artifactId>jcl-over-slf4j</artifactId>
+	        <scope>runtime</scope>
+	    </dependency>
+
+		<dependency>
+			<groupId>org.apache.shiro</groupId>
+			<artifactId>shiro-guice</artifactId>
+			<version>${project.version}</version>
+			<classifier>tests</classifier>
+		</dependency>
+        <dependency>
+            <groupId>net.sourceforge.htmlunit</groupId>
+            <artifactId>htmlunit</artifactId>
+            <version>2.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jsp</artifactId>
+            <version>${jetty.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>apache-jstl</artifactId>
+            <version>${jetty.version}</version>
+            <type>pom</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.mjeanroy</groupId>
+            <artifactId>junit-servers-jetty</artifactId>
+            <scope>test</scope>
+        </dependency>
+	</dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java b/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
new file mode 100644
index 0000000..ea9926f
--- /dev/null
+++ b/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroGuiceBootstrap.java
@@ -0,0 +1,43 @@
+/*
+ * 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.samples.guice;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+import org.apache.shiro.guice.web.ShiroWebModule;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+public class SampleShiroGuiceBootstrap extends GuiceServletContextListener {
+
+    private ServletContext servletContext;
+
+    @Override
+    public void contextInitialized(final ServletContextEvent servletContextEvent) {
+        this.servletContext = servletContextEvent.getServletContext();
+        super.contextInitialized(servletContextEvent);
+    }
+
+    @Override
+    protected Injector getInjector() {
+        return Guice.createInjector(new SampleShiroServletModule(servletContext), ShiroWebModule.guiceFilterModule());
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java b/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
new file mode 100644
index 0000000..ca6c2a3
--- /dev/null
+++ b/integration-tests/guice4/src/main/java/org/apache/shiro/samples/guice/SampleShiroServletModule.java
@@ -0,0 +1,92 @@
+/*
+ * 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.samples.guice;
+
+import com.google.inject.Provides;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+import com.google.inject.name.Names;
+import org.apache.shiro.codec.Base64;
+import org.apache.shiro.config.ConfigurationException;
+import org.apache.shiro.config.Ini;
+import org.apache.shiro.guice.web.ShiroWebModule;
+import org.apache.shiro.realm.text.IniRealm;
+import org.apache.shiro.web.mgt.CookieRememberMeManager;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.apache.shiro.web.mgt.WebSecurityManager;
+
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class SampleShiroServletModule extends ShiroWebModule {
+    private final ServletContext servletContext;
+
+    public SampleShiroServletModule(ServletContext servletContext) {
+        super(servletContext);
+
+        this.servletContext = servletContext;
+    }
+
+    @Override
+    protected void configureShiroWeb() {
+        bindConstant().annotatedWith(Names.named("shiro.loginUrl")).to("/login.jsp");
+        try {
+            this.bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
+        } catch (NoSuchMethodException e) {
+            addError("Could not locate proper constructor for IniRealm.", e);
+        }
+
+        this.addFilterChain("/login.jsp", AUTHC);
+        this.addFilterChain("/logout", LOGOUT);
+        this.addFilterChain("/account/**", AUTHC);
+
+        this.addFilterChain("/remoting/**", filterConfig(AUTHC), filterConfig(ROLES, "b2bClient"), filterConfig(PERMS, "remote:invoke:lan,wan"));
+    }
+
+    @Provides
+    @Singleton
+    Ini loadShiroIni() throws MalformedURLException {
+        URL iniUrl = servletContext.getResource("/WEB-INF/shiro.ini");
+        return Ini.fromResourcePath("url:" + iniUrl.toExternalForm());
+    }
+
+    @Override
+    protected void bindWebSecurityManager(AnnotatedBindingBuilder<? super WebSecurityManager> bind)
+    {
+        try
+        {
+            String cipherKey = loadShiroIni().getSectionProperty( "main", "securityManager.rememberMeManager.cipherKey" );
+
+            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+            CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();
+            rememberMeManager.setCipherKey( Base64.decode( cipherKey ) );
+            securityManager.setRememberMeManager(rememberMeManager);
+            bind.toInstance(securityManager);
+        }
+        catch ( MalformedURLException e )
+        {
+            // for now just throw, you could just call
+            // super.bindWebSecurityManager(bind) if you do not need rememberMe functionality
+            throw new ConfigurationException( "securityManager.rememberMeManager.cipherKey must be set in shiro.ini." );
+        }
+
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/resources/log4j.properties b/integration-tests/guice4/src/main/resources/log4j.properties
new file mode 100644
index 0000000..b10506b
--- /dev/null
+++ b/integration-tests/guice4/src/main/resources/log4j.properties
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+log4j.rootLogger=TRACE, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c]: %m%n
+
+# =============================================================================
+# 3rd Party Libraries
+# OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL
+# =============================================================================
+# ehcache caching manager:
+log4j.logger.net.sf.ehcache=WARN
+
+# Most all Apache libs:
+log4j.logger.org.apache=WARN
+
+# Quartz Enterprise Scheular (java 'cron' utility)
+log4j.logger.org.quartz=WARN
+
+# =============================================================================
+# Apache Shiro
+# =============================================================================
+# Shiro security framework
+log4j.logger.org.apache.shiro=TRACE
+#log4j.logger.org.apache.shiro.realm.text.PropertiesRealm=INFO
+#log4j.logger.org.apache.shiro.cache.ehcache.EhCache=INFO
+#log4j.logger.org.apache.shiro.io=INFO
+#log4j.logger.org.apache.shiro.web.servlet=INFO
+log4j.logger.org.apache.shiro.util.ThreadContext=INFO

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/WEB-INF/shiro.ini
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/WEB-INF/shiro.ini b/integration-tests/guice4/src/main/webapp/WEB-INF/shiro.ini
new file mode 100644
index 0000000..db453e7
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/WEB-INF/shiro.ini
@@ -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.
+#
+
+# INI configuration is very powerful and flexible, while still remaining succinct.
+# Please http://shiro.apache.org/configuration.html and
+# http://shiro.apache.org/web.html for more.
+
+[main]
+shiro.loginUrl = /login.jsp
+
+# We need to set the cipherKey, if you want the rememberMe cookie to work after restarting or on multiple nodes.
+# YOU MUST SET THIS TO A UNIQUE STRING
+securityManager.rememberMeManager.cipherKey = kPH+bIxk5D2deZiIxcaaaA==
+
+[users]
+# format: username = password, role1, role2, ..., roleN
+root = secret,admin
+guest = guest,guest
+presidentskroob = 12345,president
+darkhelmet = ludicrousspeed,darklord,schwartz
+lonestarr = vespa,goodguy,schwartz
+
+[roles]
+# format: roleName = permission1, permission2, ..., permissionN
+admin = *
+schwartz = lightsaber:*
+goodguy = winnebago:drive:eagle5
+
+[urls]
+# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
+# the 'authc' filter must still be specified for it so it can process that url's
+# login submissions. It is 'smart' enough to allow those requests through as specified by the
+# shiro.loginUrl above.
+/login.jsp = authc
+/logout = logout
+/account/** = authc
+/remoting/** = authc, roles[b2bClient], perms["remote:invoke:lan,wan"]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/WEB-INF/web.xml b/integration-tests/guice4/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..46567d4
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,43 @@
+<?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.
+  -->
+<web-app version="2.4"
+         xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+    <listener>
+        <listener-class>org.apache.shiro.samples.guice.SampleShiroGuiceBootstrap</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>GuiceFilter</filter-name>
+        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>GuiceFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+
+    <welcome-file-list>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+
+</web-app>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/account/index.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/account/index.jsp b/integration-tests/guice4/src/main/webapp/account/index.jsp
new file mode 100644
index 0000000..4f6c9d8
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/account/index.jsp
@@ -0,0 +1,36 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="../include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Users only</h2>
+
+<p>You are currently logged in.</p>
+
+<p><a href="<c:url value="/home.jsp"/>">Return to the home page.</a></p>
+
+<p><a href="<c:url value="/logout"/>">Log out.</a></p>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/home.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/home.jsp b/integration-tests/guice4/src/main/webapp/home.jsp
new file mode 100644
index 0000000..61dee25
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/home.jsp
@@ -0,0 +1,69 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+    <title>Apache Shiro Quickstart</title>
+</head>
+<body>
+
+<h1>Apache Shiro Quickstart</h1>
+
+<p>Hi <shiro:guest>Guest</shiro:guest><shiro:user><shiro:principal/></shiro:user>!
+    ( <shiro:user><a href="<c:url value="/logout"/>">Log out</a></shiro:user>
+    <shiro:guest><a href="<c:url value="/login.jsp"/>">Log in</a> (sample accounts provided)</shiro:guest> )
+</p>
+
+<p>Welcome to the Apache Shiro Quickstart sample application.
+    This page represents the home page of any web application.</p>
+
+<shiro:user><p>Visit your <a href="<c:url value="/account"/>">account page</a>.</p></shiro:user>
+<shiro:guest><p>If you want to access the user-only <a href="<c:url value="/account"/>">account page</a>,
+    you will need to log-in first.</p></shiro:guest>
+
+<h2>Roles</h2>
+
+<p>To show some taglibs, here are the roles you have and don't have. Log out and log back in under different user
+    accounts to see different roles.</p>
+
+<h3>Roles you have</h3>
+
+<p>
+    <shiro:hasRole name="admin">admin<br/></shiro:hasRole>
+    <shiro:hasRole name="president">president<br/></shiro:hasRole>
+    <shiro:hasRole name="darklord">darklord<br/></shiro:hasRole>
+    <shiro:hasRole name="goodguy">goodguy<br/></shiro:hasRole>
+    <shiro:hasRole name="schwartz">schwartz<br/></shiro:hasRole>
+</p>
+
+<h3>Roles you DON'T have</h3>
+
+<p>
+    <shiro:lacksRole name="admin">admin<br/></shiro:lacksRole>
+    <shiro:lacksRole name="president">president<br/></shiro:lacksRole>
+    <shiro:lacksRole name="darklord">darklord<br/></shiro:lacksRole>
+    <shiro:lacksRole name="goodguy">goodguy<br/></shiro:lacksRole>
+    <shiro:lacksRole name="schwartz">schwartz<br/></shiro:lacksRole>
+</p>
+
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/include.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/include.jsp b/integration-tests/guice4/src/main/webapp/include.jsp
new file mode 100644
index 0000000..fddd239
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/include.jsp
@@ -0,0 +1,22 @@
+<%--
+  ~ 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.
+  --%>
+<%@ page import="org.apache.shiro.SecurityUtils" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/index.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/index.jsp b/integration-tests/guice4/src/main/webapp/index.jsp
new file mode 100644
index 0000000..9dedd19
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/index.jsp
@@ -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.
+  --%>
+
+<%-- Forward the user to the home page --%>
+<jsp:forward page="home.jsp"/>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/login.jsp
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/login.jsp b/integration-tests/guice4/src/main/webapp/login.jsp
new file mode 100644
index 0000000..c80ee54
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/login.jsp
@@ -0,0 +1,110 @@
+<%--
+  ~ 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.
+  --%>
+<%@ include file="include.jsp" %>
+
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" href="<c:url value="/style.css"/>"/>
+</head>
+<body>
+
+<h2>Please Log in</h2>
+
+<shiro:guest>
+    <p>Here are a few sample accounts to play with in the default text-based Realm (used for this
+        demo and test installs only). Do you remember the movie these names came from? ;)</p>
+
+
+    <style type="text/css">
+        table.sample {
+            border-width: 1px;
+            border-style: outset;
+            border-color: blue;
+            border-collapse: separate;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample th {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+
+        table.sample td {
+            border-width: 1px;
+            padding: 1px;
+            border-style: none;
+            border-color: blue;
+            background-color: rgb(255, 255, 240);
+        }
+    </style>
+
+
+    <table class="sample">
+        <thead>
+        <tr>
+            <th>Username</th>
+            <th>Password</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr>
+            <td>root</td>
+            <td>secret</td>
+        </tr>
+        <tr>
+            <td>presidentskroob</td>
+            <td>12345</td>
+        </tr>
+        <tr>
+            <td>darkhelmet</td>
+            <td>ludicrousspeed</td>
+        </tr>
+        <tr>
+            <td>lonestarr</td>
+            <td>vespa</td>
+        </tr>
+        </tbody>
+    </table>
+    <br/><br/>
+</shiro:guest>
+
+<form name="loginform" action="" method="post">
+    <table align="left" border="0" cellspacing="0" cellpadding="3">
+        <tr>
+            <td>Username:</td>
+            <td><input type="text" name="username" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td>Password:</td>
+            <td><input type="password" name="password" maxlength="30"></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="left"><input type="checkbox" name="rememberMe"><font size="2">Remember Me</font></td>
+        </tr>
+        <tr>
+            <td colspan="2" align="right"><input type="submit" name="submit" value="Login"></td>
+        </tr>
+    </table>
+</form>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/main/webapp/style.css
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/main/webapp/style.css b/integration-tests/guice4/src/main/webapp/style.css
new file mode 100644
index 0000000..1308e3f
--- /dev/null
+++ b/integration-tests/guice4/src/main/webapp/style.css
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+body {
+    margin: 15px 0 0 15px;
+    padding: 1px; /*background: #2370cf;*/
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+table, td {
+    font: 12px 'Lucida Grande', Geneva, Verdana, Arial, sans-serif;
+    color: #000;
+}
+
+h1 {
+    font: 24px;
+}
+
+img {
+    border: thin black solid;
+}
+
+#contentBox {
+    text-align: center;
+    width: 50%;
+    margin: auto;
+    margin-top: 50px;
+    color: black;
+    background: #eee;
+    border: thick black solid;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java b/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
new file mode 100644
index 0000000..dcd47e1
--- /dev/null
+++ b/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/AbstractContainerIT.java
@@ -0,0 +1,142 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJetty;
+import com.github.mjeanroy.junit.servers.jetty.EmbeddedJettyConfiguration;
+import org.eclipse.jetty.annotations.AnnotationConfiguration;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.resource.FileResource;
+import org.eclipse.jetty.webapp.Configuration;
+import org.eclipse.jetty.webapp.FragmentConfiguration;
+import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
+import org.eclipse.jetty.webapp.MetaInfConfiguration;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.jetty.webapp.WebInfConfiguration;
+import org.eclipse.jetty.webapp.WebXmlConfiguration;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+import static com.github.mjeanroy.junit.servers.commons.Strings.isNotBlank;
+import static org.eclipse.jetty.util.resource.Resource.newResource;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public abstract class AbstractContainerIT {
+
+    protected static EmbeddedJetty jetty;
+
+    protected final WebClient webClient = new WebClient();
+
+    @BeforeClass
+    public static void startContainer() throws Exception {
+
+        EmbeddedJettyConfiguration config = EmbeddedJettyConfiguration.builder()
+                .withWebapp(getWarDir())
+                .build();
+
+        jetty = new EmbeddedJetty(config) {
+
+            /**
+             * Overriding with contents of this pull request, to make fragment scanning work.
+             * https://github.com/mjeanroy/junit-servers/pull/3
+             */
+            protected WebAppContext createdWebAppContext() throws Exception {
+                final String path = configuration.getPath();
+                final String webapp = configuration.getWebapp();
+                final String classpath = configuration.getClasspath();
+
+                WebAppContext ctx = new WebAppContext();
+                ctx.setClassLoader(Thread.currentThread().getContextClassLoader());
+                ctx.setContextPath(path);
+
+                // Useful for WebXmlConfiguration
+                ctx.setBaseResource(newResource(webapp));
+
+                ctx.setConfigurations(new Configuration[]{
+                        new WebInfConfiguration(),
+                        new WebXmlConfiguration(),
+                        new AnnotationConfiguration(),
+                        new JettyWebXmlConfiguration(),
+                        new MetaInfConfiguration(),
+                        new FragmentConfiguration(),
+                });
+
+                if (isNotBlank(classpath)) {
+                    // Fix to scan Spring WebApplicationInitializer
+                    // This will add compiled classes to jetty classpath
+                    // See: http://stackoverflow.com/questions/13222071/spring-3-1-webapplicationinitializer-embedded-jetty-8-annotationconfiguration
+                    // And more precisely: http://stackoverflow.com/a/18449506/1215828
+                    File classes = new File(classpath);
+                    FileResource containerResources = new FileResource(classes.toURI());
+                    ctx.getMetaData().addContainerResource(containerResources);
+                }
+
+                Server server = getDelegate();
+
+                ctx.setParentLoaderPriority(true);
+                ctx.setWar(webapp);
+                ctx.setServer(server);
+
+                // Add server context
+                server.setHandler(ctx);
+
+                return ctx;
+            }
+        };
+
+        jetty.start();
+
+        assertTrue(jetty.isStarted());
+    }
+
+    protected static String getBaseUri() {
+        return "http://localhost:" + jetty.getPort() + "/";
+    }
+
+    protected static String getWarDir() {
+        File[] warFiles = new File("target").listFiles(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return name.endsWith(".war");
+            }
+        });
+
+        assertEquals("Expected only one war file in target directory, run 'mvn clean' and try again", 1, warFiles.length);
+
+        return warFiles[0].getAbsolutePath().replaceFirst("\\.war$", "");
+    }
+
+    @Before
+    public void beforeTest() {
+        webClient.setThrowExceptionOnFailingStatusCode(true);
+    }
+
+    @AfterClass
+    public static void stopContainer() {
+        if (jetty != null) {
+            jetty.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
----------------------------------------------------------------------
diff --git a/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java b/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
new file mode 100644
index 0000000..4ebc6c7
--- /dev/null
+++ b/integration-tests/guice4/src/test/java/org/apache/shiro/samples/guice/ContainerIntegrationIT.java
@@ -0,0 +1,79 @@
+/*
+ * 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.samples.guice;
+
+import com.gargoylesoftware.htmlunit.ElementNotFoundException;
+import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
+import com.gargoylesoftware.htmlunit.WebAssert;
+import com.gargoylesoftware.htmlunit.html.HtmlCheckBoxInput;
+import com.gargoylesoftware.htmlunit.html.HtmlForm;
+import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+public class ContainerIntegrationIT extends AbstractContainerIT {
+
+    @Before
+    public void logOut() throws IOException {
+        // Make sure we are logged out
+        final HtmlPage homePage = webClient.getPage(getBaseUri());
+        try {
+            homePage.getAnchorByHref("/logout").click();
+        }
+        catch (ElementNotFoundException e) {
+            //Ignore
+        }
+    }
+
+    @Test
+    public void logIn() throws FailingHttpStatusCodeException, MalformedURLException, IOException, InterruptedException {
+
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        page = form.<HtmlInput>getInputByName("submit").click();
+        // This'll throw an expection if not logged in
+        page.getAnchorByHref("/logout");
+    }
+
+    @Test
+    public void logInAndRememberMe() throws Exception {
+        HtmlPage page = webClient.getPage(getBaseUri() + "login.jsp");
+        HtmlForm form = page.getFormByName("loginform");
+        form.<HtmlInput>getInputByName("username").setValueAttribute("root");
+        form.<HtmlInput>getInputByName("password").setValueAttribute("secret");
+        HtmlCheckBoxInput checkbox = form.getInputByName("rememberMe");
+        checkbox.setChecked(true);
+        page = form.<HtmlInput>getInputByName("submit").click();
+        jetty.stop();
+        jetty.start();
+        page = webClient.getPage(getBaseUri());
+        // page.getAnchorByHref("/logout");
+        WebAssert.assertLinkPresentWithText(page, "Log out");
+        page = page.getAnchorByHref("/account").click();
+        // login page should be shown again - user remembered but not authenticated
+        WebAssert.assertFormPresent(page, "loginform");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/a63e1d85/integration-tests/pom.xml
----------------------------------------------------------------------
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
new file mode 100644
index 0000000..1b8dd19
--- /dev/null
+++ b/integration-tests/pom.xml
@@ -0,0 +1,52 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-root</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.shiro.integrationtests</groupId>
+    <artifactId>shiro-integration-tests</artifactId>
+
+    <name>Apache Shiro :: Integration Tests</name>
+    <description>Test for alternate major versions of dependencies</description>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>guice3</module>
+        <module>guice4</module>
+    </modules>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+</project>
+


[15/20] shiro git commit: Update commons, ehcache, and aspects dependency versions

Posted by bd...@apache.org.
Update commons, ehcache, and aspects dependency versions


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

Branch: refs/heads/1.4.x
Commit: f6b1a3ca3027d27eb53ee6462e9f6c59cd01817e
Parents: 4bf2e4e
Author: Brian Demers <bd...@apache.org>
Authored: Tue Oct 11 15:09:36 2016 -0400
Committer: Brian Demers <bd...@apache.org>
Committed: Fri Oct 14 15:15:51 2016 -0400

----------------------------------------------------------------------
 pom.xml                  | 8 ++++----
 support/features/pom.xml | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/f6b1a3ca/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ea94c99..53c8946 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,13 +74,13 @@
         <!-- Compile 3rd party dependencies: -->
         <!-- Don't change this version without also changing the shiro-aspect and shiro-features
              modules' OSGi metadata: -->
-        <aspectj.version>1.8.6</aspectj.version>
-        <commons.cli.version>1.2</commons.cli.version>
-        <commons.codec.version>1.4</commons.codec.version>
+        <aspectj.version>1.8.9</aspectj.version>
+        <commons.cli.version>1.3.1</commons.cli.version>
+        <commons.codec.version>1.10</commons.codec.version>
         <crowd.version>1.5.2</crowd.version>
         <!-- Don't change this version without also changing the shiro-ehcache and shiro-features
              modules' OSGi metadata: -->
-        <ehcache.version>2.5.3</ehcache.version>
+        <ehcache.version>2.6.11</ehcache.version>
         <!-- Don't change this version without also changing the shiro-hazelcast and shiro-features OSGi metadata: -->
         <hazelcast.version>2.4.1</hazelcast.version>
         <hsqldb.version>1.8.0.7</hsqldb.version>

http://git-wip-us.apache.org/repos/asf/shiro/blob/f6b1a3ca/support/features/pom.xml
----------------------------------------------------------------------
diff --git a/support/features/pom.xml b/support/features/pom.xml
index b4d4fbb..e083e86 100644
--- a/support/features/pom.xml
+++ b/support/features/pom.xml
@@ -32,8 +32,8 @@
     <packaging>pom</packaging>
 
     <properties>
-        <aspectj.bundle.version>1.6.16_1</aspectj.bundle.version>
-        <ehcache.bundle.version>2.5.3_1</ehcache.bundle.version>
+        <aspectj.bundle.version>1.8.9_1</aspectj.bundle.version>
+        <ehcache.bundle.version>2.6.11_1</ehcache.bundle.version>
         <hazelcast.bundle.version>2.4.1_1</hazelcast.bundle.version>
         <quartz.bundle.version>1.6.1_1</quartz.bundle.version>
         <!-- Not a Shiro dependency - used for quartz bundle resolution only (see features.xml): -->