Spring Boot 3集成Swagger 3.0配置JWT Token及授权按钮问题
一、Swagger 3 配置「Authorize」按钮
Spring Boot 3 集成 Swagger 3 需要使用 springdoc-openapi-starter-webmvc-ui 依赖(原 SpringFox 已停止维护),先在项目中引入依赖:
Maven 依赖
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.2.0</version> </dependency>
Gradle 依赖
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
接下来创建 Swagger 配置类,通过 OpenAPI 和 SecurityScheme 定义 JWT 授权规则,Swagger UI 会自动显示「Authorize」按钮:
import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; 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; @Configuration public class OpenApiConfig { @Bean public OpenAPI customOpenAPI() { final String securitySchemeName = "bearerAuth"; return new OpenAPI() // 全局启用该授权规则 .addSecurityItem(new SecurityRequirement().addList(securitySchemeName)) .components( new Components() .addSecuritySchemes(securitySchemeName, new SecurityScheme() .name(securitySchemeName) .type(SecurityScheme.Type.HTTP) .scheme("bearer") .bearerFormat("JWT") // 指定Token格式为JWT .in(SecurityScheme.In.HEADER) // Token放在请求头中 ) ); } }
配置完成后启动项目,访问默认地址 http://localhost:8080/swagger-ui.html,顶部就会出现「Authorize」按钮。点击按钮输入JWT Token(直接输入即可,Swagger会自动添加Bearer 前缀),保存后调用需要授权的接口时,请求头会自动携带Token。
二、确保API正确接收JWT Token
方式1:使用Spring Security处理JWT认证
如果项目用Spring Security做权限控制,需要配置放行Swagger路径并添加JWT认证过滤器:
Security配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthenticationFilter; public SecurityConfig(JwtAuthenticationFilter jwtAuthenticationFilter) { this.jwtAuthenticationFilter = jwtAuthenticationFilter; } @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> auth // 放行Swagger所有相关路径 .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll() // 放行公开接口(根据实际路径调整) .requestMatchers("/api/public/**").permitAll() // 其他所有接口需要认证 .anyRequest().authenticated() ) // 添加JWT认证过滤器,在用户名密码认证之前执行 .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }
JWT认证过滤器示例
import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import java.io.IOException; @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenUtil jwtTokenUtil; private final UserDetailsService userDetailsService; public JwtAuthenticationFilter(JwtTokenUtil jwtTokenUtil, UserDetailsService userDetailsService) { this.jwtTokenUtil = jwtTokenUtil; this.userDetailsService = userDetailsService; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { final String authHeader = request.getHeader("Authorization"); String username = null; String jwtToken = null; // 从请求头提取Token(去掉"Bearer "前缀) if (authHeader != null && authHeader.startsWith("Bearer ")) { jwtToken = authHeader.substring(7); username = jwtTokenUtil.extractUsername(jwtToken); } // 验证Token有效性并设置安全上下文 if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); if (jwtTokenUtil.validateToken(jwtToken, userDetails)) { UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities()); authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authToken); } } filterChain.doFilter(request, response); } }
JwtTokenUtil 是自定义工具类,负责Token的生成、解析和验证逻辑。
方式2:手动在接口中接收Token
如果不用Spring Security,可直接在接口中通过@RequestHeader注解获取Token:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; @RestController public class ProtectedController { @GetMapping("/api/protected") public String protectedEndpoint(@RequestHeader("Authorization") String authHeader) { // 提取Token(去掉"Bearer "前缀) String token = authHeader.substring(7); // 这里添加Token验证逻辑 return "访问受保护接口成功"; } }
内容的提问来源于stack exchange,提问作者Arjun Trivedi
相关产品推荐
相关产品推荐

