WebMvcConfig 和 WebSecurityConfig 详解 - 实践

news/2025/11/28 19:36:13/文章来源:https://www.cnblogs.com/yangykaifa/p/19283982

WebMvcConfig 和 WebSecurityConfig 详解

一、概述

Spring Boot项目中有两个重要的配置类,它们分别负责不同的功能:

二、WebMvcConfig 详解

2.1 基本概念

WebMvcConfig 是Spring MVC框架的配置类,通过实现 WebMvcConfigurer 接口来自定义MVC的行为。

2.2 作用范围

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 配置Spring MVC的各个方面
}

主要功能

  1. 注册拦截器(Interceptor) - 自定义请求拦截逻辑
  2. 配置静态资源映射 - 静态文件访问路径
  3. 添加类型转换器 - 数据格式转换
  4. 配置视图解析器 - 视图渲染
  5. 添加格式化器 - 日期、数字格式化
  6. 跨域配置(CORS) - 跨域资源共享

2.3 项目中的实际应用

    @Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册API Key拦截器,只拦截 /openapi/** 路径registry.addInterceptor(apiKeyInterceptor).addPathPatterns("/openapi/**").order(1);  // 设置优先级}

当前项目中的作用

  • 注册了 ApiKeyInterceptor 拦截器
  • 只拦截 /openapi/** 路径的请求
  • 用于OpenAPI接口的API Key认证

2.4 WebMvcConfigurer 常用方法

public interface WebMvcConfigurer {
// 1. 添加拦截器
default void addInterceptors(InterceptorRegistry registry) {}
// 2. 静态资源处理
default void addResourceHandlers(ResourceHandlerRegistry registry) {}
// 3. 跨域配置
default void addCorsMappings(CorsRegistry registry) {}
// 4. 视图解析器
default void configureViewResolvers(ViewResolverRegistry registry) {}
// 5. 参数解析器
default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}// 6. 返回值处理器default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}// 7. 消息转换器default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}// 8. 异常处理器default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}}

2.5 典型使用场景

场景1:注册拦截器

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
}

场景2:静态资源映射

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}

场景3:跨域配置

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE");
}

三、WebSecurityConfig 详解

3.1 基本概念

WebSecurityConfig 是Spring Security框架的配置类,通过继承 WebSecurityConfigurerAdapter 来配置安全策略。

3.2 作用范围

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 配置Spring Security的安全策略
}

主要功能

  1. 认证配置(Authentication) - 用户身份验证
  2. 授权配置(Authorization) - 访问权限控制
  3. 过滤器配置 - 安全过滤器链
  4. 会话管理 - Session策略
  5. CSRF防护 - 跨站请求伪造防护
  6. 密码加密 - 密码加密器配置

3.3 项目中的实际配置

3.3.1 密码加密器配置
    /*** BCrypt密码加密器*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}

作用:提供密码加密和解密的功能,用于:

  • 用户注册时加密密码
  • 用户登录时验证密码
  • API Key Secret的加密存储
3.3.2 认证管理器配置
    @Overridepublic void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {// 配置UserDetailsService和密码加密器authenticationManagerBuilder.userDetailsService(this.userDetailsService).passwordEncoder(passwordEncoder());}

作用

  • 配置自定义的 UserDetailsService(用于加载用户信息)
  • 配置密码加密器(用于验证密码)
3.3.3 HTTP安全配置(核心)
    @Overrideprotected void configure(HttpSecurity httpSecurity) throws Exception {httpSecurity// 禁用CSRF(使用JWT不需要).csrf().disable()// 启用CORS.cors().and()// 认证失败处理.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()// 基于token,不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()// 请求授权配置.authorizeRequests()// 登录接口允许匿名访问.antMatchers("/api/auth/validate","/admin/sysUser/add","/api/**" ).permitAll()// OpenAPI接口允许匿名访问(由ApiKeyInterceptor验证).antMatchers("/openapi/**").permitAll()// Swagger相关接口允许匿名访问.antMatchers("/swagger-resources/**","/v2/api-docs/**","/doc.html/**","/webjars/**","/favicon.ico").permitAll()// 其他所有请求需要认证.anyRequest().authenticated();// 添加JWT过滤器httpSecurity.addFilterBefore(new ZkMeAuthenticationTokenFilter(this.jwtSecret),UsernamePasswordAuthenticationFilter.class);// 禁用缓存httpSecurity.headers().cacheControl();}

详细解析

  1. CSRF防护

    .csrf().disable()
    • 禁用CSRF防护,因为使用JWT Token进行认证,不需要CSRF Token
  2. CORS配置

    .cors().and()
    • 启用跨域资源共享支持
  3. 异常处理

    .exceptionHandling()
    .authenticationEntryPoint(unauthorizedHandler)
    • 配置认证失败时的处理入口点(返回401未授权)
  4. Session策略

    .sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    • 设置为无状态,不使用Session(适合JWT Token认证)
  5. 请求授权规则

    .authorizeRequests()
    .antMatchers("/api/auth/validate", ...).permitAll()  // 允许匿名访问
    .antMatchers("/openapi/**").permitAll()                // 允许匿名访问
    .anyRequest().authenticated()                          // 其他需要认证
    • 定义哪些路径允许匿名访问,哪些需要认证
  6. JWT过滤器

    httpSecurity.addFilterBefore(
    new ZkMeAuthenticationTokenFilter(this.jwtSecret),
    UsernamePasswordAuthenticationFilter.class
    );
    • 在Spring Security的过滤器链中添加自定义的JWT认证过滤器
    • 优先级在 UsernamePasswordAuthenticationFilter 之前
3.3.4 Web安全配置(静态资源)
    @Overridepublic void configure(WebSecurity web) throws Exception {// 忽略静态资源web.ignoring().antMatchers("/css/**","/js/**","/images/**","/fonts/**","/**/*.html","/favicon.ico");}

作用:让Spring Security完全忽略这些静态资源路径,不进行安全校验,提高性能。

四、两者的区别和联系

4.1 核心区别

特性WebMvcConfigWebSecurityConfig
框架Spring MVCSpring Security
职责MVC功能配置安全策略配置
拦截方式拦截器(Interceptor)过滤器(Filter)
执行时机DispatcherServlet之后DispatcherServlet之前
典型用途日志、参数转换、跨域认证、授权、加密

4.2 执行顺序

客户端请求↓
[WebSecurityConfig - 过滤器链]├─ JWT Token过滤器├─ CSRF过滤器└─ 其他安全过滤器↓
DispatcherServlet↓
[WebMvcConfig - 拦截器链]├─ API Key拦截器(针对/openapi/**)└─ 其他拦截器↓
Controller处理↓
返回响应

4.3 配置优先级

Spring Security过滤器 → Spring MVC拦截器

  1. Security过滤器 先执行(在Servlet层面)

    • 进行认证授权检查
    • 如果认证失败,直接返回401,不会进入MVC流程
  2. MVC拦截器 后执行(在DispatcherServlet之后)

    • 进行业务层面的拦截处理
    • 可以访问Handler、Model等MVC对象

4.4 实际应用示例

场景:OpenAPI接口认证

1. 请求到达: POST /openapi/v1/kyb/programs↓
2. WebSecurityConfig:- 检查路径 /openapi/** → permitAll()(允许匿名访问)- 通过Security过滤器链↓
3. DispatcherServlet:- 路由到对应的Controller↓
4. WebMvcConfig:- ApiKeyInterceptor拦截 /openapi/**- 验证 X-API-Key 和 X-API-Secret- 验证通过,继续执行↓
5. Controller处理业务逻辑↓
6. 返回响应

为什么这样设计?

  • Spring Security层面:/openapi/** 允许匿名访问,不强制JWT认证
  • Spring MVC层面:ApiKeyInterceptor 进行API Key认证
  • 实现了双重认证机制:管理后台用JWT,OpenAPI用API Key

五、常见配置示例

5.1 完整的WebMvcConfig示例

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private ApiKeyInterceptor apiKeyInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 1. API Key拦截器
registry.addInterceptor(apiKeyInterceptor)
.addPathPatterns("/openapi/**")
.order(1);
// 2. 日志拦截器
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/api/**")
.order(2);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true);
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}

5.2 完整的WebSecurityConfig示例

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.cors().and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/openapi/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(
"/css/**", "/js/**", "/images/**",
"/swagger-resources/**", "/v2/api-docs/**"
);
}
}

六、最佳实践

6.1 职责分离

6.2 性能优化

// WebSecurityConfig中忽略静态资源,避免不必要的安全校验
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/static/**");
}

6.3 双重认证机制

// Security层面:允许匿名访问
.antMatchers("/openapi/**").permitAll()
// MVC层面:API Key认证拦截器
registry.addInterceptor(apiKeyInterceptor)
.addPathPatterns("/openapi/**");

6.4 路径匹配规则

  • 精确匹配/api/users
  • 通配符匹配/api/**(匹配所有子路径)
  • 方法匹配.mvcMatchers(HttpMethod.POST, "/api/users")

七、总结

WebMvcConfig

  • 作用:配置Spring MVC的行为(拦截器、静态资源、跨域等)
  • 适用场景:业务层面的拦截、日志记录、参数转换
  • 执行时机:DispatcherServlet之后

WebSecurityConfig

两者配合

  • Security配置:决定哪些请求需要认证(粗粒度控制)
  • MVC配置:在通过Security后,进行业务层面的拦截(细粒度控制)
  • 完美配合:实现灵活的双重认证机制(JWT + API Key)

通过这两个配置类的配合,可以实现既安全又灵活的Web应用架构!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/980035.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins 已成过去式!新兴替代软件GitHub Actions即将崛起

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P12828

神秘啊 \(x\oplus y=gcd(x,y)\) 发现,当 \(x<y\) 时,\(x\oplus y\ge y-x\ge gcd(x,y)\) 那么我们这个条件就限定了上面这 \(3\) 个东西相等,记为 \(d\) \(y-x=d\) 且 \(gcd(x,y)=d\) 那么设 \(x=kd\),\(y=kd+d\…

XYD11.25模拟赛

madoka 和 homura,圆神场! T1: 显而易见的是,我们最终两个人吃的 pocky 是序列的左右两段,但是这个贡献可能是负的,所以就不能贪心来优化状态了。容易感受到,这题很纯粹。 设 \(dp[l][r][k][0/1]\),第三维是根号…

HTML---------------示例代码(1)

<!DOCTYPE html> <html><head><meta charset="utf-8"><title>童心少年</title></head><body> <table border="1"><tr><td>…

xenomai3 pcie网卡偶发性的oops

待解决 报错截图[ 1954.723628] ------------[ cut here ]------------ [ 1954.723658] NETDEV WATCHDOG: enp6s0 (r8168): transmit queue 0 timed out [ 1954.723695] WARNING: CPU: 5 PID: 0 at net/sched/sch_gene…

OOP-实验4 - FF

实验任务1 源代码task11 // 类GradeCalc声明2 3 #pragma once4 5 #include <vector>6 #include <array>7 #include <string>8 9 class GradeCalc 10 { 11 public: 12 GradeCalc(const std::stri…

day13-影刀RPA01

今日内容 1 RPA介绍 1.1 RPA是什么 # 1 RPA(Robotic Process Automation,机器人流程自动化[自动化流程机器人])是一种通过软件机器人(或称为 “数字员工”)模拟人类在计算机上的操作行为,来自动执行重复性、规则…

11月28日总结 - 作业----

11月28日总结写机器学习作业

6001 week1

🔰 开始第 1 章:AI、机器学习、数据科学(中英文对照) (内容来自 PDF、录播1、课前预习全部相关段落)第 1 章:AI、机器学习与数据科学 Chapter 1: AI, Machine Learning, and Data Science1.1 什么是数据科学?…

TDengine IDMP “无问智推”:克服工业智能化“信息沉睡”难题的利器

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

P10055

好像和我们模拟赛T2很像啊hhh。 我们还是考虑 \(AB\) 连续段这种东西。 我们 \(2,3\) 的连续段能组成多少种长度的呢? \(2,3\) 可以,之后我们全部都用 \(2\),这样我们就可以消掉除了长度 \(>1\) 的所有连续段了。…

2025-11-28 如何更换power shell背景颜色(deepseek)

好的,更换 PowerShell 的背景颜色非常简单,主要有两种方法:一种是临时性的(仅对当前窗口有效),另一种是永久性的(通过修改配置文件)。 方法一:临时更改(通过属性设置) 这种方法最简单直观,但关闭窗口后再次…

Hikvision 考勤机数据提取(2)

import xml.etree.ElementTree as ET import requests from requests.auth import HTTPDigestAuth import json import sys import hashlib import base64 import timedef get_random():timestamp = str(int(time.ti…

P8868

询问所有区间的最大值乘积之和,这个也是好人,自然溢出取模。 考虑一次询问怎么做。我觉得从区间的角度来考虑这个东西还是蛮困难的,枚举两边的人,考虑他们两能成为几次乘积。用单调栈搞出管辖区间。首先双方的管辖…

XYD11.27模拟赛

欸,最后一场模拟赛了是吧,无话可说啊 T1: \(sum[r]^sum[r1]=sum[l-1]^sum[l1-1]\) 看到异或,想到拆位吧 考虑我们怎么快速知道上面的异或和,拆位之后我们就知道了每个二进制在中间出现了多少次? 这样是不是可以分…

P10704

对于下取整,我们有多种处理的手法。 \(\sum_{i=1}^{n}\sum_{j=1}^{n} \lfloor\frac{\lfloor{\frac{n}{a_i}\rfloor}}{a_j}\rfloor\) 开一个桶,然后本质不同的 \(a\) 只会有 \(\sqrt{1e9}\) 个。 \(\sum_{i=1}^{n}\su…

P8617

看起来很板,正好拿来练练 \(\text{SAM}\) 遍历所有节点,处理一下 \(\text{endpos}\) 集合的大小,如果 \(\ge 2\),那么就可以和答案取 \(\text{max}\) 我的 \(\text{SAM}\) 写挂了hhh,经验不足,经验不足,之后不要…

P2754

咕咕了 很快复习完字符串了,看看这个。 流量肯定是人吧,而且我觉得这个东西也很难用费用流这种东西?我靠! 二分答案是容易想到的,对于每个答案判断是否可行 直接对时间建分层图,每一层就都是 \(n\) 个点。然后建…

P2474

建个图? 使用并查集,然后搞一个DAG。 然后现在我们有了 \(A,B\) 两个点。那么小于的情况,\(A,B\)。 有一个比较暴力的做法,我们把 \(A,B\) 的所有可能取值搞出来,然后把这些取值钦定了,之后搞出其它点对钦定完和…

RAG的17种方式搭建方式研究

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …