Java学习第二十六部分——Spring Security
目录
一. 关键概述
二. 核心功能
三. 核心组件
四. 常见配置
五. 安全特性
六. 集成第三方认证
七. 使用场景
八. 优势长处
九. 项目实战
1.打开idea,创建Spring Initializr项目,配置如下图,点击下一步
2. 添加Spring Web,Spring Security,Thymeleaf三个依赖,点击创建,并等待项目配置完成
3. 项目结构如下图
4. 三个Java类代码内容如下
5.三个HTML类文件内容如下
6.运行应用类,访问http://localhost:8080
7.访问http://localhost:8080/user
8.这个示例展示了 Spring Security 的核心功能:
一. 关键概述
Spring Security 是一个功能强大并且高度可定制的 Java 安全框架,用于保护基于 Spring 的应用程序。它提供了全面的安全性服务,包括认证(Authentication)、授权(Authorization)、防止常见的安全攻击等功能。
二. 核心功能
- **认证(Authentication)**
- 验证用户身份,确认用户是否是他们声称的那个人。通常通过用户名和密码完成,但也可以支持其他认证方式,如 OAuth、JWT 等。
- Spring Security 提供了多种认证机制,如表单登录、HTTP 基本认证、JWT 令牌认证等。
- **授权(Authorization)**
- 确定用户是否有权访问特定资源或执行特定操作。授权基于用户的角色和权限。
- 支持基于角色的访问控制(RBAC)和基于方法的安全性(如 `@PreAuthorize`、`@PostAuthorize` 注解)。
- **防止安全攻击**
- 提供了多种安全防护机制,如防止跨站请求伪造(CSRF)、防止会话固定攻击、防止暴力破解等。
- 自动处理安全相关的 HTTP 头,如设置 `X-Content-Type-Options`、`X-Frame-Options` 等。
三. 核心组件
- **SecurityContextHolder**
- 存储安全上下文信息,包括当前用户的认证信息(`Authentication` 对象)。
- 它是一个线程局部变量(`ThreadLocal`),确保在多线程环境下每个线程都有独立的安全上下文。
- **Authentication**
- 表示用户的认证信息,通常包含用户名、密码、权限等。
- 常见的实现类有 `UsernamePasswordAuthenticationToken`、`JwtAuthenticationToken` 等。
- **UserDetails**
- 用于加载用户特定数据,如用户名、密码、权限等。
- 需要实现 `UserDetailsService` 接口,通常从数据库中加载用户信息。
- **PasswordEncoder**
- 用于密码加密和比对。Spring Security 提供了多种加密方式,如 BCrypt、SHA-256 等。
- 常用的实现类是 `BCryptPasswordEncoder`,它是一种强哈希函数,适合存储用户密码。
- **HttpSecurity**
- 用于定义安全策略,如哪些请求需要认证、哪些请求需要授权、是否启用 CSRF 保护等。
- 在配置类中通过 `WebSecurityConfigurerAdapter` 或 `SecurityFilterChain` 来配置。
四. 常见配置
- **基于表单的登录**
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/", "/home", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.and()
.csrf().disable();
}
}
- 配置了登录页面、登录成功后的默认跳转页面、登出后的跳转页面等。
- 禁用了 CSRF 保护(实际开发中不建议禁用)。
- **JWT 认证**
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()));
}
}
- 使用 JWT 进行认证,通过自定义的 `JwtAuthenticationFilter` 和 `JwtAuthorizationFilter` 来处理 JWT 的验证和授权。
五. 安全特性
- **CSRF 保护**
- 默认启用,防止跨站请求伪造攻击。可以通过 `http.csrf().disable()` 禁用,但不推荐。
- **Session 管理**
- 可以配置会话策略,如同时登录限制、会话超时等。
- 示例:`http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");`
- **密码加密**
- 强烈推荐使用 `BCryptPasswordEncoder` 对用户密码进行加密存储。
- 示例:`passwordEncoder = new BCryptPasswordEncoder();`
六. 集成第三方认证
- **OAuth2**
- Spring Security 提供了对 OAuth2 的支持,可以集成 Google、Facebook 等第三方认证服务。
- 需要配置 `ClientRegistrationRepository` 和 `OAuth2UserService`。
- **JWT**
- 常用于无状态认证,通过令牌(JWT)在客户端和服务器之间传递用户信息。
- 需要自定义 JWT 的生成和验证逻辑。
七. 使用场景
- **企业级应用**
- 适用于需要高安全性的企业级系统,如金融、医疗等领域。
- **微服务架构**
- 可以在微服务中统一管理认证和授权,通过 JWT 等方式实现服务间的安全通信。
- **Web 应用和 API**
- 无论是传统的 Web 应用还是 RESTful API,Spring Security 都能提供强大的安全保障。
八. 优势长处
- **高度可定制**
- 几乎所有功能都可以自定义,满足不同业务需求。
- **集成方便**
- 与 Spring 生态系统无缝集成,如 Spring Boot、Spring Data 等。
- **安全性高**
- 提供了多种安全防护机制,能够有效防止常见的安全漏洞。
九. 项目实战
1.打开idea,创建Spring Initializr项目,配置如下图,点击下一步
2. 添加Spring Web,Spring Security,Thymeleaf三个依赖,点击创建,并等待项目配置完成
3. 项目结构如下图
4. 三个Java类代码内容如下
package com.example.demo.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/", "/home").permitAll() // 允许所有人访问.requestMatchers("/user/**").authenticated() // 需要登录).formLogin(form -> form.loginPage("/login") // 自定义登录页.permitAll() // 允许所有人访问登录页.defaultSuccessUrl("/user", true) // 登录成功后跳转).logout(logout -> logout.permitAll() // 允许所有人注销.logoutSuccessUrl("/") // 注销后跳转首页);return http.build();}@Beanpublic UserDetailsService userDetailsService() {// 创建内存用户(实际项目应连接数据库)UserDetails user = User.withDefaultPasswordEncoder().username("user").password("123").roles("USER").build();UserDetails admin = User.withDefaultPasswordEncoder().username("admin").password("admin").roles("ADMIN").build();return new InMemoryUserDetailsManager(user, admin);}
}
package com.example.demo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;@Controller
public class HomeController {@GetMapping("/")public String home() {return "home"; // 返回 home.html}@GetMapping("/user")public String userPage() {return "user"; // 返回 user.html}@GetMapping("/login")public String login() {return "login"; // 返回 login.html}
}
package com.example.demo.service;public class UserService {
}
5.三个HTML类文件内容如下
<!DOCTYPE html>
<meta charset="UTF-8">
<html xmlns:th="http://www.thymeleaf.org">
<head><title>首页</title>
</head>
<body>
<h1>欢迎访问首页!</h1>
<p>所有人都可以访问此页面</p>
<a th:href="@{/user}">访问用户页面</a>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>登录</title>
</head>
<body>
<h1>登录</h1>
<div th:if="${param.error}"><p style="color:red">用户名或密码错误!</p>
</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><input type="submit" value="登录"/>
</form>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>用户页</title>
</head>
<body>
<h1>用户专属页面</h1>
<p>只有登录用户可见</p>
<form th:action="@{/logout}" method="post"><input type="submit" value="注销"/>
</form>
</body>
</html>
6.运行应用类,访问http://localhost:8080
7.访问http://localhost:8080/user
8.这个示例展示了 Spring Security 的核心功能:
- 基于角色的访问控制
- 自定义登录页面
- 内存用户管理
- 注销功能
- 安全路由配置