OpenTok Rest Service Invalid JWT Error on Fiddler Request - rest

I'm trying to create OpenTok session by Rest services with JWT object as suggested. I tried to generate session with Fiddler.
Here is my fiddler request (JWT string has been changed with *** partially for security reasons)
POST https: //api.opentok.com/session/create HTTP/1.1
Host: api.opentok.com
X-OPENTOK-AUTH: json_web_token
Accept: application/json
Content-Length: 172
eyJ0eXAiOiJKV1QiL******iOiJIUzI1NiJ9.eyJpc3MiOjQ1NzM******OiJkZW5l******XQiOjE0ODI3OTIzO***SOMESIGNEDKEYHERE***.izvhwYcgwkGCyNjV*****2HRqiyBIYi9M
I got 403 {"code":-1,"message":"Invalid token format"} error probably means my JWT object is not correct. I tried creating it using http://jwt.io (as opentok suggests) and other sites and all seems correct and very similar to the one on tokbox (opentok) site.
I need an explanation to fix it and create a session.
May it be because I am using opentok trial?
JWT creation Parameters

I had the same problem. I resolved the error by setting the correct key-value pairs for the payload part.
Example of my payload is as follows in C#:
var payload = new Dictionary<string, object>()
{
{ "iss", "45728332" },
{ "ist", "project" },
{ "iat", ToUnixTime(issued) },
{ "exp", ToUnixTime(expire) }
};
The value of the "ist" should be set to "project", not the actual name of your project.
Update: Looking at your screenshot, I can say you have not set the secret key (here, it's your ApiKeySecret from TokBox account > project) at the very bottom right.

OK I have found the answer at last,
Your Opentok API Secret key should not be used directly as Sign parameter. In java as shown below, it should be encoded first.
Base64.encodeToString("db4******b51a4032a83*******5d19a*****e01".getBytes(),0)
I haven't tried it on http://jwt.io and fiddler but it seems it will work on it too. Thanks. Full code is below;
payload = Jwts.builder()
.setIssuedAt(currentTime)
.setIssuer("YOUR_OPENTOK_KEY")
.setExpiration(fiveMinutesAdded)
.claim("ist", "project")
.setHeaderParam("typ","JWT")
.signWith(SignatureAlgorithm.HS256, Base64.encodeToString("YOUR_OPENTOK_SECRET".getBytes(),0))
.compact();
return payload;

Related

How to make a call to Firestore using gRPC

I'm trying to build a gRPC client for Google's Firestore API in Elixir.
Before starting to write some code , I thought that it would be wise to first start with BloomRPC in order to debug the issue.
As base url, I'm using https://firestore.googleapis.com where I pinned the rot certificate.
As auth I'm using an access_token obtained using oauth with the following 2 scopes: "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/datastore"
being passed as a Authorization header:
{
"Authorization": "Bearer 29ya.a0AfH6SMBDYZPsVgQv0PMqyGRXypc3DfWF_2jbvAJKMquTaryCvxEB7X1Rbprfk1Ebrwid2bXbcR3Aw-d1Tytlo_lThkyqRDRIbnSz5-nQ3xWklkmjyFMAuQtFCoz01hk3vbgBwd2gdbFNNWiOU_8NqPC_vElyz2-cQ34"
}
And I get back:
{
"error": "3 INVALID_ARGUMENT: Missing required project ID."
}
So clearly I should be passing the project ID somehow but I can't find it anywhere in the docs. Anybody any clues?
I just figured out what I was doing wrong.
Basically the Bearer token I was using is correct (obtained via the OAuth Playground).
The trick was to specify the PROJECT_ID in the parent parameter of the request:
{
"parent": "projects/[project-id]/databases/(default)/documents",
"page_size": 10
}
I should have just read the docs properly :)

"invalid signature" JWT Token Opentok

I am trying to use the Opentok REST API with JWT to generate a video session token. I am using the following credentials to create the JWT following the JSONWebToken documentation at https://github.com/kylef/JSONWebToken.swift.
I have used the generated token for authorisation and followed the documentation at https://tokbox.com/developer/rest/#authentication and called the api from postman, but I am getting Invalid Signature error message. Where am i wrong?
var claims = ClaimSet()
claims["iss"] = "3*****2"
claims["ist"] = "account"
claims["iat"] = (Calendar.current.date(byAdding: .minute, value: 330, to: Date())?.timeIntervalSince1970)!
claims["exp"] = (Calendar.current.date(byAdding: .minute, value: 334, to: Date())?.timeIntervalSince1970)!
claims["jti"] = "\(NSUUID.init())"
claims["aud"] = "www.example.com"
let jToken = JWT.encode(claims: claims, algorithm: .hs256("334******************************d5af".data(using: .utf8)!))
print(jToken)
Hi Ram you are calling the session/create rest api. This api requires a project level authentication, however from you claims it looks like you are trying to generate a account level token.
The iss should be your API Key/ Project Id and the ist should be the string project.
Let me know if this helps and works.
I'm sure you figured your issue out by now but the archive mode and p2p.preference are not supposed to be header attributes but part of the body as json
At the Value field of "X-OPENTOK-AUTH" you first have to Write: "Bearer " + token.
If it doesn't work try changing "X-OPENTOK-AUTH" with "Authorization".

Can I get a consistent 'iss' value for a Google OpenIDConnect id_token?

