您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Swagger2如何集成OAuth2
## 前言
在现代Web应用开发中,API文档的自动生成和OAuth2授权机制已成为标准配置。Swagger2作为流行的API文档工具,能够与OAuth2协议无缝集成,为开发者提供既安全又便捷的API调试体验。本文将深入探讨如何在Spring Boot项目中实现Swagger2与OAuth2的集成,涵盖从基础配置到高级自定义的全过程。
## 一、环境准备
### 1.1 基础依赖
确保项目中已包含以下Maven依赖(Spring Boot 2.x版本):
```xml
<!-- Spring Security OAuth2 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
在application.yml
中配置OAuth2客户端信息:
security:
oauth2:
client:
client-id: api-client
client-secret: secret123
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
创建Swagger配置类并启用OAuth2支持:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Value("${security.oauth2.client.client-id}")
private String clientId;
@Value("${security.oauth2.client.client-secret}")
private String clientSecret;
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.controller"))
.paths(PathSelectors.any())
.build()
.securitySchemes(Arrays.asList(securityScheme()))
.securityContexts(Arrays.asList(securityContext()));
}
private SecurityScheme securityScheme() {
GrantType grantType = new ResourceOwnerPasswordCredentialsGrant(
"/oauth/token");
return new OAuthBuilder()
.name("oauth2")
.grantTypes(Arrays.asList(grantType))
.scopes(Arrays.asList(scopes()))
.build();
}
private AuthorizationScope[] scopes() {
return new AuthorizationScope[]{
new AuthorizationScope("read", "Read access"),
new AuthorizationScope("write", "Write access")
};
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.ant("/api/**"))
.build();
}
private List<SecurityReference> defaultAuth() {
return Arrays.asList(
new SecurityReference("oauth2", scopes()));
}
}
调整Spring Security配置以允许Swagger UI访问:
@Configuration
@EnableWebSecurity
@EnableOAuth2Client
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/v2/api-docs", "/swagger*/**").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
当系统需要支持多个授权服务器时:
private List<SecurityScheme> securitySchemes() {
List<SecurityScheme> schemes = new ArrayList<>();
// 主授权服务器
schemes.add(new OAuthBuilder()
.name("oauth2-main")
.grantTypes(Arrays.asList(
new ResourceOwnerPasswordCredentialsGrant("/main/oauth/token")))
.build());
// 第三方授权服务器
schemes.add(new OAuthBuilder()
.name("oauth2-thirdparty")
.grantTypes(Arrays.asList(
new AuthorizationCodeGrant(
new TokenRequestEndpoint("/thirdparty/oauth/authorize", "client-id", "client-secret"),
new TokenEndpoint("/thirdparty/oauth/token", "access_token"))))
.build());
return schemes;
}
覆盖默认的Swagger授权页面:
@Primary
@Bean
public SwaggerResourcesProvider swaggerResourcesProvider() {
return () -> {
SwaggerResource resource = new SwaggerResource();
resource.setName("API Docs");
resource.setSwaggerVersion("2.0");
resource.setLocation("/v2/api-docs");
// 自定义OAuth2配置
resource.setSwaggerVersion("2.0");
resource.getSwaggerExtensions().add(new OAuth2Extension(
Arrays.asList(
new AuthorizationScope("read", "Read access"),
new AuthorizationScope("write", "Write access")),
Arrays.asList(
new ImplicitGrant(
new LoginEndpoint("http://localhost:8080/oauth/authorize"),
"access_token"))));
return Arrays.asList(resource);
};
}
当出现CSRF相关错误时,需在SecurityConfig中排除Swagger路径:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.ignoringAntMatchers("/v2/api-docs", "/swagger*/**", "/oauth/token");
}
实现自动刷新Token的拦截器:
public class OAuth2TokenInterceptor implements RequestInterceptor {
private OAuth2RestTemplate restTemplate;
@Override
public void apply(RequestTemplate template) {
if (template.headers().containsKey("Authorization")) {
OAuth2AccessToken token = restTemplate.getAccessToken();
template.header("Authorization",
"Bearer " + token.getValue());
}
}
}
@Profile("!prod")
@Configuration
@EnableSwagger2
public class SwaggerConfig {
// 配置内容
}
http.authorizeRequests()
.antMatchers("/swagger-ui.html").hasIpAddress("192.168.1.0/24");
@Bean
public WebMvcConfigurer swaggerCacheConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html**")
.addResourceLocations("classpath:/META-INF/resources/")
.setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS));
}
};
}
@RestController
@RequestMapping("/api/users")
@Api(tags = "用户管理", authorizations = {
@Authorization(value = "oauth2", scopes = {
@AuthorizationScope(scope = "read", description = "读取权限"),
@AuthorizationScope(scope = "write", description = "写入权限")
})
})
public class UserController {
@GetMapping
@ApiOperation(value = "获取用户列表",
authorizations = @Authorization("oauth2"))
public List<User> listUsers() {
// 实现逻辑
}
}
GitHub示例仓库 包含: - 多环境配置 - 单元测试用例 - Docker部署脚本
通过本文的详细指导,开发者可以构建出既符合OAuth2安全标准又具备完善文档支持的API服务。建议在实际项目中: 1. 根据业务需求调整scope定义 2. 定期更新Swagger和OAuth2依赖版本 3. 结合API网关实现更复杂的授权策略
注意:本文基于Spring Boot 2.3.x和Swagger 2.9.x版本编写,不同版本可能存在配置差异。 “`
文章总字数:约3950字(含代码)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。