当前位置: 首页 > web >正文

Spring Security 6.x 功能概览与代码示例

Spring Security 6.x 功能概览与代码示例

Spring Security 6.x 是一个功能强大的安全框架,提供了全面的安全解决方案。以下是其主要功能及相应的代码示例:

1. 认证功能

1.1 基于表单的认证

@Configuration
@EnableWebSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.requestMatchers("/public/**").permitAll().anyRequest().authenticated()).formLogin(form -> form.loginPage("/login").defaultSuccessUrl("/home").permitAll()).logout(logout -> logout.logoutSuccessUrl("/login?logout").permitAll());return http.build();}@Beanpublic UserDetailsService userDetailsService() {UserDetails user = User.withUsername("user").password("{noop}password").roles("USER").build();return new InMemoryUserDetailsManager(user);}
}

1.2 HTTP Basic 认证

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).httpBasic(Customizer.withDefaults());return http.build();
}

1.3 JWT 认证

@Component
public class JwtUtil {private final String secret = "your-secret-key";public String generateToken(UserDetails userDetails) {Map<String, Object> claims = new HashMap<>();return Jwts.builder().setClaims(claims).setSubject(userDetails.getUsername()).setIssuedAt(new Date(System.currentTimeMillis())).setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)).signWith(SignatureAlgorithm.HS256, secret).compact();}public Boolean validateToken(String token, UserDetails userDetails) {final String username = extractUsername(token);return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));}// 其他JWT相关方法...
}@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {@Autowiredprivate JwtUtil jwtUtil;@Autowiredprivate UserDetailsService userDetailsService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {final String authorizationHeader = request.getHeader("Authorization");String username = null;String jwt = null;if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {jwt = authorizationHeader.substring(7);username = jwtUtil.extractUsername(jwt);}if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);if (jwtUtil.validateToken(jwt, userDetails)) {UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));SecurityContextHolder.getContext().setAuthentication(authToken);}}filterChain.doFilter(request, response);}
}

2. 授权功能

2.1 基于角色的访问控制

@Configuration
@EnableMethodSecurity
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.requestMatchers("/admin/**").hasRole("ADMIN").requestMatchers("/user/**").hasAnyRole("ADMIN", "USER").requestMatchers("/public/**").permitAll().anyRequest().authenticated());return http.build();}
}@RestController
@RequestMapping("/api/admin")
public class AdminController {@GetMapping("/dashboard")@PreAuthorize("hasRole('ADMIN')")public String adminDashboard() {return "Admin Dashboard";}
}

2.2 基于权限的访问控制

@RestController
@RequestMapping("/api/products")
public class ProductController {@GetMapping@PreAuthorize("hasAuthority('PRODUCT_READ')")public List<Product> getAllProducts() {// 获取所有产品}@PostMapping@PreAuthorize("hasAuthority('PRODUCT_WRITE')")public Product createProduct(@RequestBody Product product) {// 创建新产品}@DeleteMapping("/{id}")@PreAuthorize("hasAuthority('PRODUCT_DELETE')")public void deleteProduct(@PathVariable Long id) {// 删除产品}
}

3. OAuth2 集成

3.1 OAuth2 客户端配置

@Configuration
public class OAuth2Config {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).oauth2Login(oauth2 -> oauth2.loginPage("/oauth2/authorization/my-client").defaultSuccessUrl("/home")).oauth2Client(Customizer.withDefaults());return http.build();}@Beanpublic ClientRegistrationRepository clientRegistrationRepository() {return new InMemoryClientRegistrationRepository(this.googleClientRegistration());}private ClientRegistration googleClientRegistration() {return ClientRegistration.withRegistrationId("google").clientId("google-client-id").clientSecret("google-client-secret").clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC).authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE).redirectUri("{baseUrl}/login/oauth2/code/{registrationId}").scope("openid", "profile", "email").authorizationUri("https://accounts.google.com/o/oauth2/v2/auth").tokenUri("https://www.googleapis.com/oauth2/v4/token").userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo").userNameAttributeName(IdTokenClaimNames.SUB).clientName("Google").build();}
}

3.2 OAuth2 资源服务器配置

@Configuration
@EnableWebSecurity
public class ResourceServerConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));return http.build();}@Beanpublic JwtDecoder jwtDecoder() {return JwtDecoders.fromIssuerLocation("https://your-oauth-server.com");}
}

4. 方法级安全

4.1 使用 @PreAuthorize 和 @PostAuthorize

@Service
public class ProductService {@PreAuthorize("hasRole('ADMIN') or @securityService.isProductOwner(#productId, authentication.name)")public Product updateProduct(Long productId, Product product) {// 更新产品逻辑}@PostAuthorize("returnObject.owner == authentication.name or hasRole('ADMIN')")public Product getProduct(Long productId) {// 获取产品逻辑}
}@Component("securityService")
public class SecurityService {public boolean isProductOwner(Long productId, String username) {// 检查用户是否是产品所有者return productRepository.findById(productId).map(product -> product.getOwner().equals(username)).orElse(false);}
}

5. CSRF 保护

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).formLogin(Customizer.withDefaults()).csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()));return http.build();
}

6. CORS 配置

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authz -> authz.anyRequest().authenticated()).cors(cors -> cors.configurationSource(corsConfigurationSource()));return http.build();
}@Bean
CorsConfigurationSource corsConfigurationSource() {CorsConfiguration configuration = new CorsConfiguration();configuration.setAllowedOrigins(Arrays.asList("https://example.com"));configuration.setAllowedMethods(Arrays.asList("GET", "POST"));configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", configuration);return source;
}

7. 密码编码

@Bean
public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
}@Service
public class UserService {@Autowiredprivate PasswordEncoder passwordEncoder;public User createUser(String username, String rawPassword) {String encodedPassword = passwordEncoder.encode(rawPassword);return new User(username, encodedPassword);}
}

8. 安全事件发布与监听

@Component
public class AuthenticationEventListener {@EventListenerpublic void handleAuthenticationSuccess(AuthenticationSuccessEvent event) {// 处理认证成功事件String username = event.getAuthentication().getName();log.info("User {} successfully authenticated", username);}@EventListenerpublic void handleAuthenticationFailure(AbstractAuthenticationFailureEvent event) {// 处理认证失败事件String username = event.getAuthentication().getName();log.warn("User {} failed to authenticate", username);}
}

9. 自定义访问决策

@Component
public class TimeBasedAccessDecisionVoter implements AccessDecisionVoter<Object> {@Overridepublic boolean supports(ConfigAttribute attribute) {return "TIME_ACCESS".equals(attribute.getAttribute());}@Overridepublic boolean supports(Class<?> clazz) {return true;}@Overridepublic int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {for (ConfigAttribute attribute : attributes) {if (this.supports(attribute)) {// 只允许在9:00-17:00之间访问int hour = LocalTime.now().getHour();if (hour >= 9 && hour < 17) {return ACCESS_GRANTED;} else {return ACCESS_DENIED;}}}return ACCESS_ABSTAIN;}
}@Configuration
@EnableMethodSecurity
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {@Autowiredprivate TimeBasedAccessDecisionVoter timeBasedVoter;@Overrideprotected AccessDecisionManager accessDecisionManager() {List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();decisionVoters.add(new RoleVoter());decisionVoters.add(new AuthenticatedVoter());decisionVoters.add(timeBasedVoter);return new UnanimousBased(decisionVoters);}
}// 使用自定义投票器
@PreAuthorize("hasRole('USER') and @timeBasedAccessDecisionVoter.supports('TIME_ACCESS')")
public String timeSensitiveMethod() {return "This method can only be accessed between 9:00 and 17:00";
}

10. 响应式安全支持

@EnableWebFluxSecurity
public class ReactiveSecurityConfig {@Beanpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {return http.authorizeExchange(exchanges -> exchanges.pathMatchers("/public/**").permitAll().anyExchange().authenticated()).httpBasic(Customizer.withDefaults()).formLogin(Customizer.withDefaults()).build();}@Beanpublic ReactiveUserDetailsService userDetailsService() {UserDetails user = User.withUsername("user").password("{noop}password").roles("USER").build();return new MapReactiveUserDetailsService(user);}
}

总结

Spring Security 6.x 提供了全面的安全功能,包括:

  1. 多种认证机制:表单登录、HTTP Basic、JWT、OAuth2等
  2. 灵活的授权控制:基于角色、权限、方法参数等
  3. 防护机制:CSRF、CORS、会话管理等
  4. 密码安全:多种密码编码器支持
  5. 事件机制:认证成功/失败事件监听
  6. 扩展性:自定义投票器、访问决策等
  7. 响应式支持:WebFlux应用的安全保护

这些功能使得Spring Security 6.x能够满足从简单应用到复杂企业级应用的各种安全需求。以上代码示例展示了如何使用这些功能,你可以根据实际需求进行调整和扩展。

http://www.xdnf.cn/news/19588.html

相关文章:

  • 程序员独立开发直播卖产品 SOP 教程
  • arm容器启动spring-boot端口报错
  • 基于开源AI大模型、AI智能名片与S2B2C商城小程序的“教育用户”模式探究
  • 谈谈对BFC的理解
  • 当代科学(范畴大辩论) 的学科分科(论据)的要素论(论点)及方法论(论证):边缘处理
  • 浅谈 SQL 窗口函数:ROW_NUMBER() 与聚合函数的妙用
  • 机器视觉opencv教程(三):形态学变换(腐蚀与膨胀)
  • 利用爬虫获取淘宝商品信息,参数解析
  • 基于单片机停车场管理系统/车位管理/智慧停车系统
  • 小迪自用web笔记22
  • Java线程池使用入门
  • uvm验证环境中struct(结构体)和class的区别与联系
  • 基于单片机老人防丢失防摔倒系统/老人健康状态检测系统
  • CMake⼯程指南-3
  • [光学原理与应用-361]:ZEMAX - 分析 - 像差分析
  • KingbaseES V009版本发布:国产数据库的新飞跃
  • 基于全参考图的质量评价均方误差MSE、峰值信噪比PSNR
  • [特殊字符] Rust概述:系统编程的革命者
  • 力扣(LeetCode) ——101. 对称二叉树(C语言)
  • Vue Router 嵌套路由与布局系统详解:理解 component = router-view 的核心概念
  • 接口测试总结-含接口测试和前端测试的区别与比较
  • Matlab自学笔记六十六:求解带参数的不等式
  • 国庆福建霞浦游
  • Linux 启动传参
  • 使用AdaLoRA 自适应权重矩阵微调大模型介绍篇
  • Docker一小时快速上手(附报错解决方式)
  • 【MLLM】具有长期记忆的多模态智能体框架M3-Agent
  • 《信息学奥林匹克辞典》中的一个谬误
  • Java异常处理完全指南:从入门到精通
  • 安装proteus,并实现stm32仿真