I'm using Google's OpenIDConnect authentication, and I want to validate the JWT id_token returned from Google. However, the documentation seems inconsistent about what value Google returns for the iss (issuer) claim in the ID token.
One page says, "iss: always accounts.google.com", but another page says "The value of iss in the ID token is equal to accounts.google.com or https://accounts.google.com" and a comment in the example code further explains:
// If you retrieved the token on Android using the Play Services 8.3 API or newer, set
// the issuer to "https://accounts.google.com". Otherwise, set the issuer to
// "accounts.google.com". If you need to verify tokens from multiple sources, build
// a GoogleIdTokenVerifier for each issuer and try them both.
I have a server-side application, not an Android app, so I'm not using Play Services.
To further muddy the waters, the OpenIDConnect specification itself contains a note that:
Implementers may want to be aware that, as of the time of this writing, Google's deployed OpenID Connect implementation issues ID Tokens that omit the required https:// scheme prefix from the iss (issuer) Claim Value. Relying Party implementations wishing to work with Google will therefore need to have code to work around this, until such time as their implementation is updated. Any such workaround code should be written in a manner that will not break at such point Google adds the missing prefix to their issuer values.
That document is dated November 8, 2014. In the time since then, has Google standardized on an iss value, or do I really need to check for both of them? The comment above seems to indicate that only Play Services >=8.3 gets iss with https://, and everywhere else the value will be just accounts.google.com. Is that true?
You have to check both possibilities. This is what worked for me...
Decode the token to get the issuer. If the issuer is not equal to either one of https://accounts.google.com or accounts.google.com you can stop there. It's an invalid token.
If the issuer is equal to either of the above Google strings, then pass that same decoded issuer value forward to the verification step.
Following is the an implementation I wrote in JavaScript for some Node.js Express middleware:
function authorize(req, res, next) {
try {
var token = req.headers.authorization;
var decoded = jwt.decode(token, { complete: true });
var keyID = decoded.header.kid;
var algorithm = decoded.header.alg;
var pem = getPem(keyID);
var iss = decoded.payload.iss;
if (iss === 'accounts.google.com' || iss === 'https://accounts.google.com') {
var options = {
audience: CLIENT_ID,
issuer: iss,
algorithms: [algorithm]
}
jwt.verify(token, pem, options, function(err) {
if (err) {
res.writeHead(401);
res.end();
} else {
next();
}
});
} else {
res.writeHead(401);
res.end();
}
} catch (err) {
res.writeHead(401);
res.end();
}
}
Note this function uses jsonwebtoken and jwk-to-pem node modules. I ommitted details of the getPem function which ultimately converts a json web key to pem format.
To start with, I definitely agree that Google's documentation is a murky business.
There are a couple of different ways in which you can validate the integrity of the ID token on the server side (btw this is the page you're looking for):
"Manually" - constantly download Google's public keys, verify signature and then each and every field, including the iss one; the main advantage (albeit a small one in my opinion) I see here is that you can minimize the number of requests sent to Google).
"Automatically" - do a GET on Google's endpoint to verify this token - by far the simplest:
https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}
Using a Google API Client Library - the overhead might not be worth it, C# doesn't have an official one etc.
I suggest you go with the 2nd option and let Google worry about the validation algorithm.

How do you post to a Web API 2 OData Controller

I created a Web API 2 project and configured an OData4 controller following the steps here: Web API 2 Odata 4 Tutorial
However whenever I try and do a simple POST(with a JSON body to create an entity) using Postman I get the following error back:
The requested resource does not support http method 'POST'.
The POST action in the controller looks like this:
public async Task<IHttpActionResult> Post(Product product)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
The JSON I am posting in the request body is as follows:
{
"Id":"lewisblack",
"Name":"Lewis",
"Price":"Black",
"Category":"Category 1"
}
And I included the following headers in the request as well:
OData-Version: 4.0
OData-MaxVersion: 4.0
Content-Type: application/json
Am I missing something here?
UPDATE: Figured out the issue. I was using an incorrect URI.
Not much information to go on:
I suspect you don't have a PostMethod on the related controller.
Otherwhise, some other things to think about:
OData is case sensitive
You are missing a property that is required
a datatype is wrong ( Id in the example project is an integer, it looks like a string in your project, Price should be a decimal and not a string, ...)
Whats the HTTP Response code ( if above didn't help), when you post the object. ( use a tool like fiddler). Tip, if your http response is a "bad request", then your data is probably invalid to continue in the action.
I incorrectly used http://localhost:/ for the POST instead of https://localhost:/Products

REST: Not able to add cookie

I am using Apache CXF framework for my REST based service.
In the HTTPServletResponse, I am adding a cookie (using addCookie(Cookie cookie) method) but it is not being added successfully because, whenever I call the same API again, I couldn't see/use the added cookie.
I am using a REST client to call the API and I could see Set-Cookie header in the Respose Headers, but it is not being set.
What would be the problem here?
Well, the cookie is set actually.You will notice that further requests to your api carry the cookie along with them in the "Request Headers". To check the cookie, include the following code snippet in your Service Implementation:
In the implementation class, add the following annotation
#Context
private HttpHeaders headers;
Now, in the method of that class where you want to check the headers, add this code
if(headers.getRequestHeaders() != null) {
for(Entry<String, List<String>> entry : headers.getRequestHeaders().entrySet()) {
System.out.println("entry.getKey() >>>>>>>>>>> "+entry.getKey());
System.out.println("entry.getValue() >>>>>>>>>> "+entry.getValue());
}
}
Here, entry.getKey() will show you the header name and entry.getValue() will be showing a list of string values that this key is holding. If set, your cookie will appear under the header "cookie". I hope that helps.
Thanks.