Spring Boot 安全认证与授权

Spring Boot 安全认证与授权

Spring Boot 安全认证与授权

在这里插入图片描述
22.1 学习目标与重点提示

学习目标:掌握Spring Boot安全认证与授权的核心概念与使用方法,包括Spring Security的定义与特点、Spring Boot与Spring Security的集成、Spring Boot与Spring Security的配置、Spring Boot与Spring Security的认证、Spring Boot与Spring Security的授权、Spring Boot与Spring Security的实际应用场景,学会在实际开发中处理安全认证与授权问题。
重点:Spring Security的定义与特点Spring Boot与Spring Security的集成Spring Boot与Spring Security的配置Spring Boot与Spring Security的认证Spring Boot与Spring Security的授权Spring Boot与Spring Security的实际应用场景

22.2 Spring Security概述

Spring Security是Java开发中的重要组件。

22.2.1 Spring Security的定义

定义:Spring Security是Spring Boot提供的安全框架。
作用

  • 实现用户认证。
  • 实现用户授权。
  • 提供安全的编程模型。

常见的安全框架

  • Spring Security:Spring Boot提供的安全框架。
  • Shiro:Apache Shiro是一款开源的安全框架。

✅ 结论:Spring Security是Spring Boot提供的安全框架,作用是实现用户认证、用户授权、提供安全的编程模型。

22.2.2 Spring Security的特点

定义:Spring Security的特点是指Spring Security的特性。
特点

  • 全面性:Spring Security提供了全面的安全功能。
  • 可扩展性:Spring Security可以扩展到多个应用程序之间的安全通信。
  • 易用性:Spring Security提供了易用的编程模型。
  • 整合性:Spring Security可以与Spring Boot、Spring Cloud等整合。

✅ 结论:Spring Security的特点包括全面性、可扩展性、易用性、整合性。

22.3 Spring Boot与Spring Security的集成

Spring Boot与Spring Security的集成是Java开发中的重要内容。

22.3.1 集成Spring Security的步骤

定义:集成Spring Security的步骤是指使用Spring Boot与Spring Security集成的方法。
步骤

  1. 创建Spring Boot项目。
  2. 添加所需的依赖。
  3. 配置Spring Security。
  4. 创建用户服务类。
  5. 创建控制器类。
  6. 测试应用。

示例
pom.xml文件中的依赖:

<dependencies><!-- Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Security依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

Spring Security配置类:

importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("admin").password("admin123").roles("ADMIN").and().withUser("user").password("user123").roles("USER");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}

控制器类:

importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;@ControllerpublicclassSecurityController{@GetMapping("/")publicStringindex(){return"index";}@GetMapping("/login")publicStringlogin(){return"login";}@GetMapping("/user")publicStringuser(){return"user";}@GetMapping("/admin")publicStringadmin(){return"admin";}}

