在学习 Spring Boot 框架中,引入了 Spring Security 来安全验证,数据库层面使用了 Mybatis + H2。
由于之前没怎么接触过 H2(使用的目的主要是为了测试方便,本地也不需要单独安装一个 MySQL 等外部数据库),本着学习的心态,开始搞了起来。
项目在加入 Spring Security 后,开启运行,就会受到访问限制(401)。需要我们单独设置一下 SecurityFilterChain 来过滤掉一些不需要鉴权的 URL。于是添加下面的配置。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private static final String[] WHITE_LIST_URLS = {
"/api-docs/**",
"/swagger-ui.html",
"/swagger-ui/**",
"/v3/**",
"/actuator/**",
"/api/auth/**",
"/h2-console/**"
};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers(WHITE_LIST_URLS).permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
);
return http.build();
}
}
兴高采烈的运行起项目,结果死活访问不了 h2-console,在 application.yaml 中也开户了访问,也使不好使,网上的 demo 基本都试了一遍,最后无奈搜索一下 "h2-console spring boot 3.0.2",第一条为 Stackoverflow 的问题,看了一下,这不就是我苦苦追寻的嘛。
主要的原因是,如果心字符串数组形式传入 requestMatchers 将被 MvcRequestMatcher 处理,但 h2-console 不是 DispatcherServlet 的一部分。
综合解决方案如下:
在 application.yaml 文件中启用 h2-console,配置如下:
spring:
application:
name: jwt-mybatis-demo
datasource:
url: jdbc:h2:mem:jm
driver-class-name: org.h2.Driver
sql:
init:
data-locations: classpath:db/data.sql
schema-locations: classpath:db/schema.sql
mode: always
h2:
console:
enabled: true
修改 SecurityConfig 文件如下,添加 WebSecurityCustomizer,单独处理一下 h2-console 的安全。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint;
import org.springframework.security.oauth2.server.resource.web.access.BearerTokenAccessDeniedHandler;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
private static final String[] WHITE_LIST_URLS = {
"/api-docs/**",
"/swagger-ui.html",
"/swagger-ui/**",
"/v3/**",
"/actuator/**",
"/api/auth/**"
};
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.requestMatchers(WHITE_LIST_URLS).permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
.exceptionHandling(exceptions -> exceptions
.authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint())
.accessDeniedHandler(new BearerTokenAccessDeniedHandler())
);
return http.build();
}
@Bean
WebSecurityCustomizer webSecurityCustomizer() {
// 单独处理一下 h2-console 如果放在 WHITE_LIST_URLS 中将不起作用 原因是上面的过滤走的是 MvcRequestMatcher 匹配器
// 而 h2-console 不属于 DispatcherServlet 的一部分
// reference: https://stackoverflow.com/questions/75367159/how-can-i-access-the-h2-console-while-using-spring-security-spring-boot-3-0-2/75367690
return web -> web.ignoring()
.requestMatchers(new AntPathRequestMatcher("/h2-console/**"));
}
}
本文由 waynelone 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Feb 13, 2023 at 09:59 am