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

Linux命名管道(FIFO)通信:从原理到实操,一文搞懂跨进程通信

Linux命名管道(FIFO)通信:从原理到实操,一文搞懂跨进程通信

🔥个人主页:Cx330🌸 ❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》 《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔 《Git深度解析》:版本管理实战全解 🌟心向往之行必能至 🎥Cx330🌸的简介: 目录 前言: 一、先搞懂:命名管道(FIFO)是什么? 1. 命名管道的本质 2. 命名管道的核心特点 3. 命名管道与匿名管道的对比 二. 命名管道的创建方式 2.1 命令行创建(mkfifo 命令) 2.2 代码创建(mkfifo 函数) 2.3 命名管道的打开规则 三、实操实现:手搓命名管道通信 3.1 前置准备(

By Ne0inhk
Flutter 组件 injectfy 适配鸿蒙 HarmonyOS 实战:逻辑注入矩阵,构建跨模块解耦与动态依赖管理架构

Flutter 组件 injectfy 适配鸿蒙 HarmonyOS 实战:逻辑注入矩阵,构建跨模块解耦与动态依赖管理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 injectfy 适配鸿蒙 HarmonyOS 实战:逻辑注入矩阵,构建跨模块解耦与动态依赖管理架构 前言 在鸿蒙(OpenHarmony)生态迈向超大规模应用拆分、涉及数百个独立 Feature 模块与底层硬件服务深度解耦的背景下,如何实现灵活的“控制反转(IoC)”与“依赖注入(DI)”,已成为决定应用架构可维护性的“生命线”。在鸿蒙设备这类强调模块化挂载与 HAP/HSP 动态分发的环境下,如果应用内部的组件实例依然采用强耦合的硬编码初始化,由于由于各模块间复杂的循环依赖,极易由于由于初始化顺序错乱导致应用在流转拉起时的崩溃。 我们需要一种能够实现零成本解耦、支持单例(Singleton)与工厂(Factory)模式且具备极简注册语义的依赖注入框架。 injectfy 为 Flutter 开发者引入了轻量级的对象容器管理方案。它不仅支持对底层 Service 的全局托管,更提供了灵活的注入探测机制。在适配到鸿蒙

By Ne0inhk