视图模板文件(src/main/resources/templates/index.html):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>首页</title><style>body{font-family: Arial, sans-serif;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;}.container{background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}h1{color: #333;margin-bottom: 20px;}a{text-decoration: none;color: #007bff;margin-right: 20px;}a:hover{text-decoration: underline;}</style></head><body><divclass="container"><h1>首页</h1><ahref="/login">登录</a><ahref="/user">用户页面</a><ahref="/admin">管理员页面</a></div></body></html>

视图模板文件(src/main/resources/templates/login.html):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>登录</title><style>body{font-family: Arial, sans-serif;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;}.container{background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}h1{color: #333;margin-bottom: 20px;}form{display: flex;flex-direction: column;}label{margin-bottom: 5px;color: #333;}input{margin-bottom: 10px;padding: 8px;border: 1px solid #ddd;border-radius: 5px;}button{padding: 10px;background-color: #007bff;color: white;border: none;border-radius: 5px;cursor: pointer;}button:hover{background-color: #0056b3;}a{text-decoration: none;color: #007bff;margin-top: 10px;text-align: center;}a:hover{text-decoration: underline;}</style></head><body><divclass="container"><h1>登录</h1><formth:action="@{/login}"method="post"><labelfor="username">用户名:</label><inputtype="text"id="username"name="username"required><labelfor="password">密码:</label><inputtype="password"id="password"name="password"required><buttontype="submit">登录</button></form><ahref="/">返回首页</a></div></body></html>

视图模板文件(src/main/resources/templates/user.html):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>用户页面</title><style>body{font-family: Arial, sans-serif;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;}.container{background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}h1{color: #333;margin-bottom: 20px;}a{text-decoration: none;color: #007bff;margin-right: 20px;}a:hover{text-decoration: underline;}</style></head><body><divclass="container"><h1>用户页面</h1><ahref="/">返回首页</a><ahref="/logout">登出</a></div></body></html>

视图模板文件(src/main/resources/templates/admin.html):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>管理员页面</title><style>body{font-family: Arial, sans-serif;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;}.container{background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}h1{color: #333;margin-bottom: 20px;}a{text-decoration: none;color: #007bff;margin-right: 20px;}a:hover{text-decoration: underline;}</style></head><body><divclass="container"><h1>管理员页面</h1><ahref="/">返回首页</a><ahref="/logout">登出</a></div></body></html>

测试类:

importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.web.client.TestRestTemplate;importorg.springframework.boot.web.server.LocalServerPort;importorg.springframework.http.HttpEntity;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpMethod;importorg.springframework.http.ResponseEntity;importjava.util.Base64;importjava.util.Map;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classSpringSecurityApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestIndexPage(){String response = restTemplate.getForObject("http://localhost:"+ port +"/",String.class);assertThat(response).contains("首页");}@TestvoidtestUserPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/user",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestUserPageWithUserAuthentication(){String credentials ="user:user123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/user",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("用户页面");}@TestvoidtestAdminPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/admin",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestAdminPageWithAdminAuthentication(){String credentials ="admin:admin123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/admin",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("管理员页面");}}

✅ 结论:集成Spring Security的步骤包括创建Spring Boot项目、添加所需的依赖、配置Spring Security、创建用户服务类、创建控制器类、测试应用。

22.4 Spring Boot与Spring Security的认证

Spring Boot与Spring Security的认证是Java开发中的重要内容。

22.4.1 基于内存的认证

定义:基于内存的认证是指Spring Security提供的一种认证方式。
作用

  • 实现用户认证。
  • 提供安全的编程模型。

示例

importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("admin").password("admin123").roles("ADMIN").and().withUser("user").password("user123").roles("USER");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}

✅ 结论:基于内存的认证是指Spring Security提供的一种认证方式,作用是实现用户认证、提供安全的编程模型。

22.4.2 基于数据库的认证

定义:基于数据库的认证是指Spring Security提供的一种认证方式。
作用

  • 实现用户认证。
  • 提供安全的编程模型。

示例
pom.xml文件中的依赖:

<dependencies><!-- Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Security依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- Data JPA依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- H2数据库依赖 --><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><!-- 测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

实体类:

importjavax.persistence.*;@Entity@Table(name ="user")publicclassUser{@Id@GeneratedValue(strategy =GenerationType.IDENTITY)privateLong id;privateString username;privateString password;privateString role;publicUser(){}publicUser(String username,String password,String role){this.username = username;this.password = password;this.role = role;}// Getter和Setter方法publicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetUsername(){return username;}publicvoidsetUsername(String username){this.username = username;}publicStringgetPassword(){return password;}publicvoidsetPassword(String password){this.password = password;}publicStringgetRole(){return role;}publicvoidsetRole(String role){this.role = role;}@OverridepublicStringtoString(){return"User{"+"id="+ id +",+ username +'\''+",+ password +'\''+",+ role +'\''+'}';}}

Repository接口:

importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;@RepositorypublicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByUsername(String username);}

用户服务类:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.security.core.GrantedAuthority;importorg.springframework.security.core.authority.SimpleGrantedAuthority;importorg.springframework.security.core.userdetails.UserDetails;importorg.springframework.security.core.userdetails.UserDetailsService;importorg.springframework.security.core.userdetails.UsernameNotFoundException;importorg.springframework.stereotype.Service;importjava.util.ArrayList;importjava.util.List;@ServicepublicclassUserDetailsServiceImplimplementsUserDetailsService{@AutowiredprivateUserRepository userRepository;@OverridepublicUserDetailsloadUserByUsername(String username)throwsUsernameNotFoundException{User user = userRepository.findByUsername(username);if(user ==null){thrownewUsernameNotFoundException("用户不存在:"+ username);}List<GrantedAuthority> authorities =newArrayList<>(); authorities.add(newSimpleGrantedAuthority("ROLE_"+ user.getRole()));returnorg.springframework.security.core.userdetails.User.builder().username(user.getUsername()).password(user.getPassword()).authorities(authorities).build();}}

Spring Security配置类:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.security.authentication.AuthenticationManager;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;importorg.springframework.security.crypto.password.PasswordEncoder;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@AutowiredprivateUserDetailsServiceImpl userDetailsService;@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.userDetailsService(userDetailsService);}@BeanpublicPasswordEncoderpasswordEncoder(){returnNoOpPasswordEncoder.getInstance();}@Bean@OverridepublicAuthenticationManagerauthenticationManagerBean()throwsException{returnsuper.authenticationManagerBean();}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}

