I have noticed that when building a Thorntail REST application using JAX-RS and Swagger UI dependencies, the REST call generated by Swagger UI uses https instead of http.
Here is the REST Service I'm using:
#Path("/time")
#Api(value = "/time", description = "Get the time", tags = "time")
#Produces(MediaType.APPLICATION_JSON)
public class HelloWorldEndpoint {
#GET
#Path("/now")
#ApiOperation(value = "Get the current time",
notes = "Returns the time as a string",
response = String.class
)
#Produces(MediaType.APPLICATION_JSON)
public String get() {
return String.format("{\"value\" : \"The time is %s\"}", new Date());
}
}
And the dependencies:
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>swagger</artifactId>
</dependency>
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>jaxrs</artifactId>
</dependency>
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>swagger-webapp</artifactId>
</dependency>
In this case, the generated REST call is:
curl -X GET "https://localhost:8080/time/now" -H "accept: application/json"
which returns:
curl: (35) SSL received a record that exceeded the maximum permissible length.
Is there any parameter (#Api ?) that forces using 'http' instead of 'https' ?
On my side, I used this configuration in project-defaults.yml
thorntail:
deployment:
my-webapp.war:
swagger:
schemes:
- http
Related
I have a Java/Spring-based microservices architecture with two services:
A - has a public-facing endpoint which does some stuff and then calls the below endpoint on B. This endpoint requires an Authorization header (OAuth2) to identify the user.
B - has an endpoint that also requires an Authorization header (OAuth2) so that it can determine which user made the call.
I have specified B's endpoint using OpenAPI. I'm using OpenAPI Generator to generate both the client in A (Spring WebClient), and the server in B (Spring Boot).
My question is this: what do I need to do to pass the Authorization header along from A to B? I see how to set a static header, but I don't know how to pass the header based on what's received by A.
Similar to this question, but for WebClient: OpenAPI client generator Java - header per call
As your A service is a resource-server and you want to issue request to service B on behalf of the user who initiated the request to A, just set a Bearer Authorization header on WebClient with the original access-token string retrieved from current security context (use SecurityContextHolder static accessor or have AbstractOAuth2TokenAuthenticationToken<?> auth auto-magically injected by Spring as #Controller method parameter).
If your A service was a client, you could do as I did in the UiController of this tutorial.
Turns out my problem was how I specified the endpoint security in my OpenAPI specification.
I added:
components:
securitySchemes:
s2s:
type: oauth2
flows:
clientCredentials:
authorizationUrl: https://example.com/oauth/authorize
tokenUrl: https://example.com/oauth/token
scopes:
read: Read scope
And made a reference to that security schema on my endpoint:
/foo:
get:
...
security:
- s2s:
- read
Now, when I run openapi-generate on this schema and generate it to either Spring Boot (server) or Java WebClient (client), the generated endpoint signature looks like:
#RequestMapping(
method = RequestMethod.GET,
value = "/foo",
produces = { "application/json" }
)
Mono<ResponseEntity<MyResponse>> foo(
#Parameter(name = "Authorization", description = "", required = true) #RequestHeader(value = "Authorization", required = true) String authorization,
#Parameter(hidden = true) final ServerWebExchange exchange
);
The String authorization argument to the method was not previously being generated and it's what I needed here. It allows me to pass A's header along to the call to B.
Props to #Ch4mp for helping out here.
I am using the swagger with springodc-openapi-ui
It is possible to set parameters with default values for post token method: /oauth/token?
I added openapi-security dependency
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
<version>1.6.6</version>
</dependency>
but swagger displays it as:
Instead of these parameters, I want to have"grant_type": "client_credentials"
I am absolutly new in WSO2 ESB and at this time I have to achive this first simple task but I really don't know from where start.
I have to perform an HTTP POST request towards an external web service. This request should contains a mocked XML document as payload (at this time the XML have to be merely mocked so I think that I have to "write" it somewhere or something like this).
So starting by this minimalistic official tutorial:
https://docs.wso2.com/display/ESB500/Sending+a+Simple+Message
I have done the following operation:
1) I have created a new ESB Solution Project.
2) On the "main" project named SampleServices (at this time I am using the same name of the tutorial) I have registered the endpoint to my external web service (New -> Endpoint).
3) Then on this project I have add a new RESP API (New -> REST API). Differently from the tutorial I have enable POST request instead of GET into the API Resource properties because I need to send a POST request containing a payload instead the tutorial GET request. This is my settings:
4) Then, as done in the tutorial, I have setted the send mediator and on this mediator I have setted the defined endpoint pointing at my external web service that have to handle the POST request and retrieve its payload.
Ok, now my problem is: how can I put a mocked XML document into the body of my POST request sended by my *send mediator**?
Reading this second tutorial:
https://docs.wso2.com/display/ESB500/Routing+Requests+Based+on+Message+Content
I know that I can pass the request payload from outside, for example in this second tutorial perform this CURL call that starts the ESB "process":
curl -v -X POST --data #request.json http://localhost:8280/healthcare/categories/surgery/reserve --header "Content-Type:application/json"
This do a call that pass a JSON as payload. In the previous example works fine but it is not good for me.
I have to mock the XML document payload inside my ESB API flow and not take from an external request performed by CURL because in a second implementationstep it will not be mocked but il will come from a previous step in the chain.
So I need a flow like this:
When my API is called it perform a POST request that send a mocked XML payload. Maybe it is have to be putted into the send mediator but I don't know...
How can I put this XML in the payload of the requeste sended by the send mediator? Where have I to define\write it?
Check this sample:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/services/users" name="ListUsersAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" url-mapping="/*">
<inSequence>
<payloadFactory media-type="json">
<format>{ "persons":[{ "person": { "Id":"1", "givenName":"ajith", "lastName":"vitharana", "age":"25", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email", "value":"ajith#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile",
"value":"111111111" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] }}, {"person":{ "Id":"2", "givenName":"shammi", "lastName":"jagasingha", "age":"30", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email",
"value":"shammi#abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile", "value":"2222222222" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] } }] }</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
I am trying to use a custom java application of mine to upload videos to my youtube account via an access limited device like a Raspberry pi running as a server.
For this I am using the Google Oauth 2.0 for limited input device as a reference.
I followed the steps mentioned with my custom java application, Fiddler and curl, the surprise is as follows:
All of the calls worked right as mentioned by Google Oauth 2.0 for limited input device for curl.
But issues were observed with Fiddler and my custom java app for the following call:
When I am trying to get the access token from Google server (Step 4 from Google Oauth link) by posting similar request:
POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
client_id=1084945748469-eg34imk572gdhu83gj5p0an9fut6urp5.apps.googleusercontent.com&
client_secret=hDBmMRhz7eJRsM9Z2q1oFBSem&
code=4/YMSlR3fSCC1NtUh073DuZKTJJ3ss&
grant_type=http://oauth.net/grant_type/device/1.0
but instead of getting the 'access_token' as response I am getting the following :
Status Code:400 Response: { "error" : "invalid_request",
"error_description" : "Required parameter is missing: grant_type" }
Note : With or without url encoding, my problem stays the same.
I am unable to understand what the issue is with my custom java app or with fiddler, Please help.
Following are my fiddler requests:
(One can get oauth credentials (client_id and client_secret) by following this)
Fiddler request:
(url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXXX&code=4%2FWR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http%3A%2F%2Foauth.net%2Fgrant_type%2Fdevice%2F1.0
Content-Type: application/x-www-form-urlencoded
(non url encoded, obscured client secret)
POST HTTP/1.1
https://accounts.google.com/o/oauth2/token?client_id=308065994473-ur9dd7003ajs6mvr5s4kqnugr6j8tsf2.apps.googleusercontent.com&client_secret=XXXXXXXXXXXXXX&code=4/WR-qiTquqB0e4-0LCy0-7rZ2kkE2&grant_type=http://oauth.net/grant_type/device/1.0
Java code project is available at (maven project, check the test case for the Oauth calls):
https://docs.google.com/file/d/0B8ltWBtPF-DVMDZFNHNMZXpCQlk
The parameters need to be added in the http post request body not in the url, Google documentation is confusing on this part.
public synchronized HttpResponse executePOST(HttpEntity httpEntity, String path) throws IOException {
if (!parameters.isEmpty()) {
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpPost = new HttpPost(path);
logger.info(target.toHostString());
logger.info(httpPost.getURI().toString());
logger.info(httpPost.getRequestLine().toString());
for (Header header : headers) {
logger.info(header.getName() + ": " + header.getValue());
httpPost.addHeader(header);
}
httpResponse = httpClient.execute(target, httpPost);
return httpResponse;
}
I'm laying the groundwork for a very basic Grails app that integrates with Last.fm. I'm stuck on the user authentication where I get a session key. From the documentation, it sounds like a very simple HTTP POST in the format I have below in code. I've tried every variation of the HTTPBuilder's post and request(POST) I've found but all error out with something like this:
| Server running. Browse to http://localhost:8080/GroovyLastFM
| Error 2013-05-14 19:57:10,042 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver - MissingPropertyException occurred when processing request: [GET] /GroovyLastFM/RecentSongs/tokenChecker - parameters:
token: 452b5619f98e3b66cec11b61940af500
No such property: Method for class: GroovyLastFM.User. Stacktrace follows:
Message: No such property: Method for class: GroovyLastFM.User
Line | Method
->> 28 | getSession in GroovyLastFM.User
I don't know what else I could need to import, but obviously something is missing. Is this where the grails plugins come in? If so, what do I need to include at the app level to make HTTPBuilder work? I'm very new to grails and am not sure what merits an addition to the dependencies, or how to do it. Also, I'm on Grails 2.1.1 and am not using an IDE. Thanks!
package GroovyLastFM
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
import java.security.MessageDigest
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
class User {
String token
String api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
String secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
User (String token) {
this.token = token
getSession()
}
def getSession() {
String signature = md5("api_key" + api_key + "methodauth.getSessiontoken" + token + secret)
def postbody = [token:token, api_key:api_key, method:'auth.getSession', api_sig:signature]
def http = new HTTPBuilder("http://wx.audioscrobbler.com/2.0/")
http.request(Method.POST) {req->
headers.accept = "application/xml"
requestContentType = ContentType.URLENC
body = postbody
response.success { resp,xml->
// read xml response
}
}
}
I did also try a basic curl post to make sure my parameters are correct, and it did return the session key as I expected:
curl -X POST -d "token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&api_key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&method=auth.getSession&api_sig=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" http://ws.audioscrobbler.com/2.0/
Links:
Last.fm API: www.last.fm/api/webauth
Previous post I was building on: HTTPBuilder HTTP Post url encoded parameters and accept xml response?
HTTPBuilder Post Doc: http://groovy.codehaus.org/modules/http-builder/doc/post.html
You are importing groovyx.net.http.Method.* and using Method.POST, that's why you are getting No such property: Method.
Replace it with:
http.request(POST) { req -> ... }
... that should do.
Alternatively, you could also change the import to:
import static groovyx.net.http.Method
and continue using Method.POST.