Spring Boot + Spring Security + пример Thymeleaf
Пример Spring Boot Thymeleaf использует Spring Security для защиты путей/admin
и/user
Используемые технологии:
-
Spring Boot 1.5.3.RELEASE
-
Весна 4.3.8. РЕЛИЗ
-
Spring Security 4.2.2
-
Тимелист 2.1.5. ВЫПУСК
-
Дополнения Thymeleaf Spring Security4 2.1.3
-
Tomcat Embed 8.5.14
-
Maven 3
-
Java 8
1. Каталог проектов
2. Зависимости проекта
Объявляетspring-boot-starter-security
, он получит все, что вам нужно для разработки веб-приложенияSpring Boot + Spring Security
.
pom.xml
4.0.0 spring-boot-web-spring-security jar Spring Boot Web Spring Security Spring Boot Web Spring Security Example https://www.example.com 1.0 org.springframework.boot spring-boot-starter-parent 1.5.3.RELEASE 1.8 org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-thymeleaf org.thymeleaf.extras thymeleaf-extras-springsecurity4 org.springframework.boot spring-boot-devtools true org.webjars bootstrap 3.3.7 org.springframework.boot spring-boot-maven-plugin
Показать зависимости проекта:
$ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Spring Boot Web Spring Security 1.0 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-dependency-plugin:2.10:tree (default-cli) @ spring-boot-web-spring-security --- [INFO] org.springframework.boot:spring-boot-web-spring-security:jar:1.0 [INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:1.5.3.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.5.3.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.3.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.11:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.11:compile [INFO] | | | +- org.slf4j:jcl-over-slf4j:jar:1.7.25:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.25:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.25:compile [INFO] | | +- org.springframework:spring-core:jar:4.3.8.RELEASE:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-web:jar:1.5.3.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.5.3.RELEASE:compile [INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.14:compile [INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.14:compile [INFO] | | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.14:compile [INFO] | | +- org.hibernate:hibernate-validator:jar:5.3.5.Final:compile [INFO] | | | +- javax.validation:validation-api:jar:1.1.0.Final:compile [INFO] | | | +- org.jboss.logging:jboss-logging:jar:3.3.1.Final:compile [INFO] | | | \- com.fasterxml:classmate:jar:1.3.3:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.8:compile [INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.0:compile [INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.8:compile [INFO] | | +- org.springframework:spring-web:jar:4.3.8.RELEASE:compile [INFO] | | \- org.springframework:spring-webmvc:jar:4.3.8.RELEASE:compile [INFO] | +- org.thymeleaf:thymeleaf-spring4:jar:2.1.5.RELEASE:compile [INFO] | | \- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile [INFO] | | +- ognl:ognl:jar:3.0.8:compile [INFO] | | +- org.javassist:javassist:jar:3.21.0-GA:compile [INFO] | | \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile [INFO] | \- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:1.4.0:compile [INFO] | \- org.codehaus.groovy:groovy:jar:2.4.10:compile [INFO] +- org.springframework.boot:spring-boot-starter-security:jar:1.5.3.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:4.3.8.RELEASE:compile [INFO] | | \- org.springframework:spring-beans:jar:4.3.8.RELEASE:compile [INFO] | +- org.springframework.security:spring-security-config:jar:4.2.2.RELEASE:compile [INFO] | | +- org.springframework.security:spring-security-core:jar:4.2.2.RELEASE:compile [INFO] | | \- org.springframework:spring-context:jar:4.3.8.RELEASE:compile [INFO] | \- org.springframework.security:spring-security-web:jar:4.2.2.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:4.3.8.RELEASE:compile [INFO] +- org.thymeleaf.extras:thymeleaf-extras-springsecurity4:jar:2.1.3.RELEASE:compile [INFO] | \- org.slf4j:slf4j-api:jar:1.7.25:compile [INFO] +- org.springframework.boot:spring-boot-devtools:jar:1.5.3.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot:jar:1.5.3.RELEASE:compile [INFO] | \- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.3.RELEASE:compile [INFO] \- org.webjars:bootstrap:jar:3.3.7:compile [INFO] \- org.webjars:jquery:jar:1.11.1:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.072 s [INFO] Finished at: 2017-05-04T10:13:05+08:00 [INFO] Final Memory: 19M/309M [INFO] ------------------------------------------------------------------------
3. Spring Security
3.1 Extends WebSecurityConfigurerAdapter
, and defined the security rules in the configure
method.
Для пользователя «admin»:
-
Возможность доступа к странице
/admin
-
Невозможно получить доступ к странице
/user
, перенаправление на страницу 403 отказано в доступе.
Для пользователя «пользователь»:
-
может получить доступ к странице
/user
-
невозможно получить доступ к странице
/admin
, перенаправление на страницу 403 отказано в доступе.
SpringSecurityConfig.java
package com.example.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.access.AccessDeniedHandler; @Configuration public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AccessDeniedHandler accessDeniedHandler; // roles admin allow to access /admin/** // roles user allow to access /user/** // custom 403 access denied handler @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/", "/home", "/about").permitAll() .antMatchers("/admin/**").hasAnyRole("ADMIN") .antMatchers("/user/**").hasAnyRole("USER") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .exceptionHandling().accessDeniedHandler(accessDeniedHandler); } // create two users, admin and user @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER") .and() .withUser("admin").password("password").roles("ADMIN"); } }
3.2 Custom 403 Access denied handler, logs the request and redirect to /403
WelcomeController.java
package com.example.error; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; // handle 403 page @Component public class MyAccessDeniedHandler implements AccessDeniedHandler { private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class); @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { logger.info("User '" + auth.getName() + "' attempted to access the protected URL: " + httpServletRequest.getRequestURI()); } httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403"); } }
4. Весенний ботинок
4.1 A controller class, to define the http request and view name.
DefaultController.java
package com.example.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class DefaultController { @GetMapping("/") public String home1() { return "/home"; } @GetMapping("/home") public String home() { return "/home"; } @GetMapping("/admin") public String admin() { return "/admin"; } @GetMapping("/user") public String user() { return "/user"; } @GetMapping("/about") public String about() { return "/about"; } @GetMapping("/login") public String login() { return "/login"; } @GetMapping("/403") public String error403() { return "/error/403"; } }
4.2 Start Spring Boot application.
DefaultController.java
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootWebApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SpringBootWebApplication.class, args); } }
5. Thymeleaf + ресурсы + статические файлы
5.1 For Thymeleaf files, put in src/main/resources/templates/
folder.
5.2 Thymeleaf fragments, for template layout – header.
src/main/resources/templates/fragments/header.html
5.3 Thymeleaf fragments, for template layout – footer. Просмотрите тегsec
, это полезный тег для отображения материалов Spring Security, подробности см. В этомThymeleaf extra Spring Security.
src/main/resources/templates/fragments/footer.html
5.4 List of the Thymeleaf files, nothing special, self-explanatory.
домой ~
src/main/resources/templates/home.html
Spring Boot Thymeleaf + Spring Security Spring Boot Web Thymeleaf + Spring Security
1. Visit Admin page (Spring Security protected, Need Admin Role)
2. Visit User page (Spring Security protected, Need User Role)
3. Visit Normal page
админ ~
src/main/resources/templates/admin.html
Admin page (Spring Security protected)
Hello [[httpServletRequest.remoteUser}]]!
пользователь ~
src/main/resources/templates/user.html
User page (Spring Security protected)
Hello [[httpServletRequest.remoteUser}]]!
о ~
src/main/resources/templates/about.html
Normal page (No need login)
login ~
src/main/resources/templates/login.html
Spring Security Example
403 ~
src/main/resources/templates/error/403.html
403 - Access is denied
Hello '[[httpServletRequest.remoteUser}]]', you do not have permission to access this page.
5.5 For static files like CSS or Javascript, put in /src/main/resources/static/
/src/main/resources/static/css/main.css
h1{ color:#0000FF; } h2{ color:#FF0000; } footer{ margin-top:60px; }
Note
Прочтите этотSpring Boot Serving static content, чтобы понять отображение ресурсов.
6. Demo
6.1 Start the Spring Boot web app. Этот/admin/**
защищен, вам нужно войти в систему как администратор, чтобы получить к нему доступ.
Терминал
$ mvn spring-boot:run //...
6.2 Access http://localhost:8080
6.3 Access http://localhost:8080/admin
, redirect to http://localhost:8080/login
6.4 Invalid username or password http://localhost:8080/login
6.5 Login successful, redirect back to admin page http://localhost:8080/admin
, review the footer section, the user info is displayed.
6.6 Access http://localhost:8080/user
, redirect to http://localhost:8080/403
6.7 Clicks on the sign out link in the footer, redirect to http://localhost:8080/login?logout
Готово. Попробуйте войти под другим именем пользователя «user» и получить доступ к странице администратора.
Скачать исходный код
Скачать -spring-boot-spring-security-thymeleaf.zip (15 КБ)