控制器类:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PostMapping;@ControllerpublicclassSecurityController{@AutowiredprivateUserRepository userRepository;@GetMapping("/")publicStringindex(){return"index";}@GetMapping("/login")publicStringlogin(){return"login";}@GetMapping("/user")publicStringuser(){return"user";}@GetMapping("/admin")publicStringadmin(){return"admin";}@PostMapping("/register")publicStringregisterUser(String username,String password,String role){User user =newUser(username, password, role); userRepository.save(user);return"redirect:/login";}}

视图模板文件(src/main/resources/templates/register.html):

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>注册</title><style>body{font-family: Arial, sans-serif;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f5f5f5;}.container{background-color: white;padding: 20px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);}h1{color: #333;margin-bottom: 20px;}form{display: flex;flex-direction: column;}label{margin-bottom: 5px;color: #333;}input{margin-bottom: 10px;padding: 8px;border: 1px solid #ddd;border-radius: 5px;}select{margin-bottom: 10px;padding: 8px;border: 1px solid #ddd;border-radius: 5px;}button{padding: 10px;background-color: #007bff;color: white;border: none;border-radius: 5px;cursor: pointer;}button:hover{background-color: #0056b3;}a{text-decoration: none;color: #007bff;margin-top: 10px;text-align: center;}a:hover{text-decoration: underline;}</style></head><body><divclass="container"><h1>注册</h1><formth:action="@{/register}"method="post"><labelfor="username">用户名:</label><inputtype="text"id="username"name="username"required><labelfor="password">密码:</label><inputtype="password"id="password"name="password"required><labelfor="role">角色:</label><selectid="role"name="role"required><optionvalue="USER">用户</option><optionvalue="ADMIN">管理员</option></select><buttontype="submit">注册</button></form><ahref="/">返回首页</a></div></body></html>

测试类:

importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.web.client.TestRestTemplate;importorg.springframework.boot.web.server.LocalServerPort;importorg.springframework.http.HttpEntity;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpMethod;importorg.springframework.http.ResponseEntity;importjava.util.Base64;importjava.util.Map;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classSpringSecurityApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestIndexPage(){String response = restTemplate.getForObject("http://localhost:"+ port +"/",String.class);assertThat(response).contains("首页");}@TestvoidtestUserPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/user",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestUserPageWithUserAuthentication(){String credentials ="user:user123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/user",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("用户页面");}@TestvoidtestAdminPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/admin",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestAdminPageWithAdminAuthentication(){String credentials ="admin:admin123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/admin",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("管理员页面");}}

✅ 结论:基于数据库的认证是指Spring Security提供的一种认证方式,作用是实现用户认证、提供安全的编程模型。

22.5 Spring Boot与Spring Security的授权

Spring Boot与Spring Security的授权是Java开发中的重要内容。

22.5.1 基于角色的授权

定义:基于角色的授权是指Spring Security提供的一种授权方式。
作用

  • 实现用户授权。
  • 提供安全的编程模型。

示例

importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("admin").password("admin123").roles("ADMIN").and().withUser("user").password("user123").roles("USER");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}

✅ 结论:基于角色的授权是指Spring Security提供的一种授权方式,作用是实现用户授权、提供安全的编程模型。

22.5.2 基于权限的授权

定义:基于权限的授权是指Spring Security提供的一种授权方式。
作用

  • 实现用户授权。
  • 提供安全的编程模型。

