我正在尝试在 Spring-Boot 中使用 SecurityFilterChain 来实现 swagger-ui。 我尝试了各种方法来使其正常工作,但每次我都会收到以下错误。
未经授权的错误:需要完全身份验证才能访问此资源
我使用的是springfox 3.0
添加下面的 swagger 配置和安全配置代码。
SecurityConfig.java
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
//new BCryptPasswordEncoder();
}
@Bean
@Order(2)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests((authorize) -> authorize
.antMatchers("/swagger-ui/**").permitAll()
.antMatchers("/swagger-resources/**").permitAll()
.antMatchers("/swagger-ui.html").permitAll()
.anyRequest()
.authenticated());
http.cors().configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Collections.singletonList("*"));
config.setAllowedMethods(Collections.singletonList("*"));
config.addAllowedOrigin("*");
config.setAllowCredentials(true);
return config;
}
});
http.authenticationProvider(authenticationProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
SwaggerConfig.java
public class SwaggerConfig {
public static final String AUTHORIZATION_HEADER = "Authorization";
private ApiKey apiKey() {
return new ApiKey("JWT", AUTHORIZATION_HEADER, "header");
}
private ApiInfo apiInfo() {
return new ApiInfo("Spring Boot ", "Spring Boot Doc", "716",
"Terms of service", new Contact("Test", "www.xyz.com", "[email protected]"),
"License of API", "API license URL", Collections.emptyList());
}
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.securityContexts(Arrays.asList(securityContext())).securitySchemes(Arrays.asList(apiKey())).select()
.apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build();
}
private SecurityContext securityContext() {
return SecurityContext.builder().securityReferences(defaultAuth()).build();
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return Arrays.asList(new SecurityReference("JWT", authorizationScopes));
}
}
这是我添加到 webSecurityConfiguration 中的代码
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/v2/api-docs/**", "/swagger-ui/**", "/swagger-resources/**", "/v2/api-docs/**");
}
尝试 web.ignoring()
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/swagger-ui/**", "/v3/api-docs/**", "/proxy/**");
}
我也有同样的问题。 当我添加以下内容时它已修复。
...antMatchers("/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/swagger-resources", "/v3/api-docs/**", "/proxy/**").permitAll()...
我的安全类中的SecurityFilterChain Bean
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/swagger-ui.html", "/swagger-ui/**", "/swagger-resources/**", "/swagger-resources", "/v3/api-docs/**", "/proxy/**").permitAll()
.anyRequest().authenticated()
.and().exceptionHandling()
.authenticationEntryPoint(authEntryPoint)
.and()
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(roleConverter);
return http.build();
}
Swagger-UI 的 springdoc 依赖项
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.14</version>
</dependency>
如果您在请求期间有不同的过滤方法(如 OncePerRequestFilter),您应该确保不会出现错误。
您需要指定无需身份验证即可访问的所有 swagger URL 路径。 要确定要添加哪些路径,请启用
org.springframework.security
上的 DEBUG
logging.level.org.springframework.security=DEBUG
尝试访问您的 swagger 端点(因版本而异)并检查 DEBUG 日志以查看 Spring Security 尝试保护的资源和路径:
o.s.s.w.FilterChainProxy : Securing GET /swagger-ui/index.html
s.s.w.c.SecurityContextPersistenceFilter : Set SecurityContextHolder to empty SecurityContext
o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
o.s.s.w.a.i.FilterSecurityInterceptor : Authorized filter invocation [GET /swagger-ui/index.html] with attributes [permitAll]
o.s.s.w.FilterChainProxy : Secured GET /swagger-ui/index.html
s.s.w.c.SecurityContextPersistenceFilter : Cleared SecurityContextHolder to complete request
o.s.s.w.FilterChainProxy : Securing GET /swagger-ui/springfox.css?v=3.0.0
将它们添加到您的配置中:
.antMatchers("/swagger-ui/**","/swagger-resources/**","/v3/api-docs/**").permitAll()
这似乎是最好的方法,这是解决该问题的唯一与版本无关的解决方案
在您的 SecurityConfig.java 中尝试一下这个
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/v2/api-docs",
"/configuration/**",
"/swagger-resources/**",
"/configuration/security",
"/swagger-ui.html",
"/swagger-ui/**",
"/webjars/**");
}