您的位置:首页 > 科技 > 能源 > 个人简历通用免费模板_移动端cpu天梯图2021_龙泉驿网站seo_整站seo定制

个人简历通用免费模板_移动端cpu天梯图2021_龙泉驿网站seo_整站seo定制

2025/5/9 18:29:51 来源:https://blog.csdn.net/m0_73837751/article/details/147253992  浏览:    关键词:个人简历通用免费模板_移动端cpu天梯图2021_龙泉驿网站seo_整站seo定制
个人简历通用免费模板_移动端cpu天梯图2021_龙泉驿网站seo_整站seo定制

HttpSecurity (Servlet API)

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.cors(cors -> cors.configurationSource(request -> {CorsConfiguration configuration = new CorsConfiguration();configuration.setAllowedOriginPatterns(List.of("*")); // 允许所有源configuration.setAllowedMethods(List.of("*")); // 允许所有方法configuration.setAllowedHeaders(List.of("*")); // 允许所有请求头configuration.setAllowCredentials(true); // 注意:使用 * 时必须设置为 falsereturn configuration;})).csrf(AbstractHttpConfigurer::disable)//对于一些无状态的 API 服务(例如,使用 JWT 认证的 RESTful API),CSRF 保护可以被禁用,因为这些服务通常通过 HTTP Header(如 Authorization)来认证请求,而不依赖 Cookie。对于这样的服务,CSRF 攻击的风险较低,通常可以通过禁用 CSRF 来提高性能。.formLogin(AbstractHttpConfigurer::disable)// 使用新的授权配置方式.authorizeHttpRequests(authz -> authz.requestMatchers( "/auth/login").permitAll() // 使用requestMatchers替代antMatchers.anyRequest().authenticated())// 会话管理配置保持不变.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)).addFilterBefore(jwtAuthenticationFilter, AnonymousAuthenticationFilter.class) ;  // 将 JwtAuthenticationFilter 加入过滤链return http.build();}
  • 适用场景:Servlet 容器下(Tomcat、Jetty等)的 Spring Boot Web 项目,或者传统的 Spring MVC 应用。

  • 对应的依赖spring-boot-starter-web + spring-boot-starter-security (针对 servlet)。

  • 底层协议:基于 HttpServletRequestHttpServletResponse(Servlet API),每个请求都在一个独立的线程里处理。

  • 典型用法:在传统 MVC/Web 应用中进行登录表单、会话管理、拦截/放行等安全配置。

ServerHttpSecurity (Reactive API) 

    @Beanpublic SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {http// CORS 配置.cors(cors -> cors.configurationSource(request -> {CorsConfiguration configuration = new CorsConfiguration();configuration.setAllowedOriginPatterns(List.of("*")); // 允许所有源configuration.setAllowedMethods(List.of("*")); // 允许所有方法configuration.setAllowedHeaders(List.of("*")); // 允许所有请求头configuration.setAllowCredentials(true); // 注意:使用 * 时必须设置为 falsereturn configuration;}))// 禁用 CSRF 和表单登录.csrf(ServerHttpSecurity.CsrfSpec::disable).formLogin(ServerHttpSecurity.FormLoginSpec::disable) // 禁用表单登录.httpBasic(ServerHttpSecurity.HttpBasicSpec::disable) // 禁用 HTTP Basic 认证.logout(ServerHttpSecurity.LogoutSpec::disable) // 禁用默认的注销端点// 使用新的授权配置方式.authorizeExchange(authz -> authz.pathMatchers("/order/**").permitAll() // 放行登录接口.anyExchange().authenticated()  // 其他请求需要认证)// 添加 JWT 认证过滤器.addFilterBefore(jwtAuthenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION); // 将 JwtAuthenticationFilter 加入过滤链return http.build();}
  • 适用场景:Reactive(反应式)Web 环境,比如使用 Spring WebFlux 或者 Spring Cloud Gateway

  • 对应的依赖spring-boot-starter-webflux + spring-boot-starter-security (针对 reactive)。

  • 底层协议:基于非阻塞式(Netty 等)的反应式流处理。

  • 典型用法:在使用 WebFlux HandlerSpring Cloud Gateway 时,通过 ServerHttpSecurity 配置响应式的安全策略。

为什么 Spring Cloud Gateway 往往会看到 ServerHttpSecurity

  • 因为 Spring Cloud Gateway 基于 WebFlux/reactor-netty 实现,是一个典型的非阻塞、响应式的网关。Spring Security 针对这种响应式请求的链式处理方式,需要使用 ServerHttpSecurity 来配置。

  • 而传统的基于 Servlet 的网关(例如 Zuul 1.x)就还是用 HttpSecurity。

 ServerHttpSecurity中添加的过滤器需要实现WebFilter(与Spring MVC不同)

import com.aqian.common.enums.ResponseCodeEnum;
import com.aqian.common.exception.BaseException;
import com.aqian.gatewayserver.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.annotation.NonNull;@Component
public class JwtAuthenticationWebFilter implements WebFilter {@Autowiredprivate JwtUtil jwtUtil;@Overridepublic @NonNull Mono<Void> filter(@NonNull ServerWebExchange exchange, @NonNull WebFilterChain chain) {// 从请求头中获取JWTString token = getJwtFromRequest(exchange);System.out.println("经过了webfilter");// 如果JWT存在且有效,则进行验证if (token != null) {try {// token 是否有效 / 是否过期 / 是否匹配对应用户Integer userId = Integer.parseInt(jwtUtil.extractUserId(token));boolean valid = jwtUtil.validateToken(token, userId);// 如果 Token 无效或过期,直接抛出异常if (!valid) {// 这里可以区分是过期还是无效,根据业务逻辑不同抛不同的异常if (jwtUtil.isTokenExpired(token)) {throw new BaseException(ResponseCodeEnum.TOKEN_EXPIRED);}throw new BaseException(ResponseCodeEnum.TOKEN_INVALID);}// 如果 token 合法,设置到 SecurityContextUsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(userId, null, null);SecurityContextHolder.getContext().setAuthentication(authentication);// 继续执行过滤链return chain.filter(exchange);} catch (BaseException e) {// 捕获自定义异常,并设置响应状态码exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();} catch (Exception e) {// 处理其他异常exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);return exchange.getResponse().setComplete();}}// 如果没有JWT,继续执行过滤链return chain.filter(exchange);}/*** 从HTTP请求头中提取JWT令牌* @param exchange ServerWebExchange* @return JWT令牌*/private String getJwtFromRequest(ServerWebExchange exchange) {String bearerToken = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION); // 从Authorization头部获取JWTif (bearerToken != null && bearerToken.startsWith("Bearer ")) { // 如果以"Bearer "开头return bearerToken.substring(7); // 去掉"Bearer ",返回JWT部分}return null; // 如果没有JWT令牌,返回null}
}

从表象上,许多开发者就会这么区分:“HttpSecurity 在 Spring Boot Web/MVC 场景下用;ServerHttpSecurity 多见于 Spring Cloud Gateway”。但更准确的表述是:

  • Servlet 模型 (Spring MVC、Tomcat、Jetty 等) → HttpSecurity

  • Reactive 模型 (Spring WebFlux、Netty、Gateway 等) → ServerHttpSecurity

Spring Boot 本身并不强行规定你用 Servlet 还是 Reactive。你可以在 Spring Boot 中使用任何一种模型,只要你的依赖是对应的 spring-boot-starter-web (MVC) 或者 spring-boot-starter-webflux (WebFlux)。

  • Spring Boot Servlet 项目一般默认是 HttpSecurity

  • Spring Boot WebFlux 项目则需要 ServerHttpSecurity

  • Spring Cloud Gateway 是响应式的,用 ServerHttpSecurity

如果你在写的服务最终是非响应式的(Servlet 模型),就用 HttpSecurity;如果你的服务是响应式的(Reactive 模型,如 Spring Cloud Gateway 项目),就用 ServerHttpSecurity。

Spring Security WebFlux 异常处理配置详解

在 Spring Security WebFlux 中,.exceptionHandling() 方法用于配置安全异常处理行为。下面我将详细讲解它的使用方法。

基本概念

exceptionHandling() 是 ServerHttpSecurity 配置中的一个重要部分,它允许你自定义当安全相关异常发生时(如认证失败、访问被拒绝等)的处理方式。

基本配置结构

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {return http// 其他配置....exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(...).accessDeniedHandler(...))// 其他配置....build();
}

主要配置选项

(1)authenticationEntryPoint

配置认证入口点,处理未认证用户尝试访问受保护资源时的响应。

.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint((exchange, ex) -> {// 自定义响应ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);DataBuffer buffer = response.bufferFactory().wrap("{\"error\":\"Unauthorized\"}".getBytes());return response.writeWith(Mono.just(buffer));})
)

或者使用预定义的入口点:

.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(new HttpBasicServerAuthenticationEntryPoint())
)

(2)accessDeniedHandler

配置访问拒绝处理器,处理已认证但权限不足的用户尝试访问受保护资源时的响应。

.exceptionHandling(exceptionHandling -> exceptionHandling.accessDeniedHandler((exchange, ex) -> {// 自定义响应ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.FORBIDDEN);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);DataBuffer buffer = response.bufferFactory().wrap("{\"error\":\"Access Denied\"}".getBytes());return response.writeWith(Mono.just(buffer));})
)

完整示例

下面是一个完整的配置示例:

@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {return http.authorizeExchange(exchanges -> exchanges.pathMatchers("/public/**").permitAll().pathMatchers("/admin/**").hasRole("ADMIN").anyExchange().authenticated()).httpBasic(withDefaults()).formLogin(withDefaults()).exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint((exchange, ex) -> {ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);DataBuffer buffer = response.bufferFactory().wrap("{\"message\":\"Authentication required\"}".getBytes());return response.writeWith(Mono.just(buffer));}).accessDeniedHandler((exchange, ex) -> {ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.FORBIDDEN);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);DataBuffer buffer = response.bufferFactory().wrap("{\"message\":\"Insufficient privileges\"}".getBytes());return response.writeWith(Mono.just(buffer));})).csrf(ServerHttpSecurity.CsrfSpec::disable).build();
}
高级用法

高级用法 

(1)根据请求类型返回不同响应

.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint((exchange, ex) -> {ServerHttpResponse response = exchange.getResponse();if (exchange.getRequest().getHeaders().getAccept().contains(MediaType.APPLICATION_JSON)) {response.setStatusCode(HttpStatus.UNAUTHORIZED);response.getHeaders().setContentType(MediaType.APPLICATION_JSON);DataBuffer buffer = response.bufferFactory().wrap("{\"error\":\"Unauthorized\"}".getBytes());return response.writeWith(Mono.just(buffer));} else {response.setStatusCode(HttpStatus.FOUND);response.getHeaders().setLocation(URI.create("/login"));return response.setComplete();}})
)

(2)记录异常日志

.exceptionHandling(exceptionHandling -> exceptionHandling.accessDeniedHandler((exchange, ex) -> {log.warn("Access denied for user {} to path {}", exchange.getPrincipal().block().getName(),exchange.getRequest().getPath());ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.FORBIDDEN);return response.setComplete();})
)

(2)组合多个处理器

.exceptionHandling(exceptionHandling -> exceptionHandling.authenticationEntryPoint(new DelegatingServerAuthenticationEntryPoint(Arrays.asList(new BearerTokenServerAuthenticationEntryPoint(),new HttpBasicServerAuthenticationEntryPoint(),new RedirectServerAuthenticationEntryPoint("/login"))))
)

注意事项

  • 在响应式编程中,确保你的处理器返回的是 Mono<Void>

  • 避免在处理器中进行阻塞操作

  • 考虑使用 ServerWebExchange 的完整能力来构建响应

  • 对于生产环境,建议将错误信息标准化

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com