HttpSecurity各项配置
在 Spring Security 中,HttpSecurity 是用于配置 Web 层面安全策略的核心构建器(Builder)。它的核心使命是实现双重安全保障:认证(Authentication,解决“你是谁”的问题)与授权(Authorization,解决“你能做什么”的问题)。
随着 Spring Security 6.x 全面弃用旧版的 WebSecurityConfigurerAdapter,目前官方推荐采用基于 @Bean 的 Lambda 函数式配置方式。以下是 HttpSecurity 中各种常见配置的详细解读及配置示例:
请求授权配置 (authorizeHttpRequests)
这是最核心的配置之一,用于定义 URL 级别的访问控制规则。它遵循“先匹配先生效”的原则,因此宽泛的规则必须放在具体规则之后。
- requestMatchers():指定需要匹配的 URL 路径(新版推荐使用此方法替代旧的
antMatchers())。 - permitAll():无条件允许所有用户访问该路径(常用于公开接口、静态资源等)。
- hasRole("ADMIN"):要求访问者必须具备指定的角色(如 ADMIN)。
- authenticated():要求访问者必须是已认证的登录用户。
- anyRequest():匹配所有其他未被前面规则拦截的请求。
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // /public 下路径允许所有访问
.requestMatchers("/admin/**").hasRole("ADMIN") // /admin 下路径需管理员角色
.anyRequest().authenticated() // 其它所有请求都需要认证
)
表单登录配置 (formLogin)
用于配置基于表单的身份验证行为,支持自定义登录页面及成功/失败后的跳转逻辑。
- loginPage("/login"):指定自定义的前端登录页面路径。
- defaultSuccessUrl("/home", true):设置登录成功后的默认跳转页面。
- failureUrl("/login?error=true"):设置登录失败后的重定向地址。
- permitAll():必须将登录页及相关处理端点开放给未认证用户,否则会陷入重定向死循环。
.formLogin(form -> form
.loginPage("/login") // 自定义登录页面
.permitAll() // 登录页面允许所有访问
.defaultSuccessUrl("/home", true) // 登录成功后跳转主页
)
前后端分离项目一半不需要。
登出配置 (logout)
用于自定义用户的退出登录行为。
- logoutUrl("/logout"):触发登出操作的 URL。
- logoutSuccessUrl("/login?logout"):登出成功后跳转的页面。
- invalidateHttpSession(true):登出时使当前的 Session 失效。
- deleteCookies("JSESSIONID"):清除浏览器中的相关 Cookie。
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
)
CSRF 防护配置 (csrf)
跨站请求伪造(CSRF)防护默认是开启的,它会要求所有状态变更请求(POST, PUT, DELETE)携带 _csrf 令牌。初学者常因前端未传 Token 而遇到 403 错误。如果是纯前后端分离且使用 JWT 的项目,通常会选择关闭它。
.csrf(csrf -> csrf.disable()) // 禁用 CSRF 保护
HTTP Basic 认证 (httpBasic)
通常用于 RESTful API 的简单认证,客户端需要在请求头中提供用户名和密码。
.httpBasic(Customizer.withDefaults()) // 启用默认的 HTTP Basic 认证
会话管理配置 (sessionManagement)
用于控制 Session 的创建策略以及并发登录限制。
- maximumSessions(1):限制同一用户的最大并发会话数。
- maxSessionsPreventsLogin(true):当达到最大会话数时,阻止新的登录尝试。
.sessionManagement(session -> session
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
// 无状态会话 JWT使用
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
异常处理配置 (exceptionHandling)
用于自定义当用户未认证或无权限时的响应行为。
// 配置自定义认证入口点
.exceptionHandling(ex -> ex
.authenticationEntryPoint(customAuthenticationEntryPoint) // 认证失败处理
.accessDeniedHandler(accessDeniedHandler) // 授权失败处理
)
@Slf4j
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
log.warn("未授权访问被拒绝: {}", request.getRequestURI());
// 设置响应内容类型和状态码
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpStatus.UNAUTHORIZED.value());
// 创建人性化错误信息
Response<Void> errorResponse = new Response<>(
HttpStatus.UNAUTHORIZED.value(),
"访问被拒绝:请先登录获取访问权限",
null
);
// 将错误信息写入响应
response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
}
}
cors 跨域资源共享
它会在Filter链中添加一个CorsFilter。
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
- 配置顺序:
.cors()必须放在其他安全配置(如.csrf()、.authorizeHttpRequests())之前,否则跨域配置可能会被安全规则覆盖或失效。 - 凭证冲突:当设置
configuration.setAllowCredentials(true)时,allowedOrigins绝对不能使用通配符"*",必须明确指定具体的前端域名,否则浏览器会直接报错拦截4。 - 预检请求放行:确保
allowedMethods中包含了"OPTIONS"方法。如果自定义了拦截器,也要保证 OPTIONS 请求能正常到达 CORS 过滤器进行处理。 - 完全覆盖性:一旦你在 Spring Security 中启用了
.cors(),它就会完全接管跨域处理,之前在WebMvcConfigurer或@CrossOrigin注解中的相关配置将被忽略。
/**
* 定义全局 CORS 配置源
*/
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
// 允许的前端域名(生产环境强烈建议指定具体域名,而非 "*")
configuration.setAllowedOrigins(Arrays.asList("https://frontend.example.com"));
// 允许的 HTTP 方法(必须包含 OPTIONS 用于处理预检请求)
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
// 允许的请求头
configuration.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization"));
// 是否允许携带凭证(如 Cookie、JWT Token)
configuration.setAllowCredentials(true);
// 预检请求缓存时间(秒),减少 OPTIONS 请求频率
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
注意这里测试时遇到的坑,有的请求的Header中有Origin,有的没有,如果没有直接就放行了,这时就会发现好像配置没生效。什么时候有Origin呢?浏览器决定的。
在浏览器的安全沙箱机制下,JavaScript 代码是被禁止手动设置或修改 Origin 头的(它属于“Forbidden request header”)。这是为了防止恶意脚本伪造请求来源,从而破坏同源策略的安全防线。
原文链接:https://blog.dengwei.site/article/httpsecurity-various-configurations
本文来自博客园,作者:衣来伸手饭来张口,转载请注明原文链接:https://www.cnblogs.com/autowin/p/20342836

浙公网安备 33010602011771号