本项目使用IDEA创建,Eclipse用户可以参考
一、项目目录
二、项目依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!--提供security相关标签,可选可不选-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<!--bootstrap组件,可选可不选-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
三、SpringSecurity配置
在example下建立config包,新建SpringSecurityConfig类
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;
// 管理员允许登陆
// 普通用户允许登陆
// 403错误处理
@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()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
//创建两个本地用户,管理员和普通用户,要从数据库取的话自行修改
@Autowired
public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)throws Exception{
authenticationManagerBuilder.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN");
}
}
新建error包,新建MyAccessDeniedHandler类,这个类的作用是处理错误
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;
@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");
}
}
四、SpringBoot相关
新建controller包,新建DefaultController类
(这里的GetMapping就是RequestMapping和method = RequestMethod.GET的缩写)
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";
}
}
项目自动创建的DemoApplication
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.example")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
至此后台就写完了
五、静态页面
注意页面都是放在templates下的
templates/login.htm
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
>
<head>
<title>Spring Security Example </title>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="row" style="margin-top:20px">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<form th:action="@{/login}" method="post">
<fieldset>
<h1>请登录</h1>
<div th:if="${param.error}">
<div class="alert alert-danger">
无效的用户名和密码
</div>
</div>
<div th:if="${param.logout}">
<div class="alert alert-info">
您已注销
</div>
</div>
<div class="form-group">
<input type="text" name="username" id="username" class="form-control input-lg"
placeholder="UserName" required="true" autofocus="true"/>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg"
placeholder="Password" required="true"/>
</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" class="btn btn-lg btn-primary btn-block" value="Sign In"/>
</div>
<div class="col-xs-6 col-sm-6 col-md-6">
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/home.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Thymeleaf + Spring Security</title>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="starter-template">
<h1>SpringSecurity案例演示</h1>
<h2>1. 访问 <a th:href="@{/admin}">管理员页面 (受到SpringSecurity保护,需要管理员权限)</a></h2>
<h2>2. 访问 <a th:href="@{/user}">普通用户页面 (受到SpringSecurity保护,需要会员权限)</a></h2>
<h2>3. 访问 <a th:href="@{/about}">普通页面</a></h2>
</div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/admin.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="starter-template">
<h1>管理员页面 (受到SpringSecurity保护)</h1>
<h1 th:inline="text">你好 [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="注销"/>
</form>
</div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/user.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="starter-template">
<h1>普通用户界面 (受到SpringSecurity保护)</h1>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<form th:action="@{/logout}" method="post">
<input type="submit" value="注销"/>
</form>
</div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/about.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="starter-template">
<h1>普通页面 (无需登陆)</h1>
</div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/error/403.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:replace="fragments/header :: header-css"/>
</head>
<body>
<div th:replace="fragments/header :: header"/>
<div class="container">
<div class="starter-template">
<h1>403 - 访问拒绝</h1>
<div th:inline="text">你好 '[[${#httpServletRequest.remoteUser}]]',
您没有访问此页面的权限.</div>
</div>
</div>
<!-- /.container -->
<div th:replace="fragments/footer :: footer"/>
</body>
</html>
templates/fragments/footer.html
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
</head>
<body>
<div th:fragment="footer">
<div class="container">
<footer>
<!-- this is footer -->
© 2017/10/11
<span sec:authorize="isAuthenticated()">
| 登陆用户: <span sec:authentication="name"></span> |
权限: <span sec:authentication="principal.authorities"></span> |
<a th:href="@{/logout}">注销</a>
</span>
<script type="text/javascript"
src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</footer>
</div>
</div>
</body>
</html>
templates/fragments/header.html
<html xmlns:th="http://www.thymeleaf.org">
<head>
<div th:fragment="header-css">
<!-- this is header-css -->
<link rel="stylesheet" type="text/css"
href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" th:href="@{/css/main.css}"
href="../../css/main.css" />
</div>
</head>
<body>
<div th:fragment="header">
<!-- this is header -->
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" th:href="@{/}">SpringSecurity</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a th:href="@{/}">主页</a></li>
</ul>
</div>
</div>
</nav>
</div>
</body>
</html>
CSS样式文件
static/css/main.css
h1{
color:#0000FF;
}
h2{
color:#FF0000;
}
footer{
margin-top:60px;
}
接下来就可以运行了,在地址栏输入http://localhost:8080/
点击管理员页面,跳转进入登陆页面,输入管理员账号密码,admin password,点击登陆
点击注销退出到登陆页面,再次进入home页面,点击访问普通用户页面,输入普通用户账号密码,user password
如果用普通用户账号去访问管理员页面的话,则会跳转到403页面
再次注销并回到主页,点击访问普通页面,这个页面是无需任何权限的
项目参考地址
完整项目下载地址:点击打开链接