How to create jws message signing in karate [duplicate] - java-web-start

This question already has answers here:
Buffer in JS file isn't recognized (API tests automation with Karate Framework)
(3 answers)
Closed 1 year ago.
i need to pass a header in the request which should have detached jws signed by private key (signed request payload. Is there any option in karate to do so?
or anybody did it before?

Please refer to this answer: https://stackoverflow.com/a/52205655/143475
We have it as a demo sample now: https://github.com/intuit/karate/tree/master/karate-demo (look for "JWT")
* def parseJwtPayload =
"""
function(token) {
var base64Url = token.split('.')[1];
var base64Str = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var Base64 = Java.type('java.util.Base64');
var decoded = Base64.getDecoder().decode(base64Str);
var String = Java.type('java.lang.String');
return new String(decoded);
}
"""

Related

GDrive api: Whenever the file name contains special utf-8 chars -> "Content size exceeds specified contentLength. [...]" [duplicate]

This question already has answers here:
Flutter: HttpClient post contentLength -- exception
(3 answers)
Closed 2 years ago.
I'm writing a flutter application, in which I want to sync files to Google Drive. However I came across the problem, that whenever I want to upload a file for which I specify the name with a utf-8 char. like e.g. in "Käsekuchen", I get the following exception:
"ClientException (Content size exceeds specified contentLength. 1410067 bytes written while expected 1410066. [--314159265358979323846--])":
When I change the name to something without the special character, it works fine. I guess the solution is quite simple but I couldn't find it.
import 'package:googleapis/drive/v3.dart' as ga;
var client = GoogleHttpClient(await googleSignInAccount.authHeaders);
var drive = ga.DriveApi(client);
ga.File fileToUpload = ga.File();
fileToUpload.parents = ["appDataFolder"];
fileToUpload.name = "Käsekuchen.jpg";
var response = await drive.files.create(
fileToUpload,
uploadMedia:
ga.Media(uploadFile.openRead(), uploadFile.lengthSync()),
);
So do I have to specify a certain encoding somewhere or what am I doing wrong?
Answer:
The special character is endoded as two bytes. You need to account for this in the content length.
Fix:
Change:
var response = await drive.files.create(
fileToUpload,
uploadMedia:
ga.Media(uploadFile.openRead(), uploadFile.lengthSync()),
);
to:
var response = await drive.files.create(
fileToUpload,
uploadMedia:
ga.Media(uploadFile.openRead(), uploadFile.lengthSync() + 1),
);

coinbase api always 401 unauthorized

I have waited faithfully for well over 48 hours since generating api keys as suggested and no matter what I do, every coinbase api call gives 401 Unauthorized
I have checked basic non-authentication required calls like /time and /exchange_rates and they work fine
I am using coinbase and not coinbase pro so this is a simple api key and header based call
Have triple checked the hashing and decoding requirements, and nothing is apparent as an issue
Rather than asking to resolve coding problems from the standard examples, the ask is either
Is anyone aware of general authorization issues with the coinbase service right now ? (nothing published by coinbase)
Is there anything outside of the general code samples and documentation that needs to be done to get this damn thing authorizing ?
Any and all help appreciated.
References used :
https://developers.coinbase.com/docs/wallet/api-key-authentication#
Have added the basic code used for completeness here :
// Remove insecure protocols (SSL3, TLS 1.0, TLS 1.1)
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;
ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11;
// Add TLS 1.2
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
HttpClient client = new HttpClient();
string sTimeStamp = Convert.ToInt64(DateTime.Now.Ticks).ToString("F0", CultureInfo.InvariantCulture);
client.BaseAddress = new Uri(sUrl + sOperation);
var convertedString = Convert.FromBase64String(sAPI_EXCHANGE_SECRET);
var prehash = sTimeStamp + "GET" + sOperation + ""; // no content for now
string sSignature = HashString(prehash, convertedString);
// bunch of headers for coinbase
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("User-Agent", "CryptoAppClient"); // arbitrary user agent name
client.DefaultRequestHeaders.Add("CB-ACCESS-KEY", sAPI_EXCHANGE_KEY);
client.DefaultRequestHeaders.Add("CB-VERSION", sAPI_EXCHANGE_VERSION);
client.DefaultRequestHeaders.Add("CB-ACCESS-SIGN", sSignature);
client.DefaultRequestHeaders.Add("CB-ACCESS-TIMESTAMP", sTimeStamp);
// set up the actual call
HttpResponseMessage response = client.GetAsync("").Result;
.....
//----------------------------------------------------------------------------
private string HashString(string str, byte[] secret)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(str);
using (var hmaccsha = new HMACSHA256(secret))
{
return Convert.ToBase64String(hmaccsha.ComputeHash(bytes));
}
}
Finally go it sorted, combination of timestamp value wrong and the right .net functions to encrypt the message

unable to read data from decoded token jwt verify [duplicate]

This question already has an answer here:
How to get user id using jwt token
(1 answer)
Closed 2 years ago.
jwt.verify(token,process.env.SECRETKEY, function(err,decodedToken){
console.log(decodedToken);
})
Console output
{ email: 'm.blal#gmail.com', iat: 1601341321 }
how can I read the value of email from decoded token?
Attach the email to the request, then you can access that value from the controller
jwt.verify(token,process.env.SECRETKEY, function(err,decodedToken){
if(err) throw new ForbiddenException('Invalid token');
req.user = decodedToken //Attach token payload to request
})
You can use that value later on the controller using req.user or creating a decorator (I prefer this).

Post with Accept Header .Net Core 3.1 - PagSeguro

I'm trying to integrate with a payment gateway (PagSeguro), according to the documentation, I must use the Accept Header "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1".
Trying with the code not work:
HttpClient.DefaultRequestHeaders.Clear();
HttpClient.DefaultRequestHeaders.Add("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1");
var content = new StringContent(json, Encoding.Default, "application/json");
var response = await HttpClient.PostAsync(enderecoPreApprovals, content);
var responsestr = await response.Content.ReadAsStringAsync();
I also tried using the same code from documentation:
var client = new RestClient(url) {Timeout = -1};
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1");
request.AddParameter("application/json", content, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
and using flurl:
var response = await addresPreApprovals
.WithHeader("Accept", "application/vnd.pagseguro.com.br.v3+json;charset=ISO-8859-1")
.WithHeader("Content-Type", "application/json")
.PostJsonAsync(adesaoDto);
All the responses are Accept header field is mandatory.. It's like Accept Header is not recognized.
The problem is not in API why i tried using Postman and Insomnia and it's works perfectly.
The problem occurs because of the space between the semicolon (;) and the word charset. We were unable to make it work in .NET 3.1 and there is even an issue on github, indicating that it is not a problem, an implementation of the RFC 7231 specification. Whenever a string "var1 = val1; var2 = val2", o is indicated. NET converts to "var1 = val1; var2 = val2". However, in .NET 5.0, an implementation was released that allows entering a raw string. Another option, according to an old post, is to create something with .NET Framework 4.5
In .NET 5.0
var acceptValue = "application/vnd.pagseguro.com.br.v1+json;charset=ISO-8859-1";
var requestMessage = new HttpRequestMessage(HttpMethod.Post, urlApprovals);
requestMessage.Headers.TryAddWithoutValidation("accept", acceptValue);
GitHub ref: https://github.com/dotnet/runtime/issues/30171
User who solved the problem using .NET Framework 4.5: https://stackoverflow.com/a/40162071/2112736

Must/can I install MS ASP.NET Web API Client Libraries in order to post data to my Web API server?

Do I need to install ASP.NET Web API Client Libraries (as this article indicates) in order to post data to a Web API server? If so, can I do so in Visual Studio 2008 from a Windows CE project?
The reasons I wonder are:
0) The client is a Windows CE project, for which I'm using Visual Studio 2008, and I don't know if ASP.NET Web API Client Libraries are available for that version; I know I don't have the NuGet Package Manager in that environment.
1) I am successfully querying data from my RESTful Web API methods without installing ASP.NET Web API Client Libraries, using code like this:
while (true)
{
deptList.departments.Clear();
string uri = String.Format("http://platypi:28642/api/Duckbills/{0}/{1}", lastIdFetched, RECORDS_TO_FETCH);
var webRequest = (HttpWebRequest) WebRequest.Create(uri);
webRequest.Method = "GET";
using (var webResponse = (HttpWebResponse)webRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
var reader = new StreamReader(webResponse.GetResponseStream());
string jsonizedDuckbills = reader.ReadToEnd();
List<Duckbill> duckbills = JsonConvert.DeserializeObject<List<Duckbill>>(jsonizedDuckbills);
if (duckbills.Count <= 0) break;
foreach (Duckbill duckbill in duckbills)
{
duckbillList.duckbills.Add(duckbill);
lastIdFetched = duckbill.Id;
}
} // if ((webResponse.StatusCode == HttpStatusCode.OK)
} // using HttpWebResponse
int recordsAdded = LocalDBUtils.BulkInsertDuckbills(duckbillList.duckbills);
totalRecordsAdded += recordsAdded;
} // while (true);
I'm stuck on posting, though, and the cleanest example I've seen so far for doing so is at that link already shown above.
I got an answer to my question on how to post here, but that hasn't made me smart enough yet to actually accomplish it. It's a step in the right direction, perhaps, although I reckon, based on how my client query code looks, that the client posting code would be of similar "style" (like the previously referenced article here, and unlike the likewise previously referenced answer here).
UPDATE
If I'm already providing the data in the uri string itself, as I am, like this:
string uri = String.Format("http://shannon2:28642/api/Departments/{0}/{1}", onAccountOfWally, moniker);
...why would I need to also specify it in postData? Or could I set postData (if that's just a necessary step to get the length) to those values...something like:
postData = String.Format("{0}, {1}", onAccountOfWally, moniker);
?
To talk to ASP.NET Web API, you do not necessarily need the client library, although it makes the life easier. After all, one of the benefits of HTTP services is the platform reach. Literally you can use any library that gives you HTTP capabilities. So, using WebRequest, you can do something like this. I'm using JSON in the payload. You can use XML and application/www-form-urlencoded as well. Just that you need to format the request body accordingly. Also, for complex objects, you will be better off using JSON.NET unlike formatting the JSON manually.
var request = System.Net.WebRequest.Create("http://localhost:12345/api/values");
request.Method = "POST";
string postData = "{\"firstName\":\"Steven\"," + "\"lastName\":\"Waugh\"}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/json";
request.ContentLength = byteArray.Length;
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(byteArray, 0, byteArray.Length);
}
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var reader = new System.IO.StreamReader(responseStream))
{
string responseFromServer = reader.ReadToEnd();
Console.WriteLine(responseFromServer);
}
}
}
EDIT
If you are specifying data in URI, you do not need to specify the same in the request body. To let web API bind the parameters for you from URI, you will need to specify the route accordingly so that the placeholders are set for onAccountOfWally and moniker. Then you will need to use a simple type like string as action method parameters for web API to bind. By default, simple types are bound from URI path and query string and complex types from request body.