第一部分:基本介绍
Spring Security
是一个能够为基于Spring
的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
如果项目中需要进行权限管理,具有多个角色和多种权限,我们可以使用Spring Security。
第二部分:导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
第三部分:设置需求
(1)页面
①功能选择页面
②登录界面
③/pages1和/pages2限定界面
(2)三个用户身份
三个身份为:left_author和right_author以及admin,代表的含义是left_author只能访问/pages1,right_author只能访问/pages2,admin可以访问全部页面;
(3)三类用户身份的例子
每个身份下分别创建两个用户,含有账号和密码;
第四部分:功能代码解析
(1)设置三种身份
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
//.antMatchers("/**").hasRole("admin") // 允许admin用户访问所有页面
.antMatchers("/pages1").hasAnyRole("left_author","admin")
.antMatchers("/pages2").hasAnyRole("right_author","admin")
.antMatchers("/**").hasRole("admin") // 添加这一行来允许admin用户访问所有页面
.anyRequest().authenticated()
.and()
.formLogin();
}
(2)为三种身份设置用户
①设置加密格式
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
②设置用户用例
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("left_user1").password(new BCryptPasswordEncoder().encode("123456")).roles("left_author")
.and()
.withUser("left_user2").password(new BCryptPasswordEncoder().encode("123456")).roles("left_author")
.and()
.withUser("right_user1").password(new BCryptPasswordEncoder().encode("123456")).roles("right_author")
.and()
.withUser("right_user2").password(new BCryptPasswordEncoder().encode("123456")).roles("right_author")
.and()
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("admin");
}
(3)记住我功能
①在 protected void configure(HttpSecurity http) throws Exception内部
//本身用的也是cookie,默认保存两周
http.rememberMe()
.rememberMeParameter("rememberme")
.tokenValiditySeconds(200)
.tokenRepository(tokenRepository());
②在 protected void configure(HttpSecurity http) throws Exception外部
@Autowired
private DataSource dataSource;
@Bean
public JdbcTokenRepositoryImpl tokenRepository(){
JdbcTokenRepositoryImpl jr=new JdbcTokenRepositoryImpl();
jr.setDataSource(dataSource);
return jr;}
(4)强制关闭安全管理
//关闭security
@Override
public void configure(WebSecurity web) throws Exception {
//web.ignoring().antMatchers("/**");//想要关闭security也就是不让那个login一直出现的话,就解开这个注释
}
源程序获取:
前四部分基础功能实现的源程序代码如下:
通过百度网盘分享的文件:springboot整合security第一版本(不连接数据库).zip
链接:https://pan.baidu.com/s/1AC6wzy8ye9P7LSut0kkTDA?pwd=lydy
提取码:lydy
--来自百度网盘超级会员V5的分享
第五部分:配置navicat数据库
(1)数据库配置
数据库资源链接:
通过百度网盘分享的文件:安全管理security第二版数据库.zip
链接:https://pan.baidu.com/s/1y3kyX8D_GYj_A2mZIFH_Rg?pwd=u4ad
提取码:u4ad
--来自百度网盘超级会员V5的分享
(2)安全管理类修改部分
修改部分的内容为:
将原先我们自己设定的用户例子换成从数据库读取的形式:
.usersByUsernameQuery("SELECT username, password, enable FROM users WHERE username = ?")
.authoritiesByUsernameQuery("SELECT username, CONCAT('ROLE_', identify) FROM users WHERE username = ?");
注:这个查询的内部的前缀“ROLE_”是内部自动映射的,我们在数据库里面并不需要手动加上。
(3)(手动)将原先密码以加密的形式重新存储
代码:
@Test
void set()
{
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
System.out.println(encoder.encode("123456"));
}
输出结果:
也就是我们正常的密码设置的是“123456”,但是我们再次放入到数据库的时候需要改成“$2a$10$uP/92P6AkY6aFYkDAwbKPePJyif1/Sp1QmAnNVM/2fwPpK9GZE4MW”
我们在login界面的时候还按照原先提交“123456”就行。
源代码获取:
通过百度网盘分享的文件:springboot整合security第二版本(连接数据库).zip
链接:https://pan.baidu.com/s/13JQARQleAWroYZxZk2dPZA?pwd=v26t
提取码:v26t
--来自百度网盘超级会员V5的分享
第六部分:修改原本的login页面
我喜欢将页面放入到templates里面,所以:
(1)导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
(2)新建页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f0f0f0;
}
.login-container {
background-color: white;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
h2 {
text-align: center;
color: #333;
}
form {
display: flex;
flex-direction: column;
}
input {
margin: 10px 0;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.error-message {
color: red;
text-align: center;
}
</style>
</head>
<body>
<div class="login-container">
<h2>用户登录</h2>
<div th:if="${param.error}" class="error-message">
用户名或密码错误,请重试。
</div>
<form th:action="@{/perform_login}" method="post">
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
</div>
</body>
</html>
(3)修改安全管理页面的代码
位于:SecurityConfig类里面的configure(HttpSecurity http)方法下:
代码为:
//表单提交
http.formLogin()
//自定义登录页面
.loginPage("/login")//还没有认证的时候处理的信息
.loginProcessingUrl("/perform_login")//认证过程中数据传送的地址
.defaultSuccessUrl("/Choice", true)//成功之后被重定向的位置
.failureUrl("/login?error=true")//失败之后被重定向的位置
.permitAll(); // Allow everyone to access the login page
(4)编写controller类
这个get方法是奏效的关键,上面那三个post方法是在Choice页面里面点击按钮跳转用的。
代码为:
@GetMapping("/Choice")
public String Choice2() {
return "Choice"; // This will look for a `login.html` in the `templates` folder
}
(5)效果
输入pages1自动跳转到login页面:
输入的账号密码正确之后自动跳转Choice界面:
注:工作过程解析
- 表单提交: 当用户在登录页面输入用户名和密码并提交表单时,数据会被发送到您配置的
loginProcessingUrl
(在这个例子中是 "/perform_login")。 - Spring Security 拦截: Spring Security 会拦截发送到这个URL的请求。它会自动从表单中提取用户名和密码。
- 认证过程: Spring Security 使用配置的
AuthenticationProvider
来验证这些凭据。在您的情况下,这是JdbcAuthenticationProvider
,它使用您之前配置的数据源和SQL查询。 - 数据库查询: 系统会执行您在
configure(AuthenticationManagerBuilder auth)
方法中配置的SQL查询,这些查询会使用用户输入的用户名来查找相应的用户记录和权限。 - 密码验证: 系统会使用配置的
PasswordEncoder
(在您的例子中是BCryptPasswordEncoder
)来验证输入的密码是否匹配数据库中存储的加密密码。
源程序获取:
通过百度网盘分享的文件:springboot整合security第三版本(自定义页面).zip
链接:https://pan.baidu.com/s/1KoZo-0j8O9fYxcBeRrR1Ow?pwd=vobp
提取码:vobp
--来自百度网盘超级会员V5的分享
运行我打包的项目,为了能够正常运行(需要兼容maven以及java版本),具体的调整方法看我博客:http://t.csdnimg.cn/Uovig
好啦,希望能够帮助到大家!