Spring Boot 集成 Spring Security的简单应用,从数据库读取数据校验用户,页面使用Thymeleaf模板
项目地址 https://github.com/helloworlde/SpringSecurity
演示 http://project.hellowood.com.cn/Security/
创建 Spring Boot 应用
添加依赖
1 | compile('org.springframework.boot:spring-boot-starter-security') |
创建用户表并插入数据
1 | CREATE TABLE user ( |
添加配置信息
1 | spring.datasource.url=jdbc:mysql://localhost:3306/security?useSSL=false |
添加 Security 配置文件
1 |
|
添加自定义的 Authentication Provider 类
1 | import cn.com.hellowood.springsecurity.model.UserModel; |
添加校验用户信息所需要的类
添加 UserModel.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
public class UserModel {
private Integer id;
private String username;
private String password;
private Boolean enabled;
/**
* Instantiates a new User model.
*/
public UserModel() {
}
/**
* Instantiates a new User model.
*
* @param id the id
* @param username the username
* @param password the password
* @param enabled the enabled
*/
public UserModel(Integer id, String username, String password, Boolean enabled) {
this.id = id;
this.username = username;
this.password = password;
this.enabled = enabled;
}
/**
* Gets id.
*
* @return the id
*/
public Integer getId() {
return id;
}
/**
* Sets id.
*
* @param id the id
*/
public void setId(Integer id) {
this.id = id;
}
/**
* Gets username.
*
* @return the username
*/
public String getUsername() {
return username;
}
/**
* Sets username.
*
* @param username the username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* Gets password.
*
* @return the password
*/
public String getPassword() {
return password;
}
/**
* Sets password.
*
* @param password the password
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Gets enabled.
*
* @return the enabled
*/
public Boolean getEnabled() {
return enabled;
}
/**
* Sets enabled.
*
* @param enabled the enabled
*/
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
@Override
public String toString() {
return "UserModel{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", enabled=" + enabled +
'}';
}
}添加 UserService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import cn.com.hellowood.springsecurity.mapper.UserMapper;
import cn.com.hellowood.springsecurity.model.UserModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("userService")
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* Load user by username and password user model.
*
* @param username the username
* @param password the password
* @return the user model
*/
public UserModel loadUserByUsernameAndPassword(String username, String password) {
return userMapper.getUserByUsernameAndPassword(username, password);
}
}添加 UserMapper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import cn.com.hellowood.springsecurity.model.UserModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserMapper {
/**
* Gets user by username and password.
*
* @param username the username
* @param password the password
* @return the user by username and password
*/
UserModel getUserByUsernameAndPassword(@Param("username") String username,
@Param("password") String password);
}添加 UserMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.com.hellowood.springsecurity.mapper.UserMapper">
<resultMap id="baseResultMap" type="cn.com.hellowood.springsecurity.model.UserModel">
<id column="id" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"></id>
<result column="username" property="username" javaType="java.lang.String" jdbcType="VARCHAR"></result>
<result column="password" property="password" javaType="java.lang.String" jdbcType="VARCHAR"></result>
<result column="enabled" property="enabled" javaType="java.lang.Boolean" jdbcType="INTEGER"></result>
</resultMap>
<select id="getUserByUsernameAndPassword" resultType="cn.com.hellowood.springsecurity.model.UserModel">
SELECT
id,
username,
password,
enabled
FROM user
WHERE username = #{username, jdbcType=VARCHAR}
AND password = #{password, jdbcType=VARCHAR}
</select>
</mapper>添加页面
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Security</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}"/>
<link rel="stylesheet" href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container">
<form action="#" class="form-signin">
<h2 class="form-signin-heading">Hello Spring Security</h2>
<h5 class="form-signin-heading content-adjust">Anyone can access this page</h5>
<div th:if="${session.user} != null">
<h5 class="form-signin-heading content-adjust">Your username is <span th:text="${session.user.username}"></span></h5>
<a href="/user/index" th:href="@{/user/index}" class="btn btn-success btn-block">To Security page</a>
</div>
<div th:if="${session.user} == null">
<a href="/index" th:href="@{/login}" class="btn btn-primary btn-block">To Login page</a>
</div>
</form>
<div th:fragment="logout" class="logout" th:if="${session.user} != null">
<form action="#" th:action="@{/logout}" method="post" class="form-signin">
<button class="btn btn-warning btn-block" type="submit">Log out</button>
</form>
</div>
</div>
</body>
</html>login.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login page</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}"/>
<link rel="stylesheet" href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container">
<form th:action="@{/login}" method="post" class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2>
<div>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username"
th:class="${loginError} ? 'form-control is-invalid' : 'form-control'" placeholder="Username"
required="required"
autofocus="autofocus"/>
<div class="invalid-feedback" th:if="${loginError}">
Wrong username or password
</div>
</div>
<div>
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password"
required="required"/>
</div>
<button class="btn btn-success btn-block" type="submit">Sign in</button>
<a href="/index" th:href="@{/index}" class="btn btn-primary btn-block">Back to Home page</a>
</form>
</div>
</body>
</html>user/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Security</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<link rel="stylesheet" href="/css/main.css" th:href="@{/css/main.css}"/>
<link rel="stylesheet" href="/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}"/>
</head>
<body>
<div class="container">
<form action="#" class="form-signin">
<h2 class="form-signin-heading">Hello Spring Security</h2>
<h5 class="form-signin-heading content-adjust">Only logged in user can access this page</h5>
<div th:if="${session.user} != null">
<h5 class="form-signin-heading content-adjust">Logged user is <span th:text="${session.user.username}"></span></h5>
<a href="/index" th:href="@{/index}" class="btn btn-primary btn-block">Back to Home page</a>
</div>
</form>
<div th:substituteby="index::logout"></div>
</div>
</body>
</html>
添加 Controller
1 | import org.springframework.stereotype.Controller; |
启动应用,访问http://localhost:8080/user/index,此时没有登录,会被拦截并重定向到登录页面http://localhost:8080/login,输入用户名
username和密码password,登录成功后再次访问http://localhost:8080/user/index,此时该 url 可以正常访问,当输入错误的用户名或密码时会提示错误信息,说明 Spring Security 配置正确