Missing request header 'authToken' calling RestAPI method - rest

I have this RestAPI method
#GetMapping(path = "/menus",
consumes = "application/json",
produces = "application/json")
public ResponseEntity<List<MenuPriceSummary>> allMenus(HttpServletRequest request, #RequestHeader(value="Authorization: Bearer") String authToken) {
String username = jwtTokenUtil.getUsernameFromToken(authToken);
User user = userService.findByUserName(username);
return ResponseEntity.ok(menuService.allMenus(user));
}
which I call from curl
curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsb3Blei5hbnRvbmlvODVAZ21haWwuY29tIiwiZXhwIjoxNTk0MTkzNDYwLCJpYXQiOjE1MzM3MsM0NjB9.9pXvdiRMM5fjE4Ur5nqKvwvRLmNWyn6tY6y5fPXOg_BWEW2sJ8vnrLTXPfiA-Sc6Qk2XTwi6FhlIhFEQKip4aQ" "http://127.0.0.1:1133/canPeris/api/v1/users/menus"
But I got this error:
"status":400,"error":"Bad Request","message":"Missing request header 'Authorization: Bearer' for method parameter of type String"'authToken' for method parameter of type String","tr....

You can't use #RequestHeader that way. The values from the headers get split up by : and added to a Map, so every value containing a : is impossible.
You will have to change your annotation to #RequestHeader(value="Authorization") and then remove the Bearer from the authToken.

Spring MVC provides annotation #RequestHeader that can be used to map controller parameter to request header value .
Can you please change your method to
#GetMapping(path = "/menus",
consumes = "application/json",
produces = "application/json")
public ResponseEntity<List<MenuPriceSummary>> allMenus(
#RequestHeader(value="Authorization") String authToken,
HttpServletRequest request) {
String username = jwtTokenUtil.getUsernameFromToken(authToken);
User user = userService.findByUserName(username);
return ResponseEntity.ok(menuService.allMenus(user));
}
You can also make use of Interceptors to validate headers so that other rest endpoints in your application can make use of it .

Related

Rest Client gives Bad Request for HTTP PUT request

I'm new to Rest Client development. Need your help in figuring out how to get a proper response for below rest service.
curl --location --request PUT 'sandbox-url/TokenGeneratorAPI/v1/update_pay_status' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {{token}' \
--data-raw '{
"pay_id":000000000,
"status":1,
"amount":0.00,
"pay_method":0,
"pay_sys_ref":"test"
}'
I created a class in client side for request object like below.
public class PaymentRqBean {
#XmlElement(name="pay_id")
String pay_id;
#XmlElement(name="status")
String status;
#XmlElement(name="amount")
String amount;
#XmlElement(name="pay_method")
String pay_method;
#XmlElement(name="pay_sys_ref")
String pay_sys_ref;
public String getPay_id() {
return pay_id;
}
public void setPay_id(String pay_id) {
this.pay_id = pay_id;
}
}
......and getters setters for other attributes
And created a method for calling the web service in another class like below.
public PaymentRsBean callWS(PaymentRqBean pReq) {
PaymentRsBean prs = new PaymentRsBean();
Client client = ClientBuilder.newClient();
client.register(new Authenticator(com.boc.conf.Configurations.objProperty.getProperty("ikUserName"), com.boc.conf.Configurations.objProperty.getProperty("ikPassword")));
WebTarget webTarget = client.target(url);
Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON);
Response response = invocationBuilder.accept(MediaType.APPLICATION_JSON).put(Entity.json(pReq));
I'm getting HTTP 400 BAD REQUEST for above. I would be so thankful for any help given in solving this.
(Is it because #XmlRootElement? )
The problem is the way you are defining the attributes of your PaymentRqBean class.
The variables 'pay_id', 'status', 'amount' and 'pay_method' must be of numeric type (int, double...), since the request you launch indicates that they are numeric, not Strings.
"pay_id":000000000,
"status":1,
"amount":0.00,
"pay_method":0

send msg to Azure service bus que via REST

The Azure Queues are exposed to REST API.To make the REST call works. I ran a sample test on POSTMAN. The POST call
https://yournamespace.servicebus.windows.net/yourentity/messages
Also, Passing below 2 headers and values.
Header 1:
Authorization: SharedAccessSignature sr=https%3A%2F%2F.servicebus.windows.net%2Fyourentity&sig=yoursignature from code above&se=1529928563&skn=KeyName
Example:
SharedAccessSignature sr=https%3A%2F%2Fservicebussoatest1.servicebus.windows.net%2Fpublishque&sig=a0wmRklbCGFCYoSCViij9gagtZV9Bg+vU=&se=1529928563&skn=testpolicy
Header 2:
Content-Type: application/json
But even though I have passed the correct Authorization value, I am getting the error below:
401:Invalid Authorization Token signature
401:Invalid Authorization Token signature
According to the 401 error meanings that the token is not vaild.
Firstly please make sure that your policy has access to send the message.
Secondly, if you want to use the azure service bus Send Message Rest APi. The format should be following.
POST https://<yournamespace>.servicebus.windows.net/<yourentity>/messages
Authorization: SharedAccessSignature sr=https%3A%2F%2F<yournamespace>.servicebus.windows.net%2F<yourentity>&sig=<yoursignature from code above>&se=1438205742&skn=KeyName
ContentType: application/atom+xml;type=entry;charset=utf-8
We also could get more information about Service Bus access control with Shared Access
Signatures from this article.
I also do a demo with postman. It works correctly on my side.
I use the following code to get the SAS token.
public static string GetSasToken(string resourceUri, string keyName, string key, TimeSpan ttl)
{
var expiry = GetExpiry(ttl);
string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);
return sasToken;
}
private static string GetExpiry(TimeSpan ttl)
{
TimeSpan expirySinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1) + ttl;
return Convert.ToString((int)expirySinceEpoch.TotalSeconds);
}
string queueUrl = "https://tomtestsb.servicebus.windows.net/" + "queue" + "/messages";
string token = GetSasToken(queueUrl,"Key", "value", TimeSpan.FromDays(1));
We could get the key and value with Azure portal
Test it with Postman.
Headers:
Authorization:SharedAccessSignature sr=https%3a%2f%2fyournamespace.servicebus.windows.net%2fqueuename%2fmessages&sig=SyumAUNnqWFjW2MqjwlomU%2fbblqZljq6LPJp3jpfU%2b4%3d&se=1529478623&skn=KeyName
Content-Type:application/xml
Body
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">This is a message.</string>
Test Result:
Simple 2 step process:
First you can import the below Curl in postman:
curl --location --request POST '{{topicQueueForAzureServiceBusUri}}' \
--header 'ContentType: application/atom+xml;type=entry;charset=utf-8' \
--header 'Authorization: {{SasTokenForAzureServiceBus}}' \
--header 'Content-Type: application/json' \
--data-raw '{"YOUR JSON"}'
Copy All the key generation script to the prerequisite step of Postman Request and replace first four variable values from your topic/queue config:
var namespace = "YOUR Namespace";
var topicQueueName = "YOUR TOPIC/QUEUE Name";
var sharedAccessKeyName = "YOUR sharedAccessKeyName";
var sharedAccessKey = "YOUR sharedAccessKey";
var topicQueueForAzureServiceBusUri = "https://" + namespace + ".servicebus.windows.net/" + topicQueueName + "/messages";
pm.collectionVariables.set("topicQueueForAzureServiceBusUri", topicQueueForAzureServiceBusUri);
var sasToken = createSharedAccessToken(topicQueueForAzureServiceBusUri, sharedAccessKeyName, sharedAccessKey);
pm.collectionVariables.set("SasTokenForAzureServiceBus", sasToken);
function createSharedAccessToken(uri, saName, saKey) {
if (!uri || !saName || !saKey) {
throw "Missing required parameter";
}
var encoded = encodeURIComponent(uri).toLowerCase();
var now = new Date();
var week = 60*60*24*7;
var ttl = Math.round(now.getTime() / 1000) + week;
var signature = encoded + '\n' + ttl;
var hash = CryptoJS.HmacSHA256(signature, saKey);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
return 'SharedAccessSignature sr=' + encoded + '&sig=' +
encodeURIComponent(hashInBase64) + '&se=' + ttl + '&skn=' + saName;
}
This worked for me:
The url to POST to: https://[ServiceBusNamespace].servicebus.windows.net/[QueueName]/messages
Authorization: use code provided by Tom Sun - MSFT
Content-Type: application/json

Translating curl into Matlab/Webwrite

I have the following curl command I need to sent to a web server using Matlab and webwrite using POST. My problem is that I always get a "Bad request" answer so my syntax must be wrong somehow. Does anybody have an idea how this curl command, sending the body could look like in Matlab using webwrite in a correct way ?
body=$(cat << EOF
{
"order": {
"units": "100",
"instrument": "EUR_USD",
"timeInForce": "FOK",
"type": "MARKET",
"positionFill": "DEFAULT"
}
}
EOF
)
curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <AUTHENTICATION TOKEN>" \
-d "$body" \
"https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders"
I have just asked a potentially similar question so this may not work first time. However I cannot test without knowing some login details so I can but hope this helps.
data_InputValues = struct ('units',100,'instrument','EUR_USD','timeInForce','FOK','type','MARKET','positionFill','DEFAULT');
MyBody = matlab.net.http.MessageBody(struct('order',data_InputValues));
MyHTTPOptions = matlab.net.http.HTTPOptions(); % use this to change the options if necessary (e.g. extend timeout)
Request = matlab.net.http.RequestMessage;
Request.Method = 'POST';
Request.Header = matlab.net.http.HeaderField('Content-Type','application/json','Authorization: Bearer',AUTHENTICATION TOKEN);
Request.Body = MyBody;
uri = matlab.net.URI('https://api-fxtrade.oanda.com/v3/accounts/<ACCOUNT>/orders');
[response a ~] = Request.send(uri,MyHTTPOptions);
The part I struggle with is generating the MyBody part (in your case this is parsing the order variable's sub-variables). If you get this to work I would be keen to know how! P.S. my question in case it helps: Matlab RESTful PUT Command - net.http - nesting body values
The correct format for the body is as follows:
body = struct('units',100,'instrument','EUR_USD','timeInForce','FOK',...
'type','MARKET','positionFill','DEFAULT');
As for the HTTP headers that you require you can specify them with weboptions when using webwrite.
The syntax for an additional header:
options = weboptions('KeyName','Name','KeyValue','Value')
Where Name and Value are the name of the header and its value respectively.
You must add the headers that you require in weboptions.
For the code you provided, the correct syntax would be as follows:
options = weboptions('MediaType','application/json',...
'KeyName','Authorization: Bearer','KeyValue','Token');
You can then perform the POST request at the URL of interest.
response = webwrite(url,body,options);

Can't able to view a transform in browser using REST in Marklogic 9?

I tried to install below Server-Side JavaScript using this documentation and saved below as rest-sjs
function insertTimestamp(context, params, content)
{
if (context.inputType.search('json') >= 0) {
var result = content.toObject();
if (context.acceptTypes) { /* read */
result.readTimestamp = fn.currentDateTime();
} else { /* write */
result.writeTimestamp = fn.currentDateTime();
}
return result;
} else {
/* Pass thru for non-JSON documents */
return content;
}
};
exports.transform = insertTimestamp;
I tried to push this using below curl cmd:
curl --anyauth --user public\admin:admin -X PUT -i --data-binary #"C:/Users/name/Desktop/rest.sjs" -H "Content-type: application/vnd.marklogic-javascript" 'http://localhost:9963/v1/config/transforms/js-example'
When I used localhost:9963 and went to /v1/config/transforms I can see:
<rapi:transforms xmlns:rapi="http://marklogic.com/rest-api">
<rapi:transform>
<rapi:name>rest-tsm</rapi:name>
<rapi:source-format>javascript</rapi:source-format>
<rapi:transform-parameters/>
<rapi:transform-source>/v1/config/transforms/rest-tsm</rapi:transform-source>
</rapi:transform>
</rapi:transforms>
But when I went though the module /v1/config/transforms/rest-tsm I am seeing an error response:
<error-response xmlns="http://marklogic.com/xdmp/error">
<status-code>406</status-code>
<status>Unacceptable Type</status>
<message-code>REST-UNACCEPTABLETYPE</message-code>
<message>
REST-UNACCEPTABLETYPE: (err:FOER0000) No acceptable content type: None of the requested types text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 can be provided
</message>
</error-response>
I can see the the module in Modules db. Which worked fine when I try to insert a document by using the transform.
Why can't I view the transform in the browser?
Unfortunately, that rest endpoint isn't very browser friendly. The required/acceptable Accept header values do not match what browsers will normally send.
When you made the GET request through your browser, it was sending the following Accept header:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept
This field contains a semicolon-separated list of representation schemes ( Content-Type metainformation values) which will be accepted in the response to this request.
Unfortunately, the v1/config/transform/{name} (GET) REST endpoint is strict in what it will accept for the Accept header and expects a specific value:
The MIME type of the data expected in the response, either application/xslt+xml or application/xquery.
If you use the example CURL command from the documentation, and customize for your transform URI, it will return the expected response.
curl --anyauth --user public\admin:admin -X GET -i \
-H "Accept: application/xquery" \
http://localhost:9963/v1/config/transforms/rest-tsm

How to get a paypal access token using REST request

I'm trying to get this working https://developer.paypal.com/webapps/developer/docs/integration/direct/make-your-first-call/
Using Java + Jersey application. It seems like I'm missing something in POST params.
public String getPaypalToken() {
Client client = Client.create();
WebResource webResource = client.resource("https://api.sandbox.paypal.com/v1/oauth2/token");
MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
queryParams.add("username", CLIENT_ID + ":" + SECRET );
queryParams.add("grant_type", "client_credentials");
ClientResponse response = webResource.accept("application/json").acceptLanguage("en_US").type("application/x-www-form-urlencoded").post(ClientResponse.class, queryParams);
return response.toString();
}
Using previous code I got: POST https://api.sandbox.paypal.com/v1/oauth2/token returned a response status of 401 Unauthorized.
This CURL command line option just works fine:
curl -X POST https://api.sandbox.paypal.com/v1/oauth2/token -H "Accept: application/json" -H "Accept-Language: en_US" -u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" -d "grant_type=client_credentials"
Any suggestions will be appreciated.
J.
The -u option in curl sends a base64 encoded "username:password" string. I don't think adding client id / secret to the queryParams map does the same (unless Jersey treats the 'username' key differently which I don't think it does).
You should instead try
webResource.header("Authorization", "Basic " + Base64.encode(CLIENT_ID + ":" + SECRET.getBytes()))
Just sharing my solution:
Dictionary<string, string> sdkConfig = new Dictionary<string, string>();
sdkConfig.Add("mode", "sandbox");
string clientid = "<your client id>";
string secretid = "<your secret id>";
string accessToken = new OAuthTokenCredential(clientid, secretid, sdkConfig).GetAccessToken();
I previously encountered unauthorized response using RestSharp, then found this. I'm using paypal .net sdk from nuget package.
Reference.