Mat*_*ias 14 java rest swagger swagger-2.0 swagger-codegen
我正在玩我的jersey2休息服务.为了更好地概述给定的服务(描述,类型等),我大量使用了swagger(swagger-jersey2-jaxrs).所以我能够创建我的服务描述(swagger.json),我可以通过swagger ui来查看和探索它们.
现在,我需要创建一些客户端来使用这些服务.我来了accrooss swagger codegen cli这是一个很好的工具来生成你的客户端和许多不同的语言(在我的情况下为java).我能够生成api客户端和正在使用的模型.
在这里,我遇到了第一个问题.REST服务和swagger描述是http基本身份验证保护.我阅读了文档 ,它给了我一些暗示,有可能使用基本的auth.在这一点上,我不得不提到,从我的观点来看,doucmentation非常差.它说:
-a, - auth在远程获取swagger定义时添加授权标头.传入URL编码的name:header字符串,并用逗号分隔多个值.
我首先要做的是传递一个字符串,就像在http标题中,但这不起作用甚至谷歌搜索如何使用基本的auth与swagger cli没有导致一些明确的答案.经过大量的尝试和错误后我(我使用CLI 2.1.2)我最终得到了正确的格式,例如:
java -jar swagger-codegen-cli-2.1.2.jar generate -a"授权:基本YWRtaW46YWRtaW4 =" - i http:// localhost:8080/webproject/restapi/swagger.json -l java -o restclient
其中YWRtaW46YWRtaW4 =是我的情况下admin:admin的base64编码值.
到现在为止还挺好.生成的Java客户端也必须使用基本身份验证.我看了一下ApiClient中的方法,发现了setUsername和setPassword.我认为这种方法使客户端能够使用基本身份验证,但没有运气.
所以我深入研究了生成的类,特别是ApiClient和几个生成的ApiService类.我发现setUsername和setPassword没有效果,原因如下:
/**
* Helper method to set username for the first HTTP basic authentication.
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
if (auth instanceof HttpBasicAuth) {
((HttpBasicAuth) auth).setUsername(username);
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
}
Run Code Online (Sandbox Code Playgroud)
同时HashMap定义如下:
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
Run Code Online (Sandbox Code Playgroud)
身份验证hashmap变得不可变,但为什么呢?什么是purpuse?此外,ApiClinet中没有辅助方法生成所需的auth对象,所以我做了以下操作:
1)注释掉行认证Collections.unmodifiableMap(authentications),以便hashmap再次变得可修改
2)手动创建所需的auth对象
HttpBasicAuth authentication = new HttpBasicAuth();
authentication.setUsername("admin");
authentication.setPassword("admin");
Run Code Online (Sandbox Code Playgroud)
3)将auth对象添加到apiClients认证hashmap:
ApiClient apiClient = new ApiClient();
apiClient.setBasePath(basePath);
apiClient.getAuthentications().put("basic", authentication);
Run Code Online (Sandbox Code Playgroud)
4)修改invokeApi方法(ApiClient.java)
public String invokeAPI(String path, String method, Map<String, String> queryParams, Object body, Map<String, String> headerParams, Map<String, String> formParams, String accept, String contentType, String[] authNames) throws ApiException {
String authNames2[] = {"basic"};
updateParamsForAuth(authNames2, queryParams, headerParams);
//updateParamsForAuth(authNames, queryParams, headerParams);
...
Run Code Online (Sandbox Code Playgroud)
第4步是必要的,因为ApiServices调用apiClient方法,如下所示:
String[] authNames = new String[] { };
String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
Run Code Online (Sandbox Code Playgroud)
另一种可能的解决方案是在每个apiService中定义Key auf认证hashmap,例如:
String[] authNames = new String[] { "basic" };
Run Code Online (Sandbox Code Playgroud)
完成所有修改后,一切都按预期工作,但我不能想到这是自动生成的休息客户端背后的想法.所以我的问题是:我是否遗漏了一些观点,或者我是否应该考虑到swagger生成的客户端(在本例中为java)更多的是正在开发的beta解决方案?请让我说对了,我认为整个招摇框架(jersey2支持,openapi,swaggerui,codegen)是一件很棒的事情,我很欣赏开发人员的努力,但我想使用codegen,我不认为背后的想法是所以必须以这种方式自定义生成的ApiClient和ApiServices.
小智 12
问题是您的规范没有提到您要使用的安全类型(也称为安全定义)或哪个安全定义适用于哪个端点.
swagger规范在这里,但它并不能说明整个故事.
您需要做的是1.设置安全定义.这是一个简单的基本http auth定义:
securityDefinitions:
basic:
type: basic
description: HTTP Basic Authentication.
Run Code Online (Sandbox Code Playgroud)
2.在结束点使用该安全性定义.
paths:
/:
get:
security:
- basic: []
responses:
200:
description: OK
Run Code Online (Sandbox Code Playgroud)
然后重新生成你的swagger客户端代码.它应该正确设置不可变映射和authNames数组.
| 归档时间: |
|
| 查看次数: |
5332 次 |
| 最近记录: |