【Spring Security】 Spring Security 使用案例详细教程
文章目录
一、Spring Security 入门案例
入门案例具体教程查看 Hello Spring Security :: Spring Security
1.1 导入依赖
根据 Getting Spring Security ,在 pom.xml
中导入 Spring Security 的相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<spring-security.version>6.3.4</spring-security.version>
</dependency>
</dependencies>
Spring Security 会在项目中启用 默认的身份验证和安全机制。无需额外的配置,就可以体验基本的用户认证。
1.2 运行项目
在不编写代码的情况下,Spring Boot 应用后,可以看到控制台输出日志:
Using generated security password: ed803299-ccd3-4ee0-8160-652eed542814
This generated password is for development use only. Your security configuration must be updated before running your application in production.
在没有配置 Authentication 的情况下,Spring Security 默认创建一个用户名为 user
的用户,并生成随机密码。该密码只用于开发环境,生产环境应自定义更安全的认证方式。
1.3 测试项目
测试 Basic HTTP Authentication 。
(1)未验证身份的请求
通过未验证身份直接访问受保护的路径时,Spring Security 会拒绝访问,并返回 401 Unauthorized
状态码:
$ curl -i http://localhost:8080/some/path
HTTP/1.1 401
Set-Cookie: JSESSIONID=598AEA648FB18B56CB28ACC1234AC174; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Thu, 07 Nov 2024 03:16:39 GMT
curl -i http://localhost:8080/admin/secure
curl -i -u user1:123456 http://localhost:8080/admin/secure
(2) 验证身份的请求
提供用户名 user
和生成的密码后,可以成功通过身份验证。若请求的资源不存在,Spring Boot 将返回 404 Not Found
:
$ curl -i -u user:ed803299-ccd3-4ee0-8160-652eed542814 http://localhost:8080/some/path
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Thu, 07 Nov 2024 03:22:50 GMT
{"timestamp":"2024-11-07T03:22:50.775+00:00","status":404,"error":"Not Found","path":"/some/path"}
二、Spring Security 简单实现案例
本案例展示了如何使用 Spring Security 实现以下功能:
- 配置自定义用户名和密码。
- 基于角色的授权控制。
2.1 导入依赖
根据 Getting Spring Security ,在 pom.xml
中导入 Spring Security 的相关依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
2.2 配置 Spring Security
根据 Java Configuration :: Spring Security,可以通过 Java 配置来自定义用户信息。同时,通过 Authorize HttpServletRequests 来定义不同角色的访问控制规则。
/**
* Spring Security 配置类
* <p>
* 基于角色的权限控制使用案例
* </p>
*
* @author zouhu
* @data 2024-11-07 11:46
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig{
/**
* 配置自定义用户,并给每个用户分配角色
*/
@Bean
protected UserDetailsManager userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user")
.password("{noop}123456") // 使用 {noop} 前缀表示明文密码,仅用于开发和测试环境,生产环境推荐使用其他加密方式(如 BCrypt)。
// .roles("USER") // 分配 USER 角色,角色会自动添加前缀 ROLE_
.authorities("USER") // 使用 authorities 而不是 roles,角色不会添加前缀
.build());
manager.createUser(User.withUsername("admin")
.password("{noop}admin123456")
// .roles("ADMIN") // 分配 ADMIN 角色,角色会自动添加前缀 ROLE_
.authorities("ADMIN")
.build());
return manager;
}
/**
* 配置角色的访问规则
*/
@Bean
public SecurityFilterChain web(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> {
// 管理员角色可访问的资源
authorize.requestMatchers("/admin/**").hasAuthority("ADMIN");
// 用户角色可访问的资源(注释掉的部分,如果未来需要启用可以取消注释)
authorize.requestMatchers("/user/**").hasAuthority("USER");
// 允许所有角色访问的资源
authorize.requestMatchers("/").permitAll();
// 其他所有请求都需要身份验证
authorize.anyRequest().authenticated();
})
.formLogin(withDefaults()) // 启用表单登录,默认登录页面为 /login
.httpBasic(withDefaults()); // 启用 HTTP Basic Authentication
return http.build();
}
}
2.3 创建访问资源
@RestController
public class DemoController {
@GetMapping("/user/secure")
public String userAccess() {
return "Hello User!";
}
@GetMapping("/admin/secure")
public String adminAccess() {
return "Hello Admin!";
}
@RequestMapping("/")
public String home() {
return "Welcome to the Home Page!";
}
}
2.4 测试身份验证和授权
(1) 验证角色的权限
使用 @WithMockUser
注解来模拟不同角色的用户进行权限验证。
@SpringBootTest
@AutoConfigureMockMvc
class WebSecurityConfigTest {
@Autowired
private MockMvc mvc;
/**
* 测试未认证用户访问主页和受限资源
*/
// @WithMockUser // 未加 @WithMockUser 表示请求由未认证用户发出
@Test
void Unauthenticated() throws Exception {
this.mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string("Welcome to the Home Page!")); // 预期返回 200 OK
this.mvc.perform(get("/admin/secure"))
.andExpect(status().isUnauthorized()) // 预期返回 401 Unauthorized
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
/**
* 测试默认用户(无特殊权限)的访问
*/
@WithMockUser // 模拟一个没有设置特定权限的默认用户
@Test
void NotAuthorityUser() throws Exception {
this.mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string("Welcome to the Home Page!")); // 预期返回 200 OK
this.mvc.perform(get("/user/secure"))
.andExpect(status().isForbidden()); // 预期返回 403 Forbidden
}
/**
* 测试具有 USER 权限的用户访问受限资源
*/
@WithMockUser(authorities = "USER")
@Test
void UserAuthority() throws Exception {
this.mvc.perform(get("/user/secure"))
.andExpect(status().isOk())
.andExpect(content().string("Hello User!")); // 预期返回 200 OK
this.mvc.perform(get("/admin/secure"))
.andExpect(status().isForbidden()); // 预期返回 403 Forbidden
}
/**
* 测试具有 ADMIN 权限的用户访问受限资源
*/
@WithMockUser(authorities = "ADMIN")
@Test
void AdminAuthority() throws Exception {
this.mvc.perform(get("/user/secure"))
.andExpect(status().isForbidden()); // 预期返回 403 Forbidden
this.mvc.perform(get("/admin/secure"))
.andExpect(status().isOk())
.andExpect(content().string("Hello Admin!")); // 预期返回 200 OK
}
}
(2)验证用户是否能访问
使用 curl
命令行工具模拟 HTTP 请求,验证不同用户权限。
# 未认证用户访问受限资源
$ curl -i http://localhost:8080/admin/secure
HTTP/1.1 401
Set-Cookie: JSESSIONID=7C9FAE078D4DD87F777A6AA4836D12C8; Path=/; HttpOnly
WWW-Authenticate: Basic realm="Realm"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 0
Date: Thu, 07 Nov 2024 09:21:45 GMT
# 使用管理员账户访问受限资源
$ curl -i -u admin:admin123456 http://localhost:8080/admin/secure
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 12
Date: Thu, 07 Nov 2024 09:22:19 GMT
Hello Admin!
参考资料
Java Configuration :: Spring Security
原文地址:https://blog.csdn.net/weixin_44814196/article/details/143602828
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!