接下来我将为你讲解“Spring Security使用数据库登录认证授权”的完整攻略。
1. 概述
Spring Security是用于保护Spring应用程序的安全框架,它提供了包括身份验证、授权、攻击防御等在内的一系列安全特性。本文将介绍如何使用Spring Security对数据库进行登录认证授权。
2. 前置条件
本文假设你已经熟悉Spring Boot框架以及相关的基础知识,同时你已经准备好了一些必要的软件包,例如:Spring Boot、Spring Security、MySQL驱动等。
3. 步骤
步骤如下:
3.1 配置数据库
首先需要在MySQL数据库中创建一个用户表,用于存储用户的账号和密码信息。示例代码如下:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);
3.2 配置Spring Security
在Spring Boot的配置文件中配置Spring Security,使用数据库作为认证授权的数据源,并设置相应的加密算法。示例代码如下:
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Spring Security 数据源配置
spring.security.user.name=admin
spring.security.user.password=admin
spring.security.user.roles=ADMIN
spring.security.jdbc.users-by-username-query=SELECT username, password, true FROM users WHERE username=?
spring.security.jdbc.authorities-by-username-query=SELECT u.username, a.role FROM users u LEFT JOIN authorities a ON u.id = a.user_id WHERE u.username=?
spring.security.jdbc.role-prefix=ROLE_
spring.security.password.encoder.secret=thisisasecretkey
spring.security.password.encoder.iteration-count=1000
spring.security.password.encoder.strength=16
其中,spring.datasource.url
、spring.datasource.username
、spring.datasource.password
等配置为了连接数据库,而spring.security.jdbc.users-by-username-query
和spring.security.jdbc.authorities-by-username-query
则是配置了通过用户名查询用户信息和查询用户权限信息的SQL。
3.3 配置Spring Security的Web安全配置
配置Spring Security的Web安全配置,定义哪些URL需要保护,哪些URL可以匿名访问,以及如何进行身份验证授权。示例代码如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().permitAll()
.and()
.formLogin()
.and()
.logout()
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new Pbkdf2PasswordEncoder("thisisasecretkey", 1000, 16);
}
}
在这个示例代码中,打开了所有URL的匿名访问权限,但是对于/admin/**
的URL,需要具有ADMIN
角色才能够访问。另外,定义了一个PasswordEncoder
的Bean。
3.4 编写登录页面和处理程序
为了可以进行登录,我们需要在服务器端编写一个处理程序,将用户提交的表单进行处理,并将用户的信息保存到会话上下文中。示例代码如下:
@Controller
public class LoginController {
@GetMapping("/login")
public String showLoginPage() {
return "login";
}
@PostMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Cookie cookie = new Cookie("username", authentication.getName());
response.addCookie(cookie);
return "redirect:/";
}
}
在这个例子中,我们在GET请求的时候展示了登录页面,在POST请求的时候进行登录处理,并将用户的登录名保存到Cookie中。此处可根据需求自行修改。
以下为相关页面代码:
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<h1>{{title}}</h1>
<form action="/login" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username"/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</body>
</html>
3.5 运行应用程序
在以上步骤完成后,可以启动应用程序,进行登录测试,此处我们使用了Spring Boot的基本页面。
运行测试后的示例页面可见LoginPage
示例二
以下则是使用了Thymeleaf模板引擎对登录页面进行模板化处理后的完整示例代码:
3.6 依赖配置
首先需要添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
添加依赖后在配置文件中加入:
spring.thymeleaf.cache=false
3.7 编写登录页面和处理程序
依次编写登录页面、处理程序以及配置文件。其中,登录页面使用了Thymeleaf模板,示例代码如下:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8">
<title>Login Page</title>
</head>
<body>
<h1>Login Page</h1>
<div th:if="${param.error}">
<!-- 如果有错误,则显示错误信息 -->
<p class="error">Your username and password is invalid.</p>
</div>
<div th:if="${param.logout}">
<!-- 如果已经退出,则显示成功信息 -->
<p class="success">You have been logged out.</p>
</div>
<form action="/login" method="post">
<div>
<label for="username">Username:</label>
<input type="text" id="username" name="username"/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</body>
</html>
处理程序中与之前一致。
3.8 配置Spring Security
配置文件中Spring Security部分改为:
# Spring Security 数据源配置
spring.security.jdbc.users-by-username-query=SELECT username,password,active FROM users WHERE username=?
spring.security.jdbc.authorities-by-username-query=SELECT u.username, a.role AS authorities FROM users u LEFT JOIN authorities a ON u.id = a.user_id WHERE u.username=?
spring.security.jdbc.role-prefix=ROLE_
spring.security.password.encoder.secret=thisisasecretkey
spring.security.password.encoder.iteration-count=1000
spring.security.password.encoder.strength=16
spring.security.enable-csrf=false
并添加以下内容:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/", "/home").permitAll() // 访问 "/" 和 "/home" 路径的请求不要求认证即可访问
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login") // 定义登录页面为 "/login"
.permitAll() // 登录页面开放访问权限
.failureUrl("/login?error=true") // 配置登录失败后跳转的 URL
.defaultSuccessUrl("/dashboard") // 配置登录成功后跳转的 URL
.and()
.logout()
.logoutUrl("/logout") // 定义退出登录 URL
.logoutSuccessUrl("/login?logout=true") // 定义退出登录成功后的 URL
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new Pbkdf2PasswordEncoder("thisisasecretkey", 1000, 16);
}
}
在这个示例代码中,我们定义了若干个路径,其中/login
是登录页面的路径,/dashboard
是成功登录后跳转的路径,/logout
是退出登录的路径,使用get请求。
另外,我们还将静态资源路径开放出去,这样就可以访问所有的静态资源目录和文件:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/css/**")
.antMatchers("/js/**")
.antMatchers("/images/**");
}
3.9 运行应用程序
在以上步骤完成后,可以启动应用程序,进行登录测试。
示例可见:LoginPage-Thymeleaf
总结
通过上述两个示例,我们使用Spring Security实现了基于数据库的登录认证授权,同时也可以通过Thymeleaf模板引擎进行模板化处理,这样可以使我们快速地搭建出安全性较高的应用程序,本文着重于基础的用户管理部分,有兴趣的同学可自行拓展。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security使用数据库登录认证授权 - Python技术站