在开发 Rest API 时,经常会使用 swagger 进行 API 测试,但是 API 通常情况下都是受保护的,需要携带 token 才能访问,本篇文章将介绍在 Spring Boot 中,swagger 怎样与 OAuth2 服务集成。
本文所使用的环境:
首先是 swagger 的配置:
package me.javaroad.mcloud.apigw.config;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.OAuthBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.AuthorizationCodeGrant;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.GrantType;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.service.TokenEndpoint;
import springfox.documentation.service.TokenRequestEndpoint;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.ApiKeyVehicle;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
private static final String VERSION = "1.0";
@Value("${swagger.title:API Gateway}")
private String title;
@Value("${swagger.description:}")
private String description;
private final KeycloakProperties keycloakProperties;
public SwaggerConfig(KeycloakProperties keycloakProperties) {
this.keycloakProperties = keycloakProperties;
}
@Bean
public Docket apiDocket() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("me.javaroad.mcloud.apigw"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo())
.securitySchemes(Collections.singletonList(oauth()))
;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(title)
.description(description)
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.termsOfServiceUrl("")
.version(VERSION)
.build();
}
@Bean
List grantTypes() {
List grantTypes = new ArrayList<>();
TokenRequestEndpoint tokenRequestEndpoint = new TokenRequestEndpoint(
keycloakProperties.getClient().getUserAuthorizationUri(),
keycloakProperties.getClient().getClientId(), keycloakProperties.getClient().getClientSecret());
TokenEndpoint tokenEndpoint = new TokenEndpoint(keycloakProperties.getClient().getAccessTokenUri(), "access_token");
grantTypes.add(new AuthorizationCodeGrant(tokenRequestEndpoint, tokenEndpoint));
return grantTypes;
}
@Bean
SecurityScheme oauth() {
return new OAuthBuilder()
.name("OAuth2")
.scopes(scopes())
.grantTypes(grantTypes())
.build();
}
private List scopes() {
return Lists.newArrayList(new AuthorizationScope("openid", "Grants openid access"));
}
@Bean
public SecurityConfiguration securityInfo() {
return new SecurityConfiguration(keycloakProperties.getClient().getClientId(),
keycloakProperties.getClient().getClientSecret(),
"realm", keycloakProperties.getClient().getClientId(),
"apiKey", ApiKeyVehicle.HEADER, "api_key", "");
}
}
application.yml
oauth2:
keycloak:
client:
client-id: mcloud-demo
client-secret: 123456
user-authorization-uri: http://localhost:8443/auth/realms/mcloud/protocol/openid-connect/auth
access-token-uri: http://localhost:8443/auth/realms/mcloud/protocol/openid-connect/token
最后,我们需要在 keycloak 的 客户端设置中配置 swagger 的回调地址:
http://localhost/webjars/springfox-swagger-ui/o2c.html
此处需要注意配置允许跨域(第二个红框)
所有的配置到此结束,如果一切正常,访问 swagger ,将看到以下页面:
点击 Authorize
按钮后,我们就会跳转到 keycloak 进行登陆授权:
成功登陆并授权后,页面又会跳会 swagger,此时我们访问受保护的 API 时,swagger 会自动带上 access_token
作为参数:
本篇教程就到此结束,如需查看源码,请参考:
GitHub