赞
踩
最近在项目中使用Knife4j+Sa-Token,之前是将token放在cookies中,现在要放入请求头中,借助
Knife4j作者的文档实现此功能,参考链接OpenAPI3规范中添加Authorization鉴权请求Header不生效?
使用版本
spring boot版本:
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>3.2.5</version>
- <relativePath/>
- </parent>
Knife4j版本
- <dependency>
- <groupId>com.github.xiaoymin</groupId>
- <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
- <version>4.1.0</version>
- </dependency>
添加自定义请求头,并添加前缀,鉴权使用Sa-Token
- package com.yhx.common.config;
-
- import cn.dev33.satoken.interceptor.SaInterceptor;
- import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
- import cn.dev33.satoken.stp.StpLogic;
- import cn.dev33.satoken.stp.StpUtil;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
- import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
- /**
- * @author: yhx
- * @description 注解式鉴权
- * @date: 2024-06-20 16:54
- */
- @Configuration
- public class SaTokenConfigure implements WebMvcConfigurer {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- String[] excludePatterns = new String[]{"/api/v1/sys/login",
- "/doc.html/**",
- "/swagger-ui/**",
- "/swagger-ui.html",
- "/v3/api-docs/**",
- "/swagger-resources/**",
- "/webjars/**",
- "/swagger-ui.html/**",
- "/api",
- "/api-docs",
- "/api-docs/**"};
- // 注册 Sa-Token 拦截器,打开注解式鉴权功能
- registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
- .addPathPatterns("/**")
- .excludePathPatterns(excludePatterns);
- }
-
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- //配置拦截器访问静态资源
- registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
- registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/META-INF/resources/");
- registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
- }
- @Bean
- public StpLogic getStpLogicJwt() {
- return new StpLogicJwtForSimple();
- }
- }
主要是为了解决Knife4j被拦截器拦截问题
- package com.yhx.common.config;
-
- import com.google.common.net.HttpHeaders;
- import io.swagger.v3.oas.models.Components;
- import io.swagger.v3.oas.models.OpenAPI;
- import io.swagger.v3.oas.models.info.Info;
- import io.swagger.v3.oas.models.security.SecurityRequirement;
- import io.swagger.v3.oas.models.security.SecurityScheme;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * @author: yhx
- * @description
- * @date: 2024-06-21 18:41
- */
- @Configuration
- public class knife4jConfig {
- @Bean
- public OpenAPI customOpenAPI() {
- return new OpenAPI().info(new Info()
- .title("自定义项目名")
- .description("这是一个描述")
- .version("这是版本号"))
- .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION))
- .components(new Components().addSecuritySchemes(
- HttpHeaders.AUTHORIZATION,
- new SecurityScheme()
- .name(HttpHeaders.AUTHORIZATION)
- .type(SecurityScheme.Type.HTTP)
- .scheme("Bearer")
- .in(SecurityScheme.In.HEADER)
- .bearerFormat("JWT")
- )
- );
- }
- }
需要在接口层面定义使用,如下:
@Operation(security = { @SecurityRequirement(name = HttpHeaders.AUTHORIZATION) })
或者
- @SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
- @Operation(summary = "描述1")
- @PostMapping("/description")
- public ResponseEntity<ConfigPageParam> description(@ParameterObject ConfigPageParam configPageParam){
- return ResponseEntity.ok(configPageParam);
- }
但是这样过于麻烦,每个接口都需要添加,所以我们可以借助Knife4j作者提供的两个接口来实现不需要手动给每个接口添加
GlobalOperationCustomizer
:针对Operation级别的全局自定义扩展钩子函数,开发者可以对接口中每一个Operation进行扩展自定义实现,或调整,或修改,或增加扩展都行,Knife4j的部分增强特性就是基于此函数实现。GlobalOpenApiCustomizer
:是针对整个OpenAPI级别的,开发者在分组或者分包后,得到的单个OpenAPI实例,开发者可以操纵全局的OpenAPI实例,该OpenAPI对象已经是springdoc解析过的实例对象,例如该issues中的需求,开发者只需要自定义创建新Operation对象,然后通过OpenAPI实例对象进行add添加即可完成此需求。- package com.yhx.common.config;
-
- import com.github.xiaoymin.knife4j.annotations.ApiSupport;
- import com.google.common.net.HttpHeaders;
- import io.swagger.v3.oas.models.Operation;
- import io.swagger.v3.oas.models.security.SecurityRequirement;
- import lombok.extern.slf4j.Slf4j;
- import org.springdoc.core.customizers.GlobalOperationCustomizer;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.stereotype.Component;
- import org.springframework.web.method.HandlerMethod;
-
- import java.util.List;
-
- /**
- * @author: yhx
- * @description 为每个接口添加鉴权
- * @date: 2024-06-24 13:51
- */
- @Slf4j
- @Component
- public class Knife4jOperationCustomizer implements GlobalOperationCustomizer {
- @Override
- public Operation customize(Operation operation, HandlerMethod handlerMethod) {
- List<SecurityRequirement> security = operation.getSecurity();
- if (security == null) {
- security = List.of(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
- operation.setSecurity(security);
- }
- return operation;
- }
- }
效果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。