示例

importorg.springframework.context.annotation.Configuration;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;@Configuration@EnableWebSecuritypublicclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("admin").password("admin123").roles("ADMIN").and().withUser("user").password("user123").roles("USER");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}

✅ 结论:基于权限的授权是指Spring Security提供的一种授权方式,作用是实现用户授权、提供安全的编程模型。

22.6 Spring Boot与Spring Security的实际应用场景

在实际开发中,Spring Boot与Spring Security的应用场景非常广泛,如:

  • 实现用户的登录与登出。
  • 实现用户的角色管理。
  • 实现用户的权限管理。
  • 实现系统的安全审计。

示例

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;importorg.springframework.security.config.annotation.web.builders.HttpSecurity;importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;importorg.springframework.security.crypto.password.NoOpPasswordEncoder;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.GetMapping;@SpringBootApplicationpublicclassSecurityApplication{publicstaticvoidmain(String[] args){SpringApplication.run(SecurityApplication.class, args);}}@EnableWebSecurityclassSecurityConfigextendsWebSecurityConfigurerAdapter{@Overrideprotectedvoidconfigure(AuthenticationManagerBuilder auth)throwsException{ auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance()).withUser("admin").password("admin123").roles("ADMIN").and().withUser("user").password("user123").roles("USER");}@Overrideprotectedvoidconfigure(HttpSecurity http)throwsException{ http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER").antMatchers("/").permitAll().and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();}}@ControllerclassSecurityController{@GetMapping("/")publicStringindex(){return"index";}@GetMapping("/login")publicStringlogin(){return"login";}@GetMapping("/user")publicStringuser(){return"user";}@GetMapping("/admin")publicStringadmin(){return"admin";}}// 测试类@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classSecurityApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestIndexPage(){String response = restTemplate.getForObject("http://localhost:"+ port +"/",String.class);assertThat(response).contains("首页");}@TestvoidtestUserPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/user",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestUserPageWithUserAuthentication(){String credentials ="user:user123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/user",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("用户页面");}@TestvoidtestAdminPageWithoutAuthentication(){ResponseEntity<Map> response = restTemplate.getForEntity("http://localhost:"+ port +"/admin",Map.class);assertThat(response.getStatusCodeValue()).isEqualTo(302);}@TestvoidtestAdminPageWithAdminAuthentication(){String credentials ="admin:admin123";String base64Credentials =Base64.getEncoder().encodeToString(credentials.getBytes());HttpHeaders headers =newHttpHeaders(); headers.add("Authorization","Basic "+ base64Credentials);HttpEntity<String> entity =newHttpEntity<>(headers);ResponseEntity<String> response = restTemplate.exchange("http://localhost:"+ port +"/admin",HttpMethod.GET, entity,String.class);assertThat(response.getStatusCodeValue()).isEqualTo(200);assertThat(response.getBody()).contains("管理员页面");}}

输出结果

  • 访问http://localhost:8080/:返回首页。
  • 访问http://localhost:8080/login:返回登录页面。
  • 访问http://localhost:8080/user:返回用户页面。
  • 访问http://localhost:8080/admin:返回管理员页面。

✅ 结论:在实际开发中,Spring Boot与Spring Security的应用场景非常广泛,需要根据实际问题选择合适的安全框架。

总结

本章我们学习了Spring Boot安全认证与授权,包括Spring Security的定义与特点、Spring Boot与Spring Security的集成、Spring Boot与Spring Security的配置、Spring Boot与Spring Security的认证、Spring Boot与Spring Security的授权、Spring Boot与Spring Security的实际应用场景,学会了在实际开发中处理安全认证与授权问题。其中,Spring Security的定义与特点、Spring Boot与Spring Security的集成、Spring Boot与Spring Security的配置、Spring Boot与Spring Security的认证、Spring Boot与Spring Security的授权、Spring Boot与Spring Security的实际应用场景是本章的重点内容。从下一章开始,我们将学习Spring Boot的其他组件、微服务等内容。

Read more

FARS全自动科研系统技术深度解析:从多智能体架构到工业化科研范式

FARS全自动科研系统技术深度解析:从多智能体架构到工业化科研范式

前言 2026年2月12日至2月22日,一场持续228小时33分钟的直播在全球AI社区引发了持续震荡。屏幕另一端,一个名为FARS(Fully Automated Research System)的全自动研究系统,在没有人类干预的情况下,自主完成了从文献调研到论文撰写的完整科研流程,最终产出100篇学术论文,总消耗114亿Token,成本10.4万美元。 这场实验的意义远不止于“AI写论文”的简单升级。它向世界展示了科学发现的根本范式正在发生转移——从依赖人类灵感的“手工作坊”,转向由AI驱动的“工业化流水线”。本文将从最底层的技术细节出发,逐层拆解FARS的系统架构、智能体协作机制、资源调度策略、成本控制模型,以及与竞品的技术对比,为读者呈现一个完整的全自动科研系统技术图谱。 第一章 系统总体架构:四智能体流水线设计 1.1 核心设计理念:研究系统的第一性原理 FARS的设计并非简单地模仿人类科研流程,而是基于团队对“研究系统”本质的重新思考。创始团队提出,一个理想的研究系统应遵循两条基本原则: 1. 高效拓展知识边界:系统的吞吐量应成为核心评估指标,而非单篇论文的完

By Ne0inhk
基于神经网络的学生学习情况分析系统-hadoop+django

基于神经网络的学生学习情况分析系统-hadoop+django

1. 开发语言:Python 2. 框架:django 3. Python版本:python3.8 4. 数据库:mysql 5.7 5. 数据库工具:Navicat12 6. 开发软件:PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 学习数据 期末成绩预测 看板展示 摘要 系统基于B/S开发模式,采用Python语言进行开发,借助Django框架搭建系统架构,保证了系统的稳定性和可扩展性。同时,运用长短期记忆网络(LSTM)算法,对学生学习数据进行深入分析和挖掘。系统功能多样,管理员能够对用户信息进行全面管理,包括用户的注册、登录和权限设置等。可以对学生的学习数据进行收集、整理和分析,涵盖课堂表现、作业完成情况等。并且能够通过LSTM模型对学生的期末成绩进行科学预测,为教学决策提供有力支持。该系统的应用,

By Ne0inhk
【MySQL】三大范式

【MySQL】三大范式

下面我们来聊聊表的设计,如何设计一张比较合理,冗余性低且IO次数比较少,效率高的表。 我们需要先认识一下范式 什么是范式? 范式是⼀组规则。在设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式。 范式有哪些? 关系数据库有六种范式:第⼀范式(1NF)、第⼆范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,⼜称完美范式),越高的范式数据库冗余越小。然而,普遍认为范式越高虽然对数据关系有更好的约束性,但也可能导致数据库IO更繁忙,因此在实际应用中,数据库设计通常只需满足第三范式即可,如果在想提高效率,再去增加某个字段的冗余性 为啥越高的范式数据库冗余越小,IO效率越忙呢?继续看 第一范式 第一范式即:数据库表的每⼀列都是不可分割的原子数据项,而不能是集合,数组,对象等非原子数据 在关系型数据库的设计中,满足第⼀范式是对关系模式的基本要求。

By Ne0inhk
Rust异步测试与调试的实践指南

Rust异步测试与调试的实践指南

Rust异步测试与调试的实践指南 一、异步测试的基础 1.1 异步测试的概念 💡异步测试是对异步代码的功能和性能进行验证的过程,确保异步操作能够正确、高效地执行。与同步测试相比,异步测试需要处理任务调度、I/O操作和资源管理等复杂问题。 在Rust中,异步测试通常使用tokio::test宏或async-std::test宏来标记测试函数,这些宏会自动创建异步运行时环境。 1.2 常用的异步测试框架 * Tokio测试框架:适用于使用Tokio异步运行时的项目,提供tokio::test宏和tokio::spawn函数。 * Async-std测试框架:适用于使用async-std异步运行时的项目,提供async-std::test宏和async-std::task::spawn函数。 * Proptest:用于属性测试,支持异步属性测试。 * Mockall:用于模拟依赖对象,支持异步模拟。 1.3 简单异步函数的测试 下面是一个简单的异步函数测试示例: // src/lib.rsusetokio::time::sleep;usestd::time::D

By Ne0inhk