springboot2.7.8 整合swagger 2.9.2,需要整合token
时间: 2023-10-08 11:11:32 浏览: 158
为了在Swagger中添加token,可以使用Spring Security来保护API并生成token。以下是如何在Spring Boot应用程序中使用Swagger和Spring Security整合token的步骤:
1. 添加Spring Security和JWT依赖
在pom.xml文件中添加以下依赖:
```
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
```
2. 创建Spring Security配置类
创建一个类,继承WebSecurityConfigurerAdapter并重写configure(HttpSecurity http)方法。在该方法中,配置Spring Security以保护API并生成token。以下是一个示例:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
```
3. 创建JWT工具类
创建一个类,用于生成和解析JWT token。以下是一个示例:
```
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private int expiration;
public String generateToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + expiration);
return Jwts.builder()
.setSubject(userPrincipal.getUsername())
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public String getUsernameFromToken(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(secret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
log.error("Invalid JWT signature");
} catch (MalformedJwtException ex) {
log.error("Invalid JWT token");
} catch (ExpiredJwtException ex) {
log.error("Expired JWT token");
} catch (UnsupportedJwtException ex) {
log.error("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
log.error("JWT claims string is empty");
}
return false;
}
}
```
4. 创建JWT认证过滤器
创建一个类,用于验证token并将用户信息添加到Spring Security上下文中。以下是一个示例:
```
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);
if (StringUtils.hasText(jwt) && jwtUtils.validateToken(jwt)) {
String username = jwtUtils.getUsernameFromToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
log.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
}
```
5. 在Swagger中添加token
在Spring Boot应用程序中添加Swagger,并在Swagger配置类中添加以下代码:
```
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Autowired
private JwtUtils jwtUtils;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.securityContexts(Arrays.asList(securityContext()))
.securitySchemes(Arrays.asList(apiKey()))
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
private ApiKey apiKey() {
return new ApiKey("JWT", "Authorization", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(Arrays.asList(new SecurityReference("JWT", new AuthorizationScope[]{})))
.forPaths(PathSelectors.any())
.build();
}
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId(null)
.clientSecret(null)
.realm(null)
.appName(null)
.scopeSeparator(",")
.additionalQueryStringParams(null)
.useBasicAuthenticationWithAccessCodeGrant(false)
.build();
}
@Bean
public UiConfiguration uiConfig() {
return UiConfigurationBuilder.builder()
.displayRequestDuration(true)
.validatorUrl("")
.build();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Bean
public SecurityConfiguration securityConfiguration() {
return SecurityConfigurationBuilder.builder()
.clientId("test-app-client-id")
.clientSecret("test-app-client-secret")
.realm("test-app-realm")
.appName("test-app")
.scopeSeparator(",")
.additionalQueryStringParams(null)
.useBasicAuthenticationWithAccessCodeGrant(false)
.build();
}
@Bean
public SecurityConfiguration securityConfiguration() {
return SecurityConfigurationBuilder.builder()
.clientId("test-app-client-id")
.clientSecret("test-app-client-secret")
.realm("test-app-realm")
.appName("test-app")
.scopeSeparator(",")
.additionalQueryStringParams(null)
.useBasicAuthenticationWithAccessCodeGrant(false)
.build();
}
@Bean
public OAuth securitySchema() {
List<AuthorizationScope> authorizationScopeList = new ArrayList<>();
authorizationScopeList.add(new AuthorizationScope("read", "read all"));
authorizationScopeList.add(new AuthorizationScope("write", "access all"));
List<GrantType> grantTypes = new ArrayList<>();
GrantType passwordCredentialsGrant = new ResourceOwnerPasswordCredentialsGrant("http://localhost:8080/auth/token");
grantTypes.add(passwordCredentialsGrant);
return new OAuth("oauth2schema", authorizationScopeList, grantTypes);
}
@Bean
public SecurityConfiguration securityInfo() {
return new SecurityConfiguration(
"test-app-client-id",
"test-app-client-secret",
"test-app-realm",
"test-app",
"",
ApiKeyVehicle.HEADER,
"Authorization",
","
);
}
@Bean
public SecurityConfiguration security() {
return SecurityConfigurationBuilder.builder()
.clientId("test-app-client-id")
.clientSecret("test-app-client-secret")
.realm("test-app-realm")
.appName("test-app")
.scopeSeparator(",")
.additionalQueryStringParams(null)
.useBasicAuthenticationWithAccessCodeGrant(false)
.build();
}
@Bean
public UiConfiguration uiConfiguration() {
return new UiConfiguration(
null,
"none",
"alpha",
"schema",
UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS,
false,
true,
60000L
);
}
}
```
完成以上步骤后,您就可以在Swagger中使用token来访问受保护的API了。在Swagger界面的右上方,单击“Authorize”按钮并输入您的token即可。
阅读全文