发布于2026-07-17 阅读(0)
扫一扫,手机访问
Spring Security 2026 构建安全、可靠的企业应用实践指南
Spring Security 作为 Spring 生态中的安全框架,提供了一套完整的安全解决方案。随着版本不断演进,2026 版本带来了诸多新特性和改进。从架构视角来看,它不仅是技术工具,更是构建安全、可靠企业应用的关键能力。
Spring Security 从早期的 Acegi Security 发展到如今的 2026 版本,经历了从简单认证授权到完整安全生态系统的蜕变。每一个版本的更新,都在追求更全面、更灵活的安全方案。
Spring Security 2026 的核心特性包括:
核心策略:
示例:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/user/**").authenticated()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/payment/**").hasRole("USER").and()
.mfa()
.withAuthenticationMethods(
mfa -> mfa
.sms()
.email()
.totp()
)
.requireMfaFor("/api/payment/**");
}
}
坦白说,这里可以优化得更优雅。多因素认证能显著提升系统的安全性,防止未授权访问。
核心策略:
示例:
@Configuration
public class OAuth2Config {
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(
ClientRegistration.withRegistrationId("google")
.clientId("client-id")
.clientSecret("client-secret")
.redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
.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()
);
}
@Bean
public OAuth2AuthorizedClientService authorizedClientService(ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}
}
@RestController
public class OAuth2Controller {
@Autowired
private OAuth2AuthorizedClientService authorizedClientService;
@GetMapping("/user")
public Map user(@AuthenticationPrincipal OAuth2User principal) {
return principal.getAttributes();
}
}
核心策略:
示例:
@Configuration
public class PasswordConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12); // 12 轮哈希
}
}
@Service
public class UserService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserRepository userRepository;
public User createUser(User user) {
// 加密密码
user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepository.sa ve(user);
}
public boolean checkPassword(User user, String rawPassword) {
return passwordEncoder.matches(rawPassword, user.getPassword());
}
}
核心策略:
示例:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.antMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated();
}
}
@Service
public class RoleService {
public void assignRoleToUser(Long userId, String roleName) {
// 分配角色给用户
}
}
核心策略:
@PreAuthorize 等注解进行权限检查示例:
@RestController
@RequestMapping("/api")
public class ProductController {
@PreAuthorize("hasAuthority('PRODUCT_READ')")
@GetMapping("/products")
public List getProducts() {
// 获取产品列表
}
@PreAuthorize("hasAuthority('PRODUCT_CREATE')")
@PostMapping("/products")
public Product createProduct(@RequestBody Product product) {
// 创建产品
}
@PreAuthorize("hasAuthority('PRODUCT_UPDATE')")
@PutMapping("/products/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product product) {
// 更新产品
}
@PreAuthorize("hasAuthority('PRODUCT_DELETE')")
@DeleteMapping("/products/{id}")
public void deleteProduct(@PathVariable Long id) {
// 删除产品
}
}
核心策略:
示例:
@RestController
@RequestMapping("/api")
public class OrderController {
@PreAuthorize("hasRole('USER') and #userId == principal.id")
@GetMapping("/users/{userId}/orders")
public List getOrders(@PathVariable Long userId) {
// 获取用户的订单
}
@PreAuthorize("hasRole('USER') and @orderService.isOrderOwner(#id, principal.id)")
@GetMapping("/orders/{id}")
public Order getOrder(@PathVariable Long id) {
// 获取订单
}
}
@Service("orderService")
public class OrderService {
public boolean isOrderOwner(Long orderId, Long userId) {
// 检查订单是否属于用户
Order order = orderRepository.findById(orderId).orElse(null);
return order != null && order.getUserId().equals(userId);
}
}
核心策略:
示例:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/api/**"); // API 接口使用其他方式保护
}
}
// 前端使用 CSRF 令牌
//
核心策略:
示例:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new XssInterceptor());
}
}
public class XssInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 清理请求参数中的 XSS 攻击
Enumeration parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
String parameterValue = request.getParameter(parameterName);
if (parameterValue != null) {
String cleanedValue = XssUtils.clean(parameterValue);
// 替换参数值
// 注意:这需要自定义 HttpServletRequestWrapper
}
}
return true;
}
}
核心策略:
示例:
// 使用 JPA 防止 SQL 注入 @Repository public interface UserRepository extends JpaRepository{ // 使用参数化查询 List findByUsername(String username); // 使用 @Query 注解,同样是参数化查询 @Query("SELECT u FROM User u WHERE u.email = :email") User findByEmail(@Param("email") String email); } // 避免使用原生 SQL 拼接 // 错误示例 // String sql = "SELECT * FROM users WHERE username = '" + username + "'"; // 正确示例 // String sql = "SELECT * FROM users WHERE username = ?"; // preparedStatement.setString(1, username);
核心策略:
示例:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionFixation().migrateSession() // 会话固定保护
.maximumSessions(1) // 每个用户最多一个会话
.expiredUrl("/login?expired")
.maxSessionsPreventsLogin(true); // 达到最大会话数时阻止登录
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
核心策略:
示例:
@Configuration
public class JwtConfig {
@Bean
public JwtTokenProvider jwtTokenProvider() {
return new JwtTokenProvider("secret-key", 3600000); // 1小时过期
}
}
@Service
public class JwtTokenProvider {
private final String secretKey;
private final long validityInMilliseconds;
public JwtTokenProvider(String secretKey, long validityInMilliseconds) {
this.secretKey = secretKey;
this.validityInMilliseconds = validityInMilliseconds;
}
public String createToken(String username, List roles) {
Claims claims = Jwts.claims().setSubject(username);
claims.put("roles", roles);
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliseconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
return false;
}
}
public String getUsername(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();
}
}
核心策略:
示例:
// API 网关配置
@Configuration
public class GatewaySecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http
.authorizeExchange()
.pathMatchers("/api/public/**").permitAll()
.anyExchange().authenticated()
.and()
.oauth2Login()
.and()
.oauth2ResourceServer()
.jwt();
return http.build();
}
}
// 服务间通信
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(OAuth2AuthorizedClientManager authorizedClientManager) {
OAuth2AuthorizedClientHttpRequestInterceptor interceptor = new OAuth2AuthorizedClientHttpRequestInterceptor(
authorizedClientManager, clientRegistrationId -> {
OAuth2AuthorizeRequest request = OAuth2AuthorizeRequest.withClientRegistrationId("service-to-service")
.principal(new AnonymousAuthenticationToken("anonymous", "anonymousUser", Collections.emptyList()))
.build();
return authorizedClientManager.authorize(request);
}
);
return new RestTemplate(Collections.singletonList(interceptor));
}
}
核心策略:
示例:
// 认证服务
@RestController
@RequestMapping("/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@PostMapping("/login")
public ResponseEntity> login(@RequestBody LoginRequest request) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
);
SecurityContextHolder.getContext().setAuthentication(authentication);
List roles = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.toList());
String token = jwtTokenProvider.createToken(request.getUsername(), roles);
return ResponseEntity.ok(new JwtResponse(token));
}
}
// 授权服务
@Service
public class AuthorizationService {
public boolean hasPermission(String userId, String resourceId, String action) {
// 检查用户是否有权限执行操作
}
}
核心策略:
示例:
@Configuration
public class AuditConfig {
@Bean
public AuditEventRepository auditEventRepository() {
return new InMemoryAuditEventRepository();
}
@Bean
public AuditListener auditListener() {
return new AuditListener(auditEventRepository());
}
}
@Service
public class AuditService {
@Autowired
private AuditEventRepository auditEventRepository;
public void logEvent(String principal, String type, Map data) {
AuditEvent event = new AuditEvent(principal, type, data);
auditEventRepository.add(event);
}
}
// 使用审计服务
@Service
public class UserService {
@Autowired
private AuditService auditService;
public void changePassword(String username, String newPassword) {
// 更改密码
auditService.logEvent(username, "PASSWORD_CHANGED", Collections.singletonMap("username", username));
}
}
核心策略:
示例:
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer metricsCommonTags() {
return registry -> registry.config()
.commonTags("application", "security-service");
}
@Bean
public SecurityMetrics securityMetrics() {
return new SecurityMetrics();
}
}
@Service
public class SecurityMetrics {
private final Counter failedLoginAttempts;
private final Counter successfulLogins;
public SecurityMetrics(MeterRegistry meterRegistry) {
this.failedLoginAttempts = Counter.builder("security.login.failed")
.description("Number of failed login attempts")
.register(meterRegistry);
this.successfulLogins = Counter.builder("security.login.successful")
.description("Number of successful logins")
.register(meterRegistry);
}
public void recordFailedLogin() {
failedLoginAttempts.increment();
}
public void recordSuccessfulLogin() {
successfulLogins.increment();
}
}
// 使用安全指标
@Service
public class AuthService {
@Autowired
private SecurityMetrics securityMetrics;
public boolean authenticate(String username, String password) {
try {
// 认证逻辑
securityMetrics.recordSuccessfulLogin();
return true;
} catch (AuthenticationException e) {
securityMetrics.recordFailedLogin();
return false;
}
}
}
核心策略:
示例:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.anyRequest().authenticated() // 默认拒绝
.and()
.formLogin()
.and()
.httpBasic();
}
}
核心策略:
示例:
@SpringBootTest
@AutoConfigureMockMvc
public class SecurityTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testPublicEndpoint() throws Exception {
mockMvc.perform(get("/api/public/health"))
.andExpect(status().isOk());
}
@Test
public void testProtectedEndpointWithoutAuthentication() throws Exception {
mockMvc.perform(get("/api/user/profile"))
.andExpect(status().isUnauthorized());
}
@Test
public void testProtectedEndpointWithAuthentication() throws Exception {
mockMvc.perform(get("/api/user/profile")
.with(httpBasic("user", "password")))
.andExpect(status().isOk());
}
}
核心策略:
示例:
// 安全编码规范
public class SecurityUtils {
// 防止 XSS 攻击
public static String escapeHtml(String input) {
return HtmlUtils.htmlEscape(input);
}
// 防止 SQL 注入
public static String escapeSql(String input) {
// 实现 SQL 注入防护
}
// 安全的密码生成
public static String generateSecurePassword() {
// 生成安全的密码
}
}
Spring Security 团队已经开始规划 2027 版本,预计将带来更多创新特性:
发展方向:
Spring Security 2026 是一个功能强大、设计优雅的安全框架,它为我们提供了全面的安全解决方案。通过合理应用这些最佳实践,可以构建更安全、更可靠的企业应用。
这里其实可以做得更优雅一些。借助 Spring Security 2026,能够以更简洁、更灵活的方式实现安全功能,为业务创造更大的价值。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8