This is an automated email from the ASF dual-hosted git repository.
lprimak pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shiro.git
The following commit(s) were added to refs/heads/main by this push:
new 04aa9eb54 [GH-891] Added Spring Boot 3 example application fixes #891
04aa9eb54 is described below
commit 04aa9eb54604d5c8790838e6339bb7f7aed78e71
Author: lprimak <[email protected]>
AuthorDate: Mon Jul 3 22:06:45 2023 -0500
[GH-891] Added Spring Boot 3 example application
fixes #891
---
pom.xml | 5 -
samples/pom.xml | 1 +
samples/spring-boot-3-web/README.md | 17 +++
samples/spring-boot-3-web/pom.xml | 126 +++++++++++++++++++++
.../shiro/samples/AccountInfoController.java | 52 +++++++++
.../org/apache/shiro/samples/HelloController.java | 61 ++++++++++
.../org/apache/shiro/samples/LoginController.java | 34 ++++++
.../shiro/samples/RestrictedErrorController.java | 54 +++++++++
.../main/java/org/apache/shiro/samples/WebApp.java | 96 ++++++++++++++++
.../src/main/resources/META-INF/NOTICE | 15 +++
.../src/main/resources/application.properties | 26 +++++
.../src/main/resources/templates/account-info.html | 39 +++++++
.../src/main/resources/templates/error.html | 39 +++++++
.../main/resources/templates/fragments/head.html | 54 +++++++++
.../src/main/resources/templates/hello.html | 45 ++++++++
.../src/main/resources/templates/login.html | 91 +++++++++++++++
16 files changed, 750 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index e39bcb18c..c062113ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -854,11 +854,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-api</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
diff --git a/samples/pom.xml b/samples/pom.xml
index 7f53a2655..d1204c85c 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -46,6 +46,7 @@
<module>spring-hibernate</module>
<module>spring-boot</module>
<module>spring-boot-web</module>
+ <module>spring-boot-3-web</module>
<module>guice</module>
<module>quickstart-guice</module>
<module>servlet-plugin</module>
diff --git a/samples/spring-boot-3-web/README.md
b/samples/spring-boot-3-web/README.md
new file mode 100644
index 000000000..8d2474d9b
--- /dev/null
+++ b/samples/spring-boot-3-web/README.md
@@ -0,0 +1,17 @@
+Apache Shiro + Spring Boot 3 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/`
+
+Or deploy to Heroku:
+
+[](https://heroku.com/deploy?template=https://github.com/bdemers/heroku-examples-runner&env\[ARTIFACT_ID\]=samples-spring-boot-web&&env\[RUNNER\]=spring-boot)
diff --git a/samples/spring-boot-3-web/pom.xml
b/samples/spring-boot-3-web/pom.xml
new file mode 100644
index 000000000..0a10ef9de
--- /dev/null
+++ b/samples/spring-boot-3-web/pom.xml
@@ -0,0 +1,126 @@
+<?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
https://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>2.0.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>samples-spring-boot-3-web</artifactId>
+ <name>Apache Shiro :: Samples :: Spring Boot 3 Web</name>
+ <packaging>war</packaging>
+
+ <properties>
+ <module.name>samples.spring.boot3.web</module.name>
+ <spring-boot.version>3.1.1</spring-boot.version>
+<!-- below versions are not necessary in "real" applications -->
+ <spring.version>6.0.10</spring.version>
+ <slf4j.version>2.0.7</slf4j.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-core</artifactId>
+ <classifier>jakarta</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-web</artifactId>
+ <classifier>jakarta</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-spring-boot-web-starter</artifactId>
+ <classifier>jakarta</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-spring-boot-starter</artifactId>
+ <classifier>jakarta</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-spring</artifactId>
+ <classifier>jakarta</classifier>
+ </dependency>
+
+ <!-- Spring Boot -->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-configuration-processor</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+<!-- below dependencies are not necessary in "real" applications -->
+ <dependency>
+ <groupId>jakarta.servlet</groupId>
+ <artifactId>jakarta.servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-dependencies</artifactId>
+ <version>${spring-boot.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.shiro</groupId>
+ <artifactId>shiro-bom</artifactId>
+ <version>${project.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <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>
diff --git
a/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/AccountInfoController.java
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/AccountInfoController.java
new file mode 100644
index 000000000..5c75380ec
--- /dev/null
+++
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/AccountInfoController.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.samples;
+
+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.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 (principalCollection != null && !principalCollection.isEmpty()) {
+ name = principalCollection.getPrimaryPrincipal().toString();
+ }
+
+ model.addAttribute("name", name);
+
+ return "account-info";
+ }
+
+}
diff --git
a/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/HelloController.java
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/HelloController.java
new file mode 100644
index 000000000..f4dd27a32
--- /dev/null
+++
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/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.samples;
+
+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 jakarta.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 (principalCollection != null && !principalCollection.isEmpty()) {
+ 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";
+ }
+
+}
diff --git
a/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/LoginController.java
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/LoginController.java
new file mode 100644
index 000000000..f90fe337a
--- /dev/null
+++
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/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.samples;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+
+@Controller
+public class LoginController {
+
+ @RequestMapping("/login.html")
+ public String loginTemplate() {
+
+ return "login";
+ }
+
+}
diff --git
a/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/RestrictedErrorController.java
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/RestrictedErrorController.java
new file mode 100644
index 000000000..e7a5e5df5
--- /dev/null
+++
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/RestrictedErrorController.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.samples;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.error.ErrorAttributeOptions;
+import org.springframework.boot.web.servlet.error.ErrorAttributes;
+import org.springframework.boot.web.servlet.error.ErrorController;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.context.request.ServletWebRequest;
+
+import jakarta.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ */
+@Controller
+public class RestrictedErrorController implements ErrorController {
+ private static final String ERROR_PATH = "/error";
+
+ @Autowired
+ private ErrorAttributes errorAttributes;
+
+ public String getErrorPath() {
+ return ERROR_PATH;
+ }
+
+ @RequestMapping(ERROR_PATH)
+ String error(HttpServletRequest request, Model model) {
+ Map<String, Object> errorMap = errorAttributes.getErrorAttributes(
+ new ServletWebRequest(request),
+
ErrorAttributeOptions.of(ErrorAttributeOptions.Include.MESSAGE));
+ model.addAttribute("errors", errorMap);
+ return "error";
+ }
+}
diff --git
a/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/WebApp.java
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/WebApp.java
new file mode 100644
index 000000000..819db0f0d
--- /dev/null
+++
b/samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/WebApp.java
@@ -0,0 +1,96 @@
+/*
+ * 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.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.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.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 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();
+ }
+}
diff --git a/samples/spring-boot-3-web/src/main/resources/META-INF/NOTICE
b/samples/spring-boot-3-web/src/main/resources/META-INF/NOTICE
new file mode 100644
index 000000000..9d26a95ff
--- /dev/null
+++ b/samples/spring-boot-3-web/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,15 @@
+Apache Shiro
+Copyright 2008-2020 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+The implementation for org.apache.shiro.util.SoftHashMap is based
+on initial ideas from Dr. Heinz Kabutz's publicly posted version
+available at http://www.javaspecialists.eu/archive/Issue015.html,
+with continued modifications.
+
+Certain parts (StringUtils, IpAddressMatcher, etc.) of the source
+code for this product was copied for simplicity and to reduce
+dependencies from the source code developed by the Spring Framework
+Project (http://www.springframework.org).
diff --git
a/samples/spring-boot-3-web/src/main/resources/application.properties
b/samples/spring-boot-3-web/src/main/resources/application.properties
new file mode 100644
index 000000000..852dc7493
--- /dev/null
+++ b/samples/spring-boot-3-web/src/main/resources/application.properties
@@ -0,0 +1,26 @@
+#
+# 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
+
+# Let Shiro Manage the sessions
+shiro.userNativeSessionManager = true
+
+# disable URL session rewriting
+shiro.sessionManager.sessionIdUrlRewritingEnabled = false
\ No newline at end of file
diff --git
a/samples/spring-boot-3-web/src/main/resources/templates/account-info.html
b/samples/spring-boot-3-web/src/main/resources/templates/account-info.html
new file mode 100644
index 000000000..1fc0ca95b
--- /dev/null
+++ b/samples/spring-boot-3-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
diff --git a/samples/spring-boot-3-web/src/main/resources/templates/error.html
b/samples/spring-boot-3-web/src/main/resources/templates/error.html
new file mode 100644
index 000000000..be216512b
--- /dev/null
+++ b/samples/spring-boot-3-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/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
diff --git
a/samples/spring-boot-3-web/src/main/resources/templates/fragments/head.html
b/samples/spring-boot-3-web/src/main/resources/templates/fragments/head.html
new file mode 100644
index 000000000..58ab413e9
--- /dev/null
+++ b/samples/spring-boot-3-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
diff --git a/samples/spring-boot-3-web/src/main/resources/templates/hello.html
b/samples/spring-boot-3-web/src/main/resources/templates/hello.html
new file mode 100644
index 000000000..cc198be78
--- /dev/null
+++ b/samples/spring-boot-3-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> (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
diff --git a/samples/spring-boot-3-web/src/main/resources/templates/login.html
b/samples/spring-boot-3-web/src/main/resources/templates/login.html
new file mode 100644
index 000000000..7c9c5aae1
--- /dev/null
+++ b/samples/spring-boot-3-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