1.pom依赖
在所要使用Swagger的项目引用Swagger依赖
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
</dependencies>
2.Swagger配置类
该配置类上使用@EnableSwagger2
标注,表示开启Swagger功能
package cc.mrbird.febs.server.system.configure;
import cc.mrbird.febs.server.system.properties.FebsServerSystemProperties;
import cc.mrbird.febs.server.system.properties.FebsSwaggerProperties;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.GrantType;
import springfox.documentation.service.ResourceOwnerPasswordCredentialsGrant;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @description:
* @Author ztt
* @create: 2021-10-24 15:09
*/
@Configuration
@EnableSwagger2
public class FebsWebConfigure {
@Autowired
private FebsServerSystemProperties properties;
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List<ISqlParser> sqlParserList = new ArrayList<>();
sqlParserList.add(new BlockAttackSqlParser());
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
/**
* 主要是这个方法,其他的方法是抽出去的
* 在 basePackage 里面写需要生成文档的 controller 路径
*/
@Bean
public Docket swaggerApi() {
FebsSwaggerProperties swagger = properties.getSwagger();
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage(swagger.getBasePackage()))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo(swagger))
}
/**
* 这个方法主要是写一些文档的描述
*/
private ApiInfo apiInfo(FebsSwaggerProperties swagger) {
return new ApiInfo(
swagger.getTitle(),
swagger.getDescription(),
swagger.getVersion(),
null,
new Contact(swagger.getAuthor(), swagger.getUrl(), swagger.getEmail()),
swagger.getLicense(), swagger.getLicenseUrl(), Collections.emptyList());
}
}
swaggerApi
方法的apis(RequestHandlerSelectors.basePackage(
swagger.getBasePackage()
))
表示将cc.mrbird.febs.server.system.controller
路径下的所有Controller都添加进去,paths(PathSelectors.any())
表示Controller里的所有方法都纳入。
apiInfo
用于定义一些API页面信息,比如作者名称,邮箱,网站链接,开源协议等等。
这里固定配置较多(阿里编程规范称为“魔法值”),我们可以将它抽取为一个配置文件。在febs-system模块的cc.mrbird.febs.server.system路径下新建properties包,然后在该包下新建FebsSwaggerProperties
配置文件类:
@Data
public class FebsSwaggerProperties{
private String basePackage;
private String title;
private String description;
private String version;
private String author;
private String url;
private String email;
private String license;
private String licenseUrl;
private String grantUrl;
private String name;
private String scope;
}
@Data
@SpringBootConfiguration
@PropertySource(value = {"classpath:febs-server-system.properties"})
@ConfigurationProperties(prefix = "febs.server.system")
public class FebsServerSystemProperties {
/**
* 免认证 URI,多个值的话以逗号分隔
*/
private String anonUrl;
private FebsSwaggerProperties swagger = new FebsSwaggerProperties();
}
然后在febs-server-system.properties
配置文件的免认证路径里添加swagger相关资源配置:
重启febs-server-system模块,访问 http://localhost:8301/system/swagger-ui.html
3.认证oauth2
虽然已经成功接入了Swagger,但是因为我们的资源都是受资源服务器保护的,所以Swagger并不能进行正常的接口测试。所以要进行oauth2的认证
在febs-auth模块里配置一个新的Client,专门用于Swagger令牌发放。在febs-auth模块的febs-auth.properties
配置文件里添加如下配置:
febs.auth.clients[1].client=swagger
febs.auth.clients[1].secret=123456
febs.auth.clients[1].grantType=password
febs.auth.clients[1].scope=test
修改Swagger的配置类
package cc.mrbird.febs.server.system.configure;
import cc.mrbird.febs.server.system.properties.FebsServerSystemProperties;
import cc.mrbird.febs.server.system.properties.FebsSwaggerProperties;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.GrantType;
import springfox.documentation.service.ResourceOwnerPasswordCredentialsGrant;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* @description:
* @Author ztt
* @create: 2021-10-24 15:09
*/
@Configuration
@EnableSwagger2
public class FebsWebConfigure {
@Autowired
private FebsServerSystemProperties properties;
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List<ISqlParser> sqlParserList = new ArrayList<>();
sqlParserList.add(new BlockAttackSqlParser());
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
/**
* 主要是这个方法,其他的方法是抽出去的
* 在 basePackage 里面写需要生成文档的 controller 路径
*/
@Bean
public Docket swaggerApi() {
FebsSwaggerProperties swagger = properties.getSwagger();
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage(swagger.getBasePackage()))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo(swagger))
.securitySchemes(Collections.singletonList(securityScheme(swagger)))
.securityContexts(Collections.singletonList(securityContext(swagger)));
}
/**
* 这个方法主要是写一些文档的描述
*/
private ApiInfo apiInfo(FebsSwaggerProperties swagger) {
return new ApiInfo(
swagger.getTitle(),
swagger.getDescription(),
swagger.getVersion(),
null,
new Contact(swagger.getAuthor(), swagger.getUrl(), swagger.getEmail()),
swagger.getLicense(), swagger.getLicenseUrl(), Collections.emptyList());
}
/**
* 用于配置安全策略,比如配置认证模型,scope等内容
*/
private SecurityScheme securityScheme(FebsSwaggerProperties swagger) {
GrantType grantType = new ResourceOwnerPasswordCredentialsGrant(swagger.getGrantUrl());
return new OAuthBuilder()
.name(swagger.getName())
.grantTypes(Collections.singletonList(grantType))
.scopes(Arrays.asList(scopes(swagger)))
.build();
}
/**
* 这里设置 swagger2 认证的安全上下文
*/
private SecurityContext securityContext(FebsSwaggerProperties swagger) {
return SecurityContext.builder()
.securityReferences(Collections.singletonList(new SecurityReference(swagger.getName(), scopes(swagger))))
.forPaths(PathSelectors.any())
.build();
}
/**
* 这里是写允许认证的scope
*/
private AuthorizationScope[] scopes(FebsSwaggerProperties swagger) {
return new AuthorizationScope[]{
new AuthorizationScope(swagger.getScope(), "")
};
}
}
通过Docket
的securitySchemes
和securityContexts
方法设置了安全策略和安全上下文。
在securityScheme
方法中,我们通过OAuthBuilder
对象构建了安全策略,主要配置了认证类型为ResourceOwnerPasswordCredentialsGrant
(即密码模式),认证地址为http://localhost:8301/auth/oauth/token
(即通过网关转发到认证服务器),scope为test,和febs-auth模块里定义的一致。这个安全策略我们将其命名为febs_oauth_swagger
。
在securityContext
方法中,我们通过febs_oauth_swagger
名称关联了上面定义的安全策略,并且通过forPaths(PathSelectors.any())
设置所有API接口都用这个安全上下文。
重启服务,重新访问Swagger服务:
会有一个认证的按钮,点击进行认证
认证成功之后,即可正常进行接口测试了。