1.pom依赖
在所要使用Swagger的项目引用Swagger依赖
io.springfox springfox-swagger22.9.2 io.springfox springfox-swagger-ui2.9.2
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;
@Configuration
@EnableSwagger2
public class FebsWebConfigure {
@Autowired
private FebsServerSystemProperties properties;
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List sqlParserList = new ArrayList<>();
sqlParserList.add(new BlockAttackSqlParser());
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
@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 {
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;
@Configuration
@EnableSwagger2
public class FebsWebConfigure {
@Autowired
private FebsServerSystemProperties properties;
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List sqlParserList = new ArrayList<>();
sqlParserList.add(new BlockAttackSqlParser());
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
@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());
}
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();
}
private SecurityContext securityContext(FebsSwaggerProperties swagger) {
return SecurityContext.builder()
.securityReferences(Collections.singletonList(new SecurityReference(swagger.getName(), scopes(swagger))))
.forPaths(PathSelectors.any())
.build();
}
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服务:
会有一个认证的按钮,点击进行认证
认证成功之后,即可正常进行接口测试了。



