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

Clawdbot部署Qwen3:32B实操:解决‘gateway token missing’的三种Token注入方式对比

Clawdbot部署Qwen3:32B实操:解决‘gateway token missing’的三种Token注入方式对比 Clawdbot 是一个统一的 AI 代理网关与管理平台,旨在为开发者提供一个直观的界面来构建、部署和监控自主 AI 代理。通过集成的聊天界面、多模型支持和强大的扩展系统,Clawdbot 让 AI 代理的管理变得简单高效。 当你在 ZEEKLOG 星图镜像广场一键部署 Clawdbot 并集成本地运行的 qwen3:32b 模型后,大概率会遇到这样一个提示: disconnected (1008): unauthorized: gateway token missing (open a tokenized dashboard URL or paste token in Control UI settings) 这不是报错,也不是服务没起来—

By Ne0inhk
Flutter 组件 powersync_attachments_helper 的适配 鸿蒙Harmony 实战 - 驾驭分布式附件同步、实现鸿蒙端大文件离线存储与生命周期自动化管理方案

Flutter 组件 powersync_attachments_helper 的适配 鸿蒙Harmony 实战 - 驾驭分布式附件同步、实现鸿蒙端大文件离线存储与生命周期自动化管理方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 powersync_attachments_helper 的适配 鸿蒙Harmony 实战 - 驾驭分布式附件同步、实现鸿蒙端大文件离线存储与生命周期自动化管理方案 前言 在鸿蒙(OpenHarmony)生态的分布式多媒体协作、工业设备故障图片上报以及需要频繁处理大量音频/视频附件的专业级应用开发中,“非结构化数据与 SQL 逻辑的一致性同步”是决定应用能否在大规模复杂场景下存活的技术深水区。面对一条已经同步成功的“设备巡检记录”。如果其关联的“高清故障原图”因为同步时机错位、由于存储空间不足导致的本地缓存被回收,或者是在鸿蒙手机与平板之间由于同步策略不同步导致的文件路径失效。那么不仅会导致用户在查看详情时看到令人沮丧的“附件丢失”占位图,更会严重削弱政务类资产审计的底层严密性。 我们需要一种“逻辑关联、物理对齐”的附件治理艺术。 powersync_attachments_helper 是一套专为 PowerSync 设计的附件同步

By Ne0inhk
微服务链路追踪实战:SkyWalking vs Zipkin 架构深度解析与性能优化指南

微服务链路追踪实战:SkyWalking vs Zipkin 架构深度解析与性能优化指南

目录 1. 链路追踪:分布式系统的“X光机” 1.1 从单体到微服务:排查困境的演变 1.2 链路追踪的核心价值矩阵 2. 核心原理解析:Trace、Span与上下文传播 2.1 基本概念:一次请求的完整“病历” 2.2 上下文传播:Trace ID的“接力赛” 2.3 采样算法:平衡精度与开销的智慧 3. SkyWalking深度解析:无侵入监控的艺术 3.1 架构全景:从Agent到UI的完整链路 3.2 字节码增强:Java Agent的魔法 3.3 生产环境配置模板 3.4 性能特性与调优 4.

By Ne0inhk