WebMvcConfig 和 WebSecurityConfig 详解
一、概述
Spring Boot项目中有两个重要的配置类,它们分别负责不同的功能:
- WebMvcConfig - 负责Spring MVC的配置(拦截器、静态资源等)
- WebSecurityConfig - 负责Spring Security的安全配置(认证、授权、过滤器等)
二、WebMvcConfig 详解
2.1 基本概念
WebMvcConfig 是Spring MVC框架的配置类,通过实现 WebMvcConfigurer 接口来自定义MVC的行为。
2.2 作用范围
java
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 配置Spring MVC的各个方面
}
主要功能:
- ✅ 注册拦截器(Interceptor) - 自定义请求拦截逻辑
- ✅ 配置静态资源映射 - 静态文件访问路径
- ✅ 添加类型转换器 - 数据格式转换
- ✅ 配置视图解析器 - 视图渲染
- ✅ 添加格式化器 - 日期、数字格式化
- ✅ 跨域配置(CORS) - 跨域资源共享
2.3 项目中的实际应用
22:27:zkme-kyb-admin/src/main/java/com/zkme/kyb/admin/config/WebMvcConfig.java
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册API Key拦截器,只拦截 /openapi/** 路径
registry.addInterceptor(apiKeyInterceptor)
.addPathPatterns("/openapi/**")
.order(1); // 设置优先级
}
当前项目中的作用:
- 📌 注册了
ApiKeyInterceptor拦截器 - 📌 只拦截
/openapi/**路径的请求 - 📌 用于OpenAPI接口的API Key认证
2.4 WebMvcConfigurer 常用方法
java
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:注册拦截器
java
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/public/**");
}
场景2:静态资源映射
java
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
场景3:跨域配置
java
@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 作用范围
java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// 配置Spring Security的安全策略
}
主要功能:
- ✅ 认证配置(Authentication) - 用户身份验证
- ✅ 授权配置(Authorization) - 访问权限控制
- ✅ 过滤器配置 - 安全过滤器链
- ✅ 会话管理 - Session策略
- ✅ CSRF防护 - 跨站请求伪造防护
- ✅ 密码加密 - 密码加密器配置
3.3 项目中的实际配置
3.3.1 密码加密器配置
45:51:zkme-kyb-admin/src/main/java/com/zkme/kyb/admin/security/WebSecurityConfig.java
/**
* BCrypt密码加密器
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
作用:提供密码加密和解密的功能,用于:
- 用户注册时加密密码
- 用户登录时验证密码
- API Key Secret的加密存储
3.3.2 认证管理器配置
53:58:zkme-kyb-admin/src/main/java/com/zkme/kyb/admin/security/WebSecurityConfig.java
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
// 配置UserDetailsService和密码加密器
authenticationManagerBuilder.userDetailsService(this.userDetailsService)
.passwordEncoder(passwordEncoder());
}
作用:
- 配置自定义的
UserDetailsService(用于加载用户信息) - 配置密码加密器(用于验证密码)
3.3.3 HTTP安全配置(核心)
61:98:zkme-kyb-admin/src/main/java/com/zkme/kyb/admin/security/WebSecurityConfig.java
@Override
protected 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();
}
详细解析:
-
CSRF防护
java.csrf().disable()- 禁用CSRF防护,因为使用JWT Token进行认证,不需要CSRF Token
-
CORS配置
java.cors().and()- 启用跨域资源共享支持
-
异常处理
java.exceptionHandling() .authenticationEntryPoint(unauthorizedHandler)- 配置认证失败时的处理入口点(返回401未授权)
-
Session策略
java.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS)- 设置为无状态,不使用Session(适合JWT Token认证)
-
请求授权规则
java.authorizeRequests() .antMatchers("/api/auth/validate", ...).permitAll() // 允许匿名访问 .antMatchers("/openapi/**").permitAll() // 允许匿名访问 .anyRequest().authenticated() // 其他需要认证- 定义哪些路径允许匿名访问,哪些需要认证
-
JWT过滤器
javahttpSecurity.addFilterBefore( new ZkMeAuthenticationTokenFilter(this.jwtSecret), UsernamePasswordAuthenticationFilter.class );- 在Spring Security的过滤器链中添加自定义的JWT认证过滤器
- 优先级在
UsernamePasswordAuthenticationFilter之前
3.3.4 Web安全配置(静态资源)
100:111:zkme-kyb-admin/src/main/java/com/zkme/kyb/admin/security/WebSecurityConfig.java
@Override
public void configure(WebSecurity web) throws Exception {
// 忽略静态资源
web.ignoring().antMatchers(
"/css/**",
"/js/**",
"/images/**",
"/fonts/**",
"/**/*.html",
"/favicon.ico"
);
}
作用:让Spring Security完全忽略这些静态资源路径,不进行安全校验,提高性能。
四、两者的区别和联系
4.1 核心区别
| 特性 | WebMvcConfig | WebSecurityConfig |
|---|---|---|
| 框架 | Spring MVC | Spring Security |
| 职责 | MVC功能配置 | 安全策略配置 |
| 拦截方式 | 拦截器(Interceptor) | 过滤器(Filter) |
| 执行时机 | DispatcherServlet之后 | DispatcherServlet之前 |
| 典型用途 | 日志、参数转换、跨域 | 认证、授权、加密 |
4.2 执行顺序
客户端请求
↓
[WebSecurityConfig - 过滤器链]
├─ JWT Token过滤器
├─ CSRF过滤器
└─ 其他安全过滤器
↓
DispatcherServlet
↓
[WebMvcConfig - 拦截器链]
├─ API Key拦截器(针对/openapi/**)
└─ 其他拦截器
↓
Controller处理
↓
返回响应
4.3 配置优先级
Spring Security过滤器 → Spring MVC拦截器
-
Security过滤器 先执行(在Servlet层面)
- 进行认证授权检查
- 如果认证失败,直接返回401,不会进入MVC流程
-
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示例
java
@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示例
java
@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 职责分离
- ✅ WebMvcConfig:负责业务层面的拦截和转换
- ✅ WebSecurityConfig:负责安全层面的认证和授权
6.2 性能优化
java
// WebSecurityConfig中忽略静态资源,避免不必要的安全校验
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/static/**");
}
6.3 双重认证机制
java
// 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
- 🎯 作用:配置Spring Security的安全策略(认证、授权、过滤器)
- 🔧 适用场景:用户认证、权限控制、密码加密、JWT验证
- ⚡ 执行时机:DispatcherServlet之前(Servlet Filter层面)
两者配合
- ✅ Security配置:决定哪些请求需要认证(粗粒度控制)
- ✅ MVC配置:在通过Security后,进行业务层面的拦截(细粒度控制)
- ✅ 完美配合:实现灵活的双重认证机制(JWT + API Key)
通过这两个配置类的配合,可以实现既安全又灵活的Web应用架构!