shiro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdem...@apache.org
Subject [2/2] shiro git commit: Add more Spring examples
Date Wed, 14 Dec 2016 19:08:30 GMT
Add more Spring examples


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

Branch: refs/heads/master
Commit: 03cad012125b73af59f3d2653fa1fa25d50e0582
Parents: 4344076
Author: Brian Demers <bdemers@apache.org>
Authored: Wed Dec 14 11:07:59 2016 -0800
Committer: Brian Demers <bdemers@apache.org>
Committed: Wed Dec 14 11:07:59 2016 -0800

----------------------------------------------------------------------
 samples/pom.xml                                 |   2 +
 samples/spring-boot-web/README.md               |  13 ++
 .../java/org/apache/shiro/samples/WebApp.java   |  10 -
 samples/spring-boot/README.md                   |  12 ++
 samples/spring-boot/pom.xml                     |  82 +++++++++
 .../java/org/apache/shiro/samples/CliApp.java   |  64 +++++++
 .../org/apache/shiro/samples/QuickStart.java    |  93 ++++++++++
 .../org/apache/shiro/samples/SimpleService.java |  43 +++++
 .../src/main/resources/application.properties   |  21 +++
 samples/spring-mvc/README.md                    |  13 ++
 samples/spring-mvc/pom.xml                      | 161 +++++++++++++++++
 .../samples/spring/BootstrapDataPopulator.java  | 120 ++++++++++++
 .../samples/spring/DefaultSampleManager.java    | 105 +++++++++++
 .../spring/config/ApplicationConfig.java        | 181 +++++++++++++++++++
 .../samples/spring/config/JspViewsConfig.java   |  65 +++++++
 .../spring/config/RemotingServletConfig.java    |  45 +++++
 .../config/ServletApplicationInitializer.java   |  72 ++++++++
 .../spring/realm/SaltAwareJdbcRealm.java        | 121 +++++++++++++
 .../samples/spring/web/IndexController.java     | 111 ++++++++++++
 .../samples/spring/web/JnlpController.java      | 104 +++++++++++
 .../samples/spring/web/LoginController.java     |  68 +++++++
 .../samples/spring/web/LogoutController.java    |  46 +++++
 .../spring/web/RootRedirectController.java      |  36 ++++
 .../src/main/resources/application.properties   |  28 +++
 .../spring-mvc/src/main/resources/ehcache.xml   |  98 ++++++++++
 .../src/main/resources/jsecurity-sample.jks     | Bin 0 -> 1250 bytes
 .../src/main/resources/log4j.properties         |  36 ++++
 .../main/webapp/WEB-INF/resources/include.jsp   |  24 +++
 .../src/main/webapp/WEB-INF/resources/login.jsp |  49 +++++
 .../webapp/WEB-INF/resources/sampleIndex.jsp    |  83 +++++++++
 samples/spring-mvc/src/main/webapp/logo.png     | Bin 0 -> 10883 bytes
 samples/spring-mvc/src/main/webapp/shiro.css    |  48 +++++
 samples/spring/pom.xml                          | 119 ++----------
 .../samples/spring/BootstrapDataPopulator.java  | 120 ------------
 .../org/apache/shiro/samples/spring/CliApp.java |  63 +++++++
 .../samples/spring/DefaultSampleManager.java    | 105 -----------
 .../apache/shiro/samples/spring/QuickStart.java |  93 ++++++++++
 .../shiro/samples/spring/SimpleService.java     |  43 +++++
 .../spring/config/ApplicationConfig.java        | 180 ------------------
 .../samples/spring/config/JspViewsConfig.java   |  65 -------
 .../spring/config/RemotingServletConfig.java    |  45 -----
 .../config/ServletApplicationInitializer.java   |  72 --------
 .../spring/realm/SaltAwareJdbcRealm.java        | 121 -------------
 .../samples/spring/web/IndexController.java     | 111 ------------
 .../samples/spring/web/JnlpController.java      | 104 -----------
 .../samples/spring/web/LoginController.java     |  68 -------
 .../samples/spring/web/LogoutController.java    |  46 -----
 .../spring/web/RootRedirectController.java      |  36 ----
 .../src/main/resources/application.properties   |   9 -
 samples/spring/src/main/resources/ehcache.xml   |  98 ----------
 .../src/main/resources/jsecurity-sample.jks     | Bin 1250 -> 0 bytes
 .../spring/src/main/resources/log4j.properties  |   7 +-
 .../main/webapp/WEB-INF/resources/include.jsp   |  24 ---
 .../src/main/webapp/WEB-INF/resources/login.jsp |  49 -----
 .../webapp/WEB-INF/resources/sampleIndex.jsp    |  83 ---------
 samples/spring/src/main/webapp/logo.png         | Bin 10883 -> 0 bytes
 samples/spring/src/main/webapp/shiro.css        |  48 -----
 57 files changed, 2162 insertions(+), 1501 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/pom.xml
----------------------------------------------------------------------
diff --git a/samples/pom.xml b/samples/pom.xml
index 3bf2f62..72b9193 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -38,8 +38,10 @@
         <module>web</module>
         <module>spring-client</module>
         <module>spring</module>
+        <module>spring-mvc</module>
         <module>spring-xml</module>
         <module>spring-hibernate</module>
+        <module>spring-boot</module>
         <module>spring-boot-web</module>
         <module>guice</module>
         <module>quickstart-guice</module>

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot-web/README.md
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/README.md b/samples/spring-boot-web/README.md
new file mode 100644
index 0000000..23921b1
--- /dev/null
+++ b/samples/spring-boot-web/README.md
@@ -0,0 +1,13 @@
+Apache Shiro + Spring Web Example
+=================================
+
+A Spring Boot example web application that show the usage of a user login, checking permissions, and annotation protected methods.
+
+Run the Example
+---------------
+
+```
+mvn spring-boot:run
+```
+
+Browse to `http://localhost:8080/`
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java b/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
index 505a78c..819db0f 100644
--- a/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
+++ b/samples/spring-boot-web/src/main/java/org/apache/shiro/samples/WebApp.java
@@ -69,16 +69,6 @@ public class WebApp { //NOPMD
         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();

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot/README.md
----------------------------------------------------------------------
diff --git a/samples/spring-boot/README.md b/samples/spring-boot/README.md
new file mode 100644
index 0000000..fa738cc
--- /dev/null
+++ b/samples/spring-boot/README.md
@@ -0,0 +1,12 @@
+Apache Shiro + Spring CLI Example
+=================================
+
+A Spring Boot example CLI application that show the usage of a user login, checking permissions, and annotation protected methods.
+
+Run the Example
+---------------
+
+```
+mvn spring-boot:run
+```
+

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-boot/pom.xml b/samples/spring-boot/pom.xml
new file mode 100644
index 0000000..0847e9f
--- /dev/null
+++ b/samples/spring-boot/pom.xml
@@ -0,0 +1,82 @@
+<?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.samples</groupId>
+        <artifactId>shiro-samples</artifactId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>samples-spring-boot</artifactId>
+    <name>Apache Shiro :: Samples :: Spring Boot</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-starter</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>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>runtime</scope>
+        </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/03cad012/samples/spring-boot/src/main/java/org/apache/shiro/samples/CliApp.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot/src/main/java/org/apache/shiro/samples/CliApp.java b/samples/spring-boot/src/main/java/org/apache/shiro/samples/CliApp.java
new file mode 100644
index 0000000..f925245
--- /dev/null
+++ b/samples/spring-boot/src/main/java/org/apache/shiro/samples/CliApp.java
@@ -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.samples;
+
+import org.apache.shiro.realm.Realm;
+import org.apache.shiro.realm.text.TextConfigurationRealm;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+/**
+ * Spring Boot Application that show the usage of a user login, checking permissions, and annotation protected methods.
+ *
+ * @see QuickStart
+ * @see SimpleService
+ */
+@Configuration
+@SpringBootApplication
+public class CliApp { //NOPMD
+
+    public static void main(String[] args) {
+
+        ConfigurableApplicationContext context = SpringApplication.run(CliApp.class, args);
+
+        // Grab the 'QuickStart' bean, call 'run()' to start the example.
+        context.getBean(QuickStart.class).run();
+    }
+
+    /**
+     * Example hard coded Realm bean.
+     * @return hard coded Realm bean
+     */
+    @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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot/src/main/java/org/apache/shiro/samples/QuickStart.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot/src/main/java/org/apache/shiro/samples/QuickStart.java b/samples/spring-boot/src/main/java/org/apache/shiro/samples/QuickStart.java
new file mode 100644
index 0000000..bf6eef8
--- /dev/null
+++ b/samples/spring-boot/src/main/java/org/apache/shiro/samples/QuickStart.java
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Simple Bean used to demonstrate subject usage.
+ */
+@Component
+public class QuickStart {
+
+    private static Logger log = LoggerFactory.getLogger(QuickStart.class);
+
+    @Autowired
+    private SecurityManager securityManager;
+
+    @Autowired
+    private SimpleService simpleService;
+
+    public void run() {
+
+        // get the current subject
+        Subject subject = SecurityUtils.getSubject();
+
+        // Subject is not authenticated yet
+        Assert.isTrue(!subject.isAuthenticated());
+
+        // login the subject with a username / password
+        UsernamePasswordToken token = new UsernamePasswordToken("joe.coder", "password");
+        subject.login(token);
+
+        // joe.coder has the "user" role
+        subject.checkRole("user");
+
+        // joe.coder does NOT have the admin role
+        Assert.isTrue(!subject.hasRole("admin"));
+
+        // joe.coder has the "read" permission
+        subject.checkPermission("read");
+
+        // current user is allowed to execute this method.
+        simpleService.readRestrictedCall();
+
+        try {
+            // but not this one!
+            simpleService.writeRestrictedCall();
+        }
+        catch (AuthorizationException e) {
+            log.info("Subject was NOT allowed to execute method 'writeRestrictedCall'");
+        }
+
+        // logout
+        subject.logout();
+        Assert.isTrue(!subject.isAuthenticated());
+    }
+
+
+    /**
+     * Sets the static instance of SecurityManager. This is NOT needed for web applications.
+     */
+    @PostConstruct
+    private void initStaticSecurityManager() {
+        SecurityUtils.setSecurityManager(securityManager);
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot/src/main/java/org/apache/shiro/samples/SimpleService.java
----------------------------------------------------------------------
diff --git a/samples/spring-boot/src/main/java/org/apache/shiro/samples/SimpleService.java b/samples/spring-boot/src/main/java/org/apache/shiro/samples/SimpleService.java
new file mode 100644
index 0000000..aad6b72
--- /dev/null
+++ b/samples/spring-boot/src/main/java/org/apache/shiro/samples/SimpleService.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;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * Simple Service with methods protected with annotations.
+ */
+@Component
+public class SimpleService {
+
+    private static Logger log = LoggerFactory.getLogger(SimpleService.class);
+
+    @RequiresPermissions("write")
+    public void writeRestrictedCall() {
+        log.info("executing method that requires the 'write' permission");
+    }
+
+    @RequiresPermissions("read")
+    public void readRestrictedCall() {
+        log.info("executing method that requires the 'read' permission");
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-boot/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/samples/spring-boot/src/main/resources/application.properties b/samples/spring-boot/src/main/resources/application.properties
new file mode 100644
index 0000000..986fca9
--- /dev/null
+++ b/samples/spring-boot/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.
+#
+
+logging.level.org.springframework.web=DEBUG
+logging.level.org.hibernate=ERROR
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/README.md
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/README.md b/samples/spring-mvc/README.md
new file mode 100644
index 0000000..6c3861e
--- /dev/null
+++ b/samples/spring-mvc/README.md
@@ -0,0 +1,13 @@
+Apache Shiro + Spring Web Example
+=================================
+
+This example creates a web application (WAR packaged) to demonstrate configuring Apache Shiro via Spring.  This example also includes a Spring Remoting example.
+
+Run the Example
+---------------
+
+```
+mvn jetty:run
+```
+
+Browse to `http://localhost:8080/shiro-samples-spring`

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/pom.xml
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/pom.xml b/samples/spring-mvc/pom.xml
new file mode 100644
index 0000000..9a09877
--- /dev/null
+++ b/samples/spring-mvc/pom.xml
@@ -0,0 +1,161 @@
+<?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>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>samples-spring-mvc</artifactId>
+    <name>Apache Shiro :: Samples :: Spring MVC</name>
+    <packaging>war</packaging>
+    <description>
+    	Spring-based web application sample demonstrating Shiro's capabilities. Uses samples-spring module
+    	as the web start application.
+    </description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!-- Note	that you need	to run mvn jetty:run-exploded	to test	the	webstart application -->
+                <groupId>org.eclipse.jetty</groupId>
+                <artifactId>jetty-maven-plugin</artifactId>
+                <version>${jetty.version}</version>
+                <configuration>
+                    <httpConnector>
+                        <port>8080</port>
+                    </httpConnector>
+                    <webApp>
+                        <contextPath>/shiro-samples-spring</contextPath>
+                        <baseResource implementation="org.eclipse.jetty.util.resource.ResourceCollection">
+                            <resourcesAsCSV>${project.build.directory}/extra/,src/main/webapp</resourcesAsCSV>
+                        </baseResource>
+                    </webApp>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>generate-resources</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <artifactItems>
+                        <artifactItem>
+                            <groupId>org.apache.shiro.samples</groupId>
+                            <artifactId>samples-spring-client</artifactId>
+                            <version>${project.version}</version>
+                            <type>zip</type>
+                        </artifactItem>
+                    </artifactItems>
+                    <outputDirectory>${project.build.directory}/extra/WEB-INF/resources</outputDirectory>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <configuration>
+                    <webResources>
+                        <resource>
+                            <!-- this is relative to the pom.xml directory -->
+                            <directory>${project.build.directory}/extra</directory>
+                        </resource>
+                    </webResources>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.shiro.samples</groupId>
+            <artifactId>samples-spring-client</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-ehcache</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-spring</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.shiro</groupId>
+            <artifactId>shiro-web</artifactId>
+        </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>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework</groupId>-->
+            <!--<artifactId>spring-context</artifactId>-->
+        <!--</dependency>-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-jdbc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>${hsqldb.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jstl</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+    </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/BootstrapDataPopulator.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/BootstrapDataPopulator.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/BootstrapDataPopulator.java
new file mode 100644
index 0000000..7e50f0a
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/BootstrapDataPopulator.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.samples.spring;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.shiro.crypto.hash.Sha256Hash;
+
+/**
+ * A data populator that creates a set of security tables and test data that can be used by the
+ * Shiro Spring sample application to demonstrate the use of the {@link org.apache.shiro.realm.jdbc.JdbcRealm}
+ * The tables created by this class follow the default table and column names that {@link org.apache.shiro.realm.jdbc.JdbcRealm} uses.
+ *
+ */
+public class BootstrapDataPopulator implements InitializingBean {
+
+    private static final String CREATE_TABLES = "create table users (\n" +
+            "    username varchar(255) primary key,\n" +
+            "    password varchar(255) not null\n" +
+            ");\n" +
+            "\n" +
+            "create table roles (\n" +
+            "    role_name varchar(255) primary key\n" +
+            ");\n" +
+            "\n" +
+            "create table user_roles (\n" +
+            "    username varchar(255) not null,\n" +
+            "    role_name varchar(255) not null,\n" +
+            "    constraint user_roles_uq unique ( username, role_name )\n" +
+            ");\n" +
+            "\n" +
+            "create table roles_permissions (\n" +
+            "    role_name varchar(255) not null,\n" +
+            "    permission varchar(255) not null,\n" +
+            "    primary key (role_name, permission)\n" +
+            ");";
+
+    private static final Logger log = LoggerFactory.getLogger(BootstrapDataPopulator.class);
+
+    protected DataSource dataSource = null;
+
+    public void setDataSource(DataSource dataSource) {
+        this.dataSource = dataSource;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        //because we're using an in-memory hsqldb for the sample app, a new one will be created each time the
+        //app starts, so create the tables and insert the 2 sample users on bootstrap:
+
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
+        jdbcTemplate.execute(CREATE_TABLES);
+
+        //password is 'user1' SHA hashed and base64 encoded:
+        //The first argument to the hash constructor is the actual value to be hased.  The 2nd is the
+        //salt.  In this simple demo scenario, the username and the password are the same, but to clarify the
+        //distinction, you would see this in practice:
+        //new Sha256Hash( <password>, <cryptographically strong randomly generated salt> (not the username!) )
+        String query = "insert into users values ('user1', '" + new Sha256Hash("user1", "user1").toBase64() + "' )";
+        jdbcTemplate.execute(query);
+        log.debug("Created user1.");
+
+        //password is 'user2' SHA hashed and base64 encoded:
+        query = "insert into users values ( 'user2', '"  + new Sha256Hash("user2", "user2").toBase64() + "' )";
+        jdbcTemplate.execute(query);
+        log.debug("Created user2.");
+
+        query = "insert into roles values ( 'role1' )";
+        jdbcTemplate.execute(query);
+        log.debug("Created role1");
+
+        query = "insert into roles values ( 'role2' )";
+        jdbcTemplate.execute(query);
+        log.debug("Created role2");
+
+        query = "insert into roles_permissions values ( 'role1', 'permission1')";
+        jdbcTemplate.execute(query);
+        log.debug("Created permission 1 for role 1");
+
+        query = "insert into roles_permissions values ( 'role1', 'permission2')";
+        jdbcTemplate.execute(query);
+        log.debug("Created permission 2 for role 1");
+
+        query = "insert into roles_permissions values ( 'role2', 'permission1')";
+        jdbcTemplate.execute(query);
+        log.debug("Created permission 1 for role 2");
+
+        query = "insert into user_roles values ( 'user1', 'role1' )";
+        jdbcTemplate.execute(query);
+        query = "insert into user_roles values ( 'user1', 'role2' )";
+        jdbcTemplate.execute(query);
+        log.debug("Assigned user1 roles role1 and role2");
+
+        query = "insert into user_roles values ( 'user2', 'role2' )";
+        jdbcTemplate.execute(query);
+        log.debug("Assigned user2 role role2");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/DefaultSampleManager.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/DefaultSampleManager.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/DefaultSampleManager.java
new file mode 100644
index 0000000..8321ad1
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/DefaultSampleManager.java
@@ -0,0 +1,105 @@
+/*
+ * 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.spring;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+
+
+/**
+ * Default implementation of the {@link SampleManager} interface that stores
+ * and retrieves a value from the user's session.
+ *
+ * @since 0.1
+ */
+public class DefaultSampleManager implements SampleManager {
+
+    /*--------------------------------------------
+    |             C O N S T A N T S             |
+    ============================================*/
+    /**
+     * Key used to store the value in the user's session.
+     */
+    private static final String VALUE_KEY = "sample_value";
+
+    /*--------------------------------------------
+    |    I N S T A N C E   V A R I A B L E S    |
+    ============================================*/
+    private static final Logger log = LoggerFactory.getLogger(DefaultSampleManager.class);
+
+    /*--------------------------------------------
+    |         C O N S T R U C T O R S           |
+    ============================================*/
+
+    /*--------------------------------------------
+    |  A C C E S S O R S / M O D I F I E R S    |
+    ============================================*/
+
+    /*--------------------------------------------
+    |               M E T H O D S               |
+    ============================================*/
+
+    public String getValue() {
+        String value = null;
+
+        Subject subject = SecurityUtils.getSubject();
+        Session session = subject.getSession(false);
+        if (session != null) {
+            value = (String) session.getAttribute(VALUE_KEY);
+            if (log.isDebugEnabled()) {
+                log.debug("retrieving session key [" + VALUE_KEY + "] with value [" + value + "] on session with id [" + session.getId() + "]");
+            }
+        }
+
+        return value;
+    }
+
+    public void setValue(String newValue) {
+        Subject subject = SecurityUtils.getSubject();
+        Session session = subject.getSession();
+
+        if (log.isDebugEnabled()) {
+            log.debug("saving session key [" + VALUE_KEY + "] with value [" + newValue + "] on session with id [" + session.getId() + "]");
+        }
+
+        session.setAttribute(VALUE_KEY, newValue);
+    }
+
+    public void secureMethod1() {
+        if (log.isInfoEnabled()) {
+            log.info("Secure method 1 called...");
+        }
+    }
+
+    public void secureMethod2() {
+        if (log.isInfoEnabled()) {
+            log.info("Secure method 2 called...");
+        }
+    }
+
+    public void secureMethod3() {
+        if (log.isInfoEnabled()) {
+            log.info("Secure method 3 called...");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
new file mode 100644
index 0000000..67a5cca
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ApplicationConfig.java
@@ -0,0 +1,181 @@
+/*
+ * 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.spring.config;
+
+import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
+import org.apache.shiro.cache.CacheManager;
+import org.apache.shiro.cache.ehcache.EhCacheManager;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.samples.spring.BootstrapDataPopulator;
+import org.apache.shiro.samples.spring.DefaultSampleManager;
+import org.apache.shiro.samples.spring.realm.SaltAwareJdbcRealm;
+import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration;
+import org.apache.shiro.spring.config.ShiroBeanConfiguration;
+import org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor;
+import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
+import org.apache.shiro.spring.web.config.ShiroWebConfiguration;
+import org.apache.shiro.spring.web.config.ShiroWebFilterConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+
+import javax.sql.DataSource;
+
+import static org.apache.shiro.web.filter.mgt.DefaultFilter.anon;
+
+/**
+ * Application bean definitions.
+ */
+@Configuration
+@PropertySource("classpath:application.properties")
+@Import({ShiroBeanConfiguration.class,
+        ShiroAnnotationProcessorConfiguration.class,
+        ShiroWebConfiguration.class,
+        ShiroWebFilterConfiguration.class,
+        JspViewsConfig.class,
+        RemotingServletConfig.class})
+@ComponentScan("org.apache.shiro.samples.spring")
+public class ApplicationConfig {
+
+
+    /**
+     *Populates the sample database with sample users and roles.
+     * @param dataSource
+     * @return
+     */
+    @Bean
+    protected BootstrapDataPopulator bootstrapDataPopulator(DataSource dataSource) {
+        BootstrapDataPopulator populator =new BootstrapDataPopulator();
+        populator.setDataSource(dataSource);
+        return populator;
+    }
+
+
+    /**
+     * Used by the SecurityManager to access security data (users, roles, etc).
+     * Many other realm implementations can be used too (PropertiesRealm,
+     * LdapRealm, etc.
+     * @param dataSource
+     * @return
+     */
+    @Bean
+    protected SaltAwareJdbcRealm jdbcRealm(DataSource dataSource) {
+
+        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
+        credentialsMatcher.setHashAlgorithmName("SHA-256");
+        credentialsMatcher.setStoredCredentialsHexEncoded(false);
+
+        SaltAwareJdbcRealm jdbcRealm = new SaltAwareJdbcRealm();
+        jdbcRealm.setName("jdbcRealm");
+        jdbcRealm.setCredentialsMatcher(credentialsMatcher);
+        jdbcRealm.setDataSource(dataSource);
+
+        return jdbcRealm;
+    }
+
+
+    /**
+     * Let's use some enterprise caching support for better performance.  You can replace this with any enterprise
+     * caching framework implementation that you like (Terracotta+Ehcache, Coherence, GigaSpaces, etc
+     *
+     *
+     * @return
+     */
+    @Bean
+    protected EhCacheManager cacheManager() {
+
+        EhCacheManager ehCacheManager = new EhCacheManager();
+
+        // Set a net.sf.ehcache.CacheManager instance here if you already have one.
+        // If not, a new one will be creaed with a default config:
+        // ehCacheManager.setCacheManager(...);
+
+        // If you don't have a pre-built net.sf.ehcache.CacheManager instance to inject, but you want
+        // a specific Ehcache configuration to be used, specify that here.  If you don't, a default
+        //will be used.:
+        // ehCacheManager.setCacheManagerConfigFile("classpath:some/path/to/ehcache.xml");
+
+        return ehCacheManager;
+    }
+
+    /**
+     * Secure Spring remoting:  Ensure any Spring Remoting method invocations can be associated
+     * with a Subject for security checks.
+     * @param securityManager
+     * @return
+     */
+    @Bean
+    protected SecureRemoteInvocationExecutor secureRemoteInvocationExecutor(SecurityManager securityManager) {
+
+        SecureRemoteInvocationExecutor executor = new SecureRemoteInvocationExecutor();
+        executor.setSecurityManager(securityManager);
+
+        return executor;
+    }
+
+
+    /**
+     * Simulated business-tier "Manager", not Shiro related, just an example
+     * @return
+     */
+    @Bean
+    protected DefaultSampleManager sampleManager() {
+        return new DefaultSampleManager();
+    }
+
+    /**
+     * Sample RDBMS data source that would exist in any application - not Shiro related.
+     * @return
+     */
+    @Bean
+    protected DriverManagerDataSource dataSource() {
+
+        DriverManagerDataSource dataSource = new DriverManagerDataSource();
+        dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
+        dataSource.setUrl("jdbc:hsqldb:mem:shiro-spring");
+        dataSource.setUsername("sa");
+
+        return dataSource;
+    }
+
+    @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");
+
+
+        chainDefinition.addPathDefinition("/favicon.ico", "anon");
+        chainDefinition.addPathDefinition("/logo.png", "anon");
+        chainDefinition.addPathDefinition("/shiro.css", "anon");
+        chainDefinition.addPathDefinition("/s/login", "anon");
+        chainDefinition.addPathDefinition("/*.jar", "anon"); //allow WebStart to pull the jars for the swing app
+        chainDefinition.addPathDefinition("/remoting/**", "anon"); // protected using SecureRemoteInvocationExecutor
+        chainDefinition.addPathDefinition("/**", "authc");
+
+
+        return chainDefinition;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
new file mode 100644
index 0000000..551089c
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/JspViewsConfig.java
@@ -0,0 +1,65 @@
+/*
+ * 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.spring.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+import org.springframework.web.servlet.view.JstlView;
+
+/**
+ * JSP / HTML views and resource bean definitions.
+ */
+@Configuration
+@ComponentScan("org.apache.shiro.samples.spring")
+@EnableWebMvc
+public class JspViewsConfig extends WebMvcConfigurerAdapter {
+
+    @Bean
+    @Order(1)
+    public ViewResolver getViewResolver(){
+        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
+        resolver.setViewClass(JstlView.class);
+        resolver.setPrefix("/WEB-INF/resources/");
+        resolver.setSuffix(".jsp");
+        return resolver;
+    }
+
+    @Bean
+    @Order(0)
+    public ViewResolver jnlpViewResolver() {
+        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
+        resolver.setViewClass(JstlView.class);
+        resolver.setPrefix("/WEB-INF/jnlp/");
+        resolver.setSuffix(".jsp");
+        return resolver;
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("*.css", "*.png").addResourceLocations("/");
+        registry.addResourceHandler("*.jar", "*.pack").addResourceLocations("/WEB-INF/resources/");
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/RemotingServletConfig.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/RemotingServletConfig.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/RemotingServletConfig.java
new file mode 100644
index 0000000..9d79bca
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/RemotingServletConfig.java
@@ -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.
+ */
+package org.apache.shiro.samples.spring.config;
+
+import org.apache.shiro.samples.spring.SampleManager;
+import org.apache.shiro.spring.remoting.SecureRemoteInvocationExecutor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
+
+/**
+ * Remoting bean definitions.
+ */
+@Configuration
+@ComponentScan("org.apache.shiro.samples.spring")
+public class RemotingServletConfig {
+
+    @Bean(name = "/sampleManager")
+    public HttpInvokerServiceExporter accountServiceExporter(SampleManager sampleManager,
+                                                             SecureRemoteInvocationExecutor secureRemoteInvocationExecutor) {
+
+        HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
+        httpInvokerServiceExporter.setService(sampleManager);
+        httpInvokerServiceExporter.setServiceInterface(SampleManager.class);
+        httpInvokerServiceExporter.setRemoteInvocationExecutor(secureRemoteInvocationExecutor);
+        return httpInvokerServiceExporter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ServletApplicationInitializer.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ServletApplicationInitializer.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ServletApplicationInitializer.java
new file mode 100644
index 0000000..66e503a
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/config/ServletApplicationInitializer.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.samples.spring.config;
+
+import org.springframework.web.WebApplicationInitializer;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
+import org.springframework.web.filter.DelegatingFilterProxy;
+import org.springframework.web.servlet.DispatcherServlet;
+import org.springframework.web.util.Log4jConfigListener;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRegistration;
+import java.util.EnumSet;
+
+/**
+ * Initializes Spring Environment without the need for a web.xml
+ */
+public class ServletApplicationInitializer implements WebApplicationInitializer {
+
+    @Override
+    public void onStartup(ServletContext container) {
+
+        //now add the annotations
+        AnnotationConfigWebApplicationContext appContext = getContext();
+
+        // Manage the lifecycle of the root application context
+        container.addListener(new ContextLoaderListener(appContext));
+
+        container.addListener(new Log4jConfigListener());
+
+        FilterRegistration.Dynamic shiroFilter = container.addFilter("shiroFilterFactoryBean", DelegatingFilterProxy.class);
+        shiroFilter.setInitParameter("targetFilterLifecycle", "true");
+        shiroFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
+
+
+        ServletRegistration.Dynamic remotingDispatcher = container.addServlet("remoting", new DispatcherServlet(appContext));
+        remotingDispatcher.setLoadOnStartup(1);
+        remotingDispatcher.addMapping("/remoting/*");
+
+
+        ServletRegistration.Dynamic dispatcher = container.addServlet("DispatcherServlet", new DispatcherServlet(appContext));
+        dispatcher.setLoadOnStartup(1);
+        dispatcher.addMapping("/");
+
+    }
+
+    private AnnotationConfigWebApplicationContext getContext() {
+        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
+        context.setConfigLocation(getClass().getPackage().getName());
+        return context;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/realm/SaltAwareJdbcRealm.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/realm/SaltAwareJdbcRealm.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/realm/SaltAwareJdbcRealm.java
new file mode 100644
index 0000000..56448d0
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/realm/SaltAwareJdbcRealm.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.samples.spring.realm;
+
+import org.apache.shiro.authc.*;
+import org.apache.shiro.realm.jdbc.JdbcRealm;
+import org.apache.shiro.util.ByteSource;
+import org.apache.shiro.util.JdbcUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Realm that exists to support salted credentials.  The JdbcRealm implementation needs to be updated in a future
+ * Shiro release to handle this.
+ */
+public class SaltAwareJdbcRealm extends JdbcRealm {
+
+    private static final Logger log = LoggerFactory.getLogger(SaltAwareJdbcRealm.class);
+
+    @Override
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
+        UsernamePasswordToken upToken = (UsernamePasswordToken) token;
+        String username = upToken.getUsername();
+
+        // Null username is invalid
+        if (username == null) {
+            throw new AccountException("Null usernames are not allowed by this realm.");
+        }
+
+        Connection conn = null;
+        AuthenticationInfo info = null;
+        try {
+            conn = dataSource.getConnection();
+
+            String password = getPasswordForUser(conn, username);
+
+            if (password == null) {
+                throw new UnknownAccountException("No account found for user [" + username + "]");
+            }
+
+            SimpleAuthenticationInfo saInfo = new SimpleAuthenticationInfo(username, password, getName());
+            /**
+             * This (very bad) example uses the username as the salt in this sample app.  DON'T DO THIS IN A REAL APP!
+             *
+             * Salts should not be based on anything that a user could enter (attackers can exploit this).  Instead
+             * they should ideally be cryptographically-strong randomly generated numbers.
+             */
+            saInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
+
+            info = saInfo;
+
+        } catch (SQLException e) {
+            final String message = "There was a SQL error while authenticating user [" + username + "]";
+            if (log.isErrorEnabled()) {
+                log.error(message, e);
+            }
+
+            // Rethrow any SQL errors as an authentication exception
+            throw new AuthenticationException(message, e);
+        } finally {
+            JdbcUtils.closeConnection(conn);
+        }
+
+        return info;
+    }
+
+    private String getPasswordForUser(Connection conn, String username) throws SQLException {
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        String password = null;
+        try {
+            ps = conn.prepareStatement(authenticationQuery);
+            ps.setString(1, username);
+
+            // Execute query
+            rs = ps.executeQuery();
+
+            // Loop over results - although we are only expecting one result, since usernames should be unique
+            boolean foundResult = false;
+            while (rs.next()) {
+
+                // Check to ensure only one row is processed
+                if (foundResult) {
+                    throw new AuthenticationException("More than one user row found for user [" + username + "]. Usernames must be unique.");
+                }
+
+                password = rs.getString(1);
+
+                foundResult = true;
+            }
+        } finally {
+            JdbcUtils.closeResultSet(rs);
+            JdbcUtils.closeStatement(ps);
+        }
+
+        return password;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/IndexController.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/IndexController.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/IndexController.java
new file mode 100644
index 0000000..97609db
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/IndexController.java
@@ -0,0 +1,111 @@
+/*
+ * 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.spring.web;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.samples.spring.SampleManager;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Spring MVC controller responsible for rendering the Shiro Spring sample
+ * application index page.
+ *
+ * @since 0.1
+ */
+@Controller
+@RequestMapping("/s/index")
+public class IndexController {
+
+    /*--------------------------------------------
+    |             C O N S T A N T S             |
+    ============================================*/
+
+    /*--------------------------------------------
+    |    I N S T A N C E   V A R I A B L E S    |
+    ============================================*/
+
+    @Autowired
+    private SampleManager sampleManager;
+
+    /*--------------------------------------------
+    |         C O N S T R U C T O R S           |
+    ============================================*/
+
+    /*--------------------------------------------
+    |  A C C E S S O R S / M O D I F I E R S    |
+    ============================================*/
+
+    public void setSampleManager(SampleManager sampleManager) {
+        this.sampleManager = sampleManager;
+    }
+
+    /*--------------------------------------------
+    |               M E T H O D S               |
+    ============================================*/
+
+    @RequestMapping(method = RequestMethod.GET)
+    protected String doGet(Model model) {
+
+        buildModel(model);
+        model.addAttribute("value", sampleManager.getValue());
+
+        return "sampleIndex";
+    }
+
+    protected Model buildModel(Model model) {
+
+        Subject subject = SecurityUtils.getSubject();
+        boolean hasRole1 = subject.hasRole("role1");
+        boolean hasRole2 = subject.hasRole("role2");
+
+        model.addAttribute("hasRole1", hasRole1);
+        model.addAttribute("hasRole2", hasRole2);
+
+        Session session = subject.getSession();
+        Map<Object, Object> sessionAttributes = new LinkedHashMap<Object, Object>();
+        for (Object key : session.getAttributeKeys()) {
+            sessionAttributes.put(key, session.getAttribute(key));
+        }
+        model.addAttribute("sessionAttributes", sessionAttributes);
+
+        model.addAttribute("subjectSession", subject.getSession());
+        return model;
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    protected String doPost(@RequestParam("value") String newSessionValue, Model model) {
+
+        sampleManager.setValue(newSessionValue);
+
+        buildModel(model);
+        model.addAttribute("value", sampleManager.getValue());
+
+        return "sampleIndex";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/JnlpController.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/JnlpController.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/JnlpController.java
new file mode 100644
index 0000000..686ced9
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/JnlpController.java
@@ -0,0 +1,104 @@
+/*
+ * 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.spring.web;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.Subject;
+
+/**
+ * Controller used to dynamically build a JNLP file used to launch the Shiro
+ * Spring WebStart sample application.
+ *
+ * @since 0.1
+ */
+@Component
+@RequestMapping("/s/shiro.jnlp")
+public class JnlpController extends AbstractController {
+
+    /*--------------------------------------------
+    |             C O N S T A N T S             |
+    ============================================*/
+
+    /*--------------------------------------------
+    |    I N S T A N C E   V A R I A B L E S    |
+    ============================================*/
+    private String jnlpView = "shiro.jnlp";
+
+    /*--------------------------------------------
+    |         C O N S T R U C T O R S           |
+    ============================================*/
+
+    /*--------------------------------------------
+    |  A C C E S S O R S / M O D I F I E R S    |
+    ============================================*/
+
+    public void setJnlpView(String jnlpView) {
+        this.jnlpView = jnlpView;
+    }
+
+    /*--------------------------------------------
+    |               M E T H O D S               |
+    ============================================*/
+
+    @RequestMapping(method = RequestMethod.GET)
+    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+        Subject subject = SecurityUtils.getSubject();
+        Session session = null;
+
+        if (subject != null) {
+            session = subject.getSession();
+        }
+        if (session == null) {
+            String msg = "Expected a non-null Shiro session.";
+            throw new IllegalArgumentException(msg);
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("http://");
+        sb.append(request.getServerName());
+        if (request.getServerPort() != 80) {
+            sb.append(":");
+            sb.append(request.getServerPort());
+        }
+        sb.append(request.getContextPath());
+
+        // prevent JNLP caching by setting response headers
+        response.setHeader("cache-control", "no-cache");
+        response.setHeader("pragma", "no-cache");
+
+        Map<String, Object> model = new HashMap<String, Object>();
+        model.put("codebaseUrl", sb.toString());
+        model.put("sessionId", session.getId());
+        return new ModelAndView(jnlpView, model);
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LoginController.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LoginController.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LoginController.java
new file mode 100644
index 0000000..95a47a6
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LoginController.java
@@ -0,0 +1,68 @@
+/*
+ * 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.spring.web;
+
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * Spring MVC controller responsible for authenticating the user.
+ *
+ * @since 0.1
+ */
+@Component
+@RequestMapping("/s/login")
+public class LoginController {
+
+    private static transient final Logger log = LoggerFactory.getLogger(LoginController.class);
+
+    private static String loginView = "login";
+
+    @RequestMapping(method = RequestMethod.GET)
+    protected String view() {
+        return loginView;
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    protected String onSubmit(@RequestParam("username") String username,
+                              @RequestParam("password") String password,
+                              Model model) throws Exception {
+
+        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
+
+        try {
+            SecurityUtils.getSubject().login(token);
+        } catch (AuthenticationException e) {
+            log.debug("Error authenticating.", e);
+            model.addAttribute("errorInvalidLogin", "The username or password was not correct.");
+
+            return loginView;
+        }
+
+        return "redirect:/s/index";
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LogoutController.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LogoutController.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LogoutController.java
new file mode 100644
index 0000000..7a8b5a8
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/LogoutController.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.samples.spring.web;
+
+import org.apache.shiro.SecurityUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Controller responsible for logging out the current user by invoking
+ * {@link org.apache.shiro.subject.Subject#logout()}
+ *
+ * @since 0.1
+ */
+@Component
+@RequestMapping("/s/logout")
+public class LogoutController extends AbstractController {
+
+    @RequestMapping(method = RequestMethod.GET)
+    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
+        SecurityUtils.getSubject().logout();
+        return new ModelAndView("redirect:login");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/RootRedirectController.java
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/RootRedirectController.java b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/RootRedirectController.java
new file mode 100644
index 0000000..6f64306
--- /dev/null
+++ b/samples/spring-mvc/src/main/java/org/apache/shiro/samples/spring/web/RootRedirectController.java
@@ -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.
+ */
+package org.apache.shiro.samples.spring.web;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * Implements the root {@code welcome-file}j as a {@code @RequestMapping}.
+ */
+@Controller
+@RequestMapping({"/"})
+public class RootRedirectController {
+
+    @RequestMapping(method = RequestMethod.GET)
+    public String redirect() {
+        return "redirect:/s/login";
+    }
+}

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/resources/application.properties
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/resources/application.properties b/samples/spring-mvc/src/main/resources/application.properties
new file mode 100644
index 0000000..f78b8fd
--- /dev/null
+++ b/samples/spring-mvc/src/main/resources/application.properties
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+
+# Let Shiro Manage the sessions
+shiro.userNativeSessionManager = true
+
+# disable URL session rewriting
+shiro.sessionManager.sessionIdUrlRewritingEnabled = false
+
+shiro.loginUrl = /s/login
+shiro.successUrl = /s/index
+shiro.unauthorizedUrl = /s/unauthorized

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/resources/ehcache.xml
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/resources/ehcache.xml b/samples/spring-mvc/src/main/resources/ehcache.xml
new file mode 100644
index 0000000..eb3504d
--- /dev/null
+++ b/samples/spring-mvc/src/main/resources/ehcache.xml
@@ -0,0 +1,98 @@
+<!--
+  ~ 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.
+  -->
+
+<!-- EhCache XML configuration file used for Shiro spring sample application -->
+<ehcache>
+
+    <!-- Sets the path to the directory where cache .data files are created.
+
+If the path is a Java System Property it is replaced by
+its value in the running VM.
+
+The following properties are translated:
+user.home - User's home directory
+user.dir - User's current working directory
+java.io.tmpdir - Default temp file path -->
+    <diskStore path="java.io.tmpdir/shiro-spring-sample"/>
+
+
+    <!--Default Cache configuration. These will applied to caches programmatically created through
+    the CacheManager.
+
+    The following attributes are required:
+
+    maxElementsInMemory            - Sets the maximum number of objects that will be created in memory
+    eternal                        - Sets whether elements are eternal. If eternal,  timeouts are ignored and the
+                                     element is never expired.
+    overflowToDisk                 - Sets whether elements can overflow to disk when the in-memory cache
+                                     has reached the maxInMemory limit.
+
+    The following attributes are optional:
+    timeToIdleSeconds              - Sets the time to idle for an element before it expires.
+                                     i.e. The maximum amount of time between accesses before an element expires
+                                     Is only used if the element is not eternal.
+                                     Optional attribute. A value of 0 means that an Element can idle for infinity.
+                                     The default value is 0.
+    timeToLiveSeconds              - Sets the time to live for an element before it expires.
+                                     i.e. The maximum time between creation time and when an element expires.
+                                     Is only used if the element is not eternal.
+                                     Optional attribute. A value of 0 means that and Element can live for infinity.
+                                     The default value is 0.
+    diskPersistent                 - Whether the disk store persists between restarts of the Virtual Machine.
+                                     The default value is false.
+    diskExpiryThreadIntervalSeconds- The number of seconds between runs of the disk expiry thread. The default value
+                                     is 120 seconds.
+    memoryStoreEvictionPolicy      - Policy would be enforced upon reaching the maxElementsInMemory limit. Default
+                                     policy is Least Recently Used (specified as LRU). Other policies available -
+                                     First In First Out (specified as FIFO) and Less Frequently Used
+                                     (specified as LFU)
+    -->
+
+    <defaultCache
+            maxElementsInMemory="10000"
+            eternal="false"
+            timeToIdleSeconds="120"
+            timeToLiveSeconds="120"
+            overflowToDisk="false"
+            diskPersistent="false"
+            diskExpiryThreadIntervalSeconds="120"
+            />
+
+    <!-- We want eternal="true" (with no timeToIdle or timeToLive settings) because Shiro manages session
+expirations explicitly.  If we set it to false and then set corresponding timeToIdle and timeToLive properties,
+ehcache would evict sessions without Shiro's knowledge, which would cause many problems
+(e.g. "My Shiro session timeout is 30 minutes - why isn't a session available after 2 minutes?"
+Answer - ehcache expired it due to the timeToIdle property set to 120 seconds.)
+
+diskPersistent=true since we want an enterprise session management feature - ability to use sessions after
+even after a JVM restart.  -->
+    <cache name="shiro-activeSessionCache"
+           maxElementsInMemory="10000"
+           eternal="true"
+           overflowToDisk="true"
+           diskPersistent="true"
+           diskExpiryThreadIntervalSeconds="600"/>
+
+    <cache name="org.apache.shiro.realm.SimpleAccountRealm.authorization"
+           maxElementsInMemory="100"
+           eternal="false"
+           timeToLiveSeconds="600"
+           overflowToDisk="false"/>
+
+</ehcache>

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/resources/jsecurity-sample.jks
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/resources/jsecurity-sample.jks b/samples/spring-mvc/src/main/resources/jsecurity-sample.jks
new file mode 100644
index 0000000..eb2ff9b
Binary files /dev/null and b/samples/spring-mvc/src/main/resources/jsecurity-sample.jks differ

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/resources/log4j.properties b/samples/spring-mvc/src/main/resources/log4j.properties
new file mode 100644
index 0000000..829ad67
--- /dev/null
+++ b/samples/spring-mvc/src/main/resources/log4j.properties
@@ -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.
+#
+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 %p [%c] - %m %n
+
+# General Apache libraries
+log4j.logger.org.apache=WARN
+
+# Spring
+log4j.logger.org.springframework=INFO
+
+# Default Shiro logging
+log4j.logger.org.apache.shiro=TRACE
+
+# Disable verbose logging
+log4j.logger.org.apache.shiro.util.ThreadContext=WARN
+log4j.logger.org.apache.shiro.cache.ehcache.EhCache=WARN

http://git-wip-us.apache.org/repos/asf/shiro/blob/03cad012/samples/spring-mvc/src/main/webapp/WEB-INF/resources/include.jsp
----------------------------------------------------------------------
diff --git a/samples/spring-mvc/src/main/webapp/WEB-INF/resources/include.jsp b/samples/spring-mvc/src/main/webapp/WEB-INF/resources/include.jsp
new file mode 100644
index 0000000..f65884f
--- /dev/null
+++ b/samples/spring-mvc/src/main/webapp/WEB-INF/resources/include.jsp
@@ -0,0 +1,24 @@
+<%--
+  ~ 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 session="false" %>
+
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
+<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
\ No newline at end of file


Mime
View raw message