I'm currently playing around with my jersey2 rest service. For a better overview of the given service (description, types and so on) I make heavily use of swagger (swagger-jersey2-jaxrs). So I'm able to genereate my service description (swagger.json) and I can view and explore them via swagger ui.
我正在玩我的jersey2休息服务。为了更好地概述给定的服务(描述,类型等),我大量使用了swagger(swagger-jersey2-jaxrs)。所以我能够创建我的服务描述(swagger.json),我可以通过swagger ui来查看和探索它们。
Now I'm at the point that I need to create some clients to make use of these services. I came accrooss swagger codegen cli which is a nice tool to generate your client and many different languages (java in my case). I'm able to generate the api client and the model in use.
现在,我需要创建一些客户端来利用这些服务。我来了accrooss swagger codegen cli,这是一个很好的工具来生成你的客户端和许多不同的语言(在我的情况下为java)。我能够生成api客户端和正在使用的模型。
Here I came accross the first problem. The REST services and the swagger description are http basic auth protected. I read the documentation which gave me some hint that there is a possibility to use basic auth. At this point I have to mention that from my point of view the doucmentation is very poor. It says:
在这里,我遇到了第一个问题。 REST服务和swagger描述是http基本身份验证保护。我阅读了文档,它给了我一些暗示,有可能使用基本的auth。在这一点上,我不得不提到,从我的观点来看,doucmentation非常差。它说:
-a , --auth adds authorization headers when fetching the swagger definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values.
-a, - auth在远程获取swagger定义时添加授权标头。传入URL编码的name:header字符串,并用逗号分隔多个值。
First thing I thoght of is to pass a string like in an http header but that doen't work and even googling how to use basic auth with swagger cli didn't result in some clear answser. After a lot of try and errors I (I'm using CLI 2.1.2) I finaly came accross the right format, eg:
我首先要做的是传递一个像http标题中的字符串,但这不起作用,甚至谷歌搜索如何使用基本的auth与swagger cli没有导致一些明确的答案。经过大量的尝试和错误后我(我使用CLI 2.1.2)我最终得到了正确的格式,例如:
java -jar swagger-codegen-cli-2.1.2.jar generate -a "Authorization: Basic YWRtaW46YWRtaW4=" -i http://localhost:8080/webproject/restapi/swagger.json -l java -o restclient
java -jar swagger-codegen-cli-2.1.2.jar generate -a“授权:基本YWRtaW46YWRtaW4 =” - i http:// localhost:8080 / webproject / restapi / swagger.json -l java -o restclient
where YWRtaW46YWRtaW4= is the the base64 encoded value of admin:admin in my case.
其中YWRtaW46YWRtaW4 =是我的情况下admin:admin的base64编码值。
So far so good. The generated java client have to make use of basic auth as well. I took a look at the methods from the ApiClient and found setUsername and setPassword. I thought that this methods empoweres the client to use basic auth but no luck.
到现在为止还挺好。生成的Java客户端也必须使用基本身份验证。我看了一下ApiClient中的方法,发现了setUsername和setPassword。我认为这种方法使客户端能够使用基本的auth,但没有运气。
So I took a deeper look at the generated classes especially the ApiClient and the several generated ApiService Classes. I found out that the setUsername and setPassword have no effect because of the following:
所以我深入研究了生成的类,特别是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!");
}
where at the same time the HashMap is defined as the following:
同时HashMap定义如下:
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<String, Authentication>();
// Prevent the authentications from being modified.
authentications = Collections.unmodifiableMap(authentications);
The authentication hashmap becomes immutable, but why? What is the purpuse? Furthermore there are no helper methods inside the ApiClinet which generates the needed auth object so I did the follwing:
身份验证hashmap变得不可变,但为什么呢?什么是purpuse?此外,ApiClinet中没有辅助方法可以生成所需的auth对象,所以我做了以下操作:
1) comment out the line authentications Collections.unmodifiableMap(authentications) so the hashmap becomes modifiable again
1)注释掉行认证Collections.unmodifiableMap(authentications),以便hashmap再次变得可修改
2) create needed auth object manualy
2)手动创建所需的auth对象
HttpBasicAuth authentication = new HttpBasicAuth();
authentication.setUsername("admin");
authentication.setPassword("admin");
3) add the auth object to the apiClients authentication hashmap:
3)将auth对象添加到apiClients认证hashmap:
ApiClient apiClient = new ApiClient();
apiClient.setBasePath(basePath);
apiClient.getAuthentications().put("basic", authentication);
4) modifying invokeApi Method (ApiClient.java)
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);
...
Step 4 is necessary because the ApiServices invoke the apiClient method like the following:
第4步是必要的,因为ApiServices调用apiClient方法,如下所示:
String[] authNames = new String[] { };
String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
An other possible solution would be to define the Key auf the authentications hashmap in every apiService like:
另一种可能的解决方案是在每个apiService中定义Key auf认证hashmap,例如:
String[] authNames = new String[] { "basic" };
After doing all the modifications everything works as expected but I cant think of that this is the idea behind an autogenerated rest client. So my question is: Am I missing some point or should I think of the swagger generated client (java in this case) more of a beta solution which is under development? Please get me right, I think the whole swagger framework (jersey2 support, openapi, swaggerui, codegen) is a great thing and I appreciate the developers effort but I want to use the codegen right and I don't think that the idea behind is so have to customize the generated ApiClient and ApiServices in such a way.
完成所有修改后,一切都按预期工作,但我不能想到这是自动生成的休息客户端背后的想法。所以我的问题是:我是否错过了一些观点,或者我是否应该考虑到swagger生成的客户端(在本例中为java)更多的是正在开发的beta解决方案?请让我说对了,我认为整个招摇框架(jersey2支持,openapi,swaggerui,codegen)是一件很棒的事情,我很欣赏开发人员的努力,但我想正确使用codegen,我不认为背后的想法是所以必须以这种方式自定义生成的ApiClient和ApiServices。
1 个解决方案
#1
9
The issue is that your specification does not mention the types of Security you want to use (a.k.a. Security Definitions) or which Security Definition applies to which end point.
问题是您的规范没有提到您要使用的安全类型(a.k.a.安全定义)或哪个安全定义适用于哪个端点。
The swagger specification is here, but it doesn't tell the whole story.
swagger规范在这里,但它并不能说明整个故事。
What you need to do is 1. Set up the Security Definitions. Here is a simple basic http auth definition:
您需要做的是1.设置安全定义。这是一个简单的基本http auth定义:
securityDefinitions:
basic:
type: basic
description: HTTP Basic Authentication.
and 2. Use that security definition in the end point.
2.在结束点使用该安全性定义。
paths:
/:
get:
security:
- basic: []
responses:
200:
description: OK
Then regenerate your swagger client code. It should set up the immutable map correctly and the authNames array.
然后重新生成你的swagger客户端代码。它应该正确设置不可变映射和authNames数组。
#1
9
The issue is that your specification does not mention the types of Security you want to use (a.k.a. Security Definitions) or which Security Definition applies to which end point.
问题是您的规范没有提到您要使用的安全类型(a.k.a.安全定义)或哪个安全定义适用于哪个端点。
The swagger specification is here, but it doesn't tell the whole story.
swagger规范在这里,但它并不能说明整个故事。
What you need to do is 1. Set up the Security Definitions. Here is a simple basic http auth definition:
您需要做的是1.设置安全定义。这是一个简单的基本http auth定义:
securityDefinitions:
basic:
type: basic
description: HTTP Basic Authentication.
and 2. Use that security definition in the end point.
2.在结束点使用该安全性定义。
paths:
/:
get:
security:
- basic: []
responses:
200:
description: OK
Then regenerate your swagger client code. It should set up the immutable map correctly and the authNames array.
然后重新生成你的swagger客户端代码。它应该正确设置不可变映射和authNames数组。