Spring Boot 整合 Spring Security
2018-04-11 本文已影响135人
沧海一粟谦
在我们的项目开发中经常需要对页面做一些安全控制:对于没有访问权限的用户需要转到登录表单页面等。要实现访问控制的方法多种多样,可以通过Aop、拦截器实现,也可以通过框架(Apache Shiro、Spring Security)实现。Spring Security框架有两个概念:认证和授权,认证可以访问系统的用户,而授权则是用户可以访问的资源。
构建项目
在上一章[Spring Boot 整合 Thymeleaf]的基础上添加security依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Spring Security配置
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/index").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin").password("123456").roles("USER");
}
}
- @EnableWebMvcSecurity注解开启Spring Security的功能
- 继承WebSecurityConfigurerAdapter,并重写它的方法来设置一些web安全的细节
- 通过authorizeRequests()定义哪些URL需要被保护、哪些不需要被保护。例如以上代码指定了/和/index不需要任何认证就可以访问,其他的路径都必须通过身份验证。
- 通过formLogin()定义当需要用户登录时候,转到的登录页面。
- configureGlobal(AuthenticationManagerBuilder auth)方法,在内存中创建了一个用户,该用户的名称为admin,密码为123456,用户角色为USER。
注意:Spring Boot 2.0后Spring Security有些改动,不建议这样使用
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
<head>
<title>Spring Security</title>
</head>
<body>
<h1>欢迎使用Spring Security!</h1>
<p>点击 <a th:href="@{/list}">这里</a> 查看列表</p>
</body>
</html>
login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
<head>
<title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
用户名或密码错
</div>
<div th:if="${param.logout}">
您已注销成功
</div>
<form th:action="@{/login}" method="post">
<div><label> 用户名 : <input type="text" name="username"/> </label></div>
<div><label> 密 码 : <input type="password" name="password"/> </label></div>
<div><input type="submit" value="登录"/></div>
</form>
</body>
</html>
Spring Security提供了一个过滤器来拦截请求并验证用户身份。如果用户身份认证失败,页面就重定向到/login?error,并且页面中会展现相应的错误信息。若用户想要注销登录,可以通过访问/login?logout请求,在完成注销之后,页面展现相应的成功消息。
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>userList</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.css}"></link>
</head>
<body class="container">
<br/>
<h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1>
<h3>用户列表</h3>
<br/><br/>
<div class="with:80%">
<table class="table table-hover">
<thead>
<tr>
<th>#</th>
<th>User Name</th>
<th>Password</th>
<th>Age</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<th scope="row" th:text="${user.id}">1</th>
<td th:text="${user.userName}">neo</td>
<td th:text="${user.passWord}">Otto</td>
<td th:text="${user.age}">6</td>
<td><a th:href="@{/toEdit(id=${user.id})}">edit</a></td>
<td><a th:href="@{/delete(id=${user.id})}">delete</a></td>
</tr>
</tbody>
</table>
</div>
<div class="form-group">
<div class="col-sm-2 control-label">
<a href="/toAdd" th:href="@{/toAdd}" class="btn btn-info">添加</a>
</div>
</div>
<form th:action="@{/logout}" method="post" >
<input type="submit" class="btn btn-info" value="注销"/>
</form>
</body>
</html>
UserController中添加请求映射
@RequestMapping(value = "/")
public String index(){
return "user/index";
}
@RequestMapping(value = "/list")
public String list(Model model){
List<User> users = userService.findAll();
model.addAttribute("users",users);
return "user/list";
}
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){return "user/login";}
到这里,我们启用应用,并访问http://localhost:8080/,可以正常访问。但是访问http://localhost:8080/list的时候被重定向到了http://localhost:8080/login页面,因为没有登录,用户没有访问权限,通过输入用户名admin和密码123456进行登录后,跳转到了list页面。