如何在Spring Boot 3中配置仅允许本地主机(localhost)访问?
Spring Boot 3 配置仅允许本地主机访问的实现方案
Spring Boot 3 配套的 Spring Security 6 对授权配置做了重大调整,原 Spring Boot 2 中基于字符串表达式的 access("hasIpAddress(...)") 方式已被移除,需要改用基于 Lambda 表达式或自定义 AuthorizationManager 的方式实现「本地IP免认证、其他请求需认证」的需求。
方案一:使用 Lambda 表达式快速实现
直接在授权配置中通过 IpAddressMatcher 匹配本地IP,结合用户认证状态判断:
import org.springframework.security.web.util.matcher.IpAddressMatcher; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.context.annotation.Bean; import org.springframework.security.authorization.AuthorizationDecision; @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // 初始化本地IP匹配器(覆盖IPv4和IPv6的本地地址) IpAddressMatcher ipv4Local = new IpAddressMatcher("127.0.0.1/32"); IpAddressMatcher ipv6Local = new IpAddressMatcher("::1/128"); http.authorizeHttpRequests(auth -> auth // 对所有请求应用授权规则 .anyRequest().access((authentication, context) -> { // 判断请求是否来自本地IP boolean isLocalRequest = ipv4Local.matches(context.getRequest()) || ipv6Local.matches(context.getRequest()); // 判断当前用户是否已认证 boolean isUserAuthenticated = authentication.isAuthenticated(); // 满足任一条件则允许访问 return new AuthorizationDecision(isLocalRequest || isUserAuthenticated); }) ) // 允许所有人访问登录页面 .formLogin(form -> form.permitAll()); return http.build(); } }
方案二:自定义 AuthorizationManager 复用逻辑
如果需要在多个地方复用本地IP+认证的授权规则,可以自定义 AuthorizationManager 实现类:
1. 自定义授权管理器
import org.springframework.security.authorization.AuthorizationDecision; import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.core.Authentication; import org.springframework.security.web.access.intercept.RequestAuthorizationContext; import org.springframework.security.web.util.matcher.IpAddressMatcher; public class LocalOrAuthenticatedAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> { // 预定义本地IP匹配器 private final IpAddressMatcher ipv4Local = new IpAddressMatcher("127.0.0.1/32"); private final IpAddressMatcher ipv6Local = new IpAddressMatcher("::1/128"); @Override public AuthorizationDecision check(Supplier<Authentication> authenticationSupplier, RequestAuthorizationContext context) { boolean isLocal = ipv4Local.matches(context.getRequest()) || ipv6Local.matches(context.getRequest()); boolean isAuthenticated = authenticationSupplier.get().isAuthenticated(); return new AuthorizationDecision(isLocal || isAuthenticated); } }
2. 在安全配置中使用自定义管理器
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.context.annotation.Bean; @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth -> auth .anyRequest().access(new LocalOrAuthenticatedAuthorizationManager()) ) .formLogin(form -> form.permitAll()); return http.build(); } }
关键说明
IpAddressMatcher支持CIDR格式的IP匹配,127.0.0.1/32精确匹配IPv4本地回环地址,::1/128精确匹配IPv6本地回环地址。formLogin().permitAll()保留了原Spring Boot 2配置中允许所有人访问登录页面的逻辑,确保非本地用户可以通过登录获取认证权限。
内容的提问来源于stack exchange,提问作者user5479362
相关产品推荐
相关产品推荐

