reTHINK-project / dev-registry-global

Global Registry
Apache License 2.0
4 stars 0 forks source link

Call Global Registry #23

Closed AlexTouze closed 7 years ago

AlexTouze commented 7 years ago

I try to call the Global registry with an xhr request but I receive an error 500 in response. What parameters are expected in enter ?

sgoendoer commented 7 years ago

https://github.com/reTHINK-project/dev-registry-global#interfaces

What exactly is the request you are sending?

Try http://130.149.22.133:5002/ in a browser

AlexTouze commented 7 years ago

I send this request :

request( { method: 'PUT', proxy: 'http://proxy.rd.francetelecom.fr:3128/', uri: 'http://130.149.22.133:5002/guid/' + req.body.guid, port: '5002', headers: { 'Content-Length': req.body.jwt.length, 'Content-Type': 'application/json' }, data: JSON.stringify(req.body.jwt) }

sgoendoer commented 7 years ago

I get these errors in the logs:

org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]

Aparently, the JWT is malformed. What is in the JWT?

AlexTouze commented 7 years ago

The JWT is a jsonwebtoken

AlexTouze commented 7 years ago

I try to generate a jsonwebtoken as in java sample (TestJWT.java)

sgoendoer commented 7 years ago

Please note that due to changes in the Dataset schema, these classes are outdated. If you want to create a valid Dataset JWT, use test/DatasetTool.java

Apart from that:

Have you checked what stringify actually does to the body? Maybe you monitor what is actually sent out there.

The part where this error is thrown is line 149 in RestService:

JSONObject jwtHeader = new JSONObject(new String(Base64UrlCodec.BASE64URL.decodeToString(jwt.split("\\.")[0])));

Here, the JWT's header is separated from the JWT (which is the HTTP request's body) and decoded. A JSON Object is created form the result.

The problem is apparently that what is passed to the JSONObject-constructor is not valid JSON. Hence my question what the request's body ACTUALLY looks like.

sgoendoer commented 7 years ago

Has this been solved?

AlexTouze commented 7 years ago

I try to generate a good JWT

sgoendoer commented 7 years ago

You can always try the one from the examples https://github.com/reTHINK-project/dev-registry-global#put-guidguid or create one using test/DatasetTool.java before creating the JWT by yourself. This way, you can make sure that the interface is working fine.

AlexTouze commented 7 years ago

This is an example to better explain my JWT's generation :

In enter I have this

guid : "d0mRlfKDsHqVd-mKB1eYIGqYH15mdwwDSFveDtCb9j0" privatePEM : "-----BEGIN PRIVATE KEY----- MEUCAQAwEAYHKoZIzj0CAQYFK4EEAAoELjAsAgEBBCAwn4eUFU6Gozcgrbt56sMd ogvmeMENLNg8L1wNWRKmV6EFAwMAAAA= -----END PRIVATE KEY-----" publicPEM : "-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEX1JVnjEwEYUw+uNo/fDZupu7me0FiaYRnVRkeWuGnvE+T42ybRAOeDebCQUeINJJQQc3+VVQgpJMPy6CTopvIQ==-----END PUBLIC KEY-----" salt: "0rohRPbNdQXyUonFRX+WyIdxvSlt8xx6Cq71IyrXfoE="

{"guid":"d0mRlfKDsHqVd-mKB1eYIGqYH15mdwwDSFveDtCb9j0","schemaVersion":1,"userIDs":[{"uid":"user://machin.goendoer.net/","domain":"google.com"},{"uid":"user://bidule.com/fluffy123","domain":"google.com"}],"lastUpdate":"2016-12-07T11:36:38+00:00","timeout":"2026-12-07T11:36:38+00:00","publicKey":"-----BEGIN PUBLIC KEY-----MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEX1JVnjEwEYUw+uNo/fDZupu7me0FiaYRnVRkeWuGnvE+T42ybRAOeDebCQUeINJJQQc3+VVQgpJMPy6CTopvIQ==-----END PUBLIC KEY-----","salt":"0rohRPbNdQXyUonFRX+WyIdxvSlt8xx6Cq71IyrXfoE=","active":1,"revoked":0,"defaults":{"voice":"a","chat":"b","video":"c"}}

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.ZXlKbmRXbGtJam9pWkRCdFVteG1TMFJ6U0hGV1pDMXRTMEl4WlZsSlIzRlpTREUxYldSM2QwUlRSblpsUkhSRFlqbHFNQ0lzSW5OamFHVnRZVlpsY25OcGIyNGlPakVzSW5WelpYSkpSSE1pT2x0N0luVnBaQ0k2SW5WelpYSTZMeTl0WVdOb2FXNHVaMjlsYm1SdlpYSXVibVYwTHlJc0ltUnZiV0ZwYmlJNkltZHZiMmRzWlM1amIyMGlmU3g3SW5WcFpDSTZJblZ6WlhJNkx5OWlhV1IxYkdVdVkyOXRMMlpzZFdabWVURXlNeUlzSW1SdmJXRnBiaUk2SW1kdmIyZHNaUzVqYjIwaWZWMHNJbXhoYzNSVmNHUmhkR1VpT2lJeU1ERTJMVEV5TFRBM1ZERXhPak0yT2pNNEt6QXdPakF3SWl3aWRHbHRaVzkxZENJNklqSXdNall0TVRJdE1EZFVNVEU2TXpZNk16Z3JNREE2TURBaUxDSndkV0pzYVdOTFpYa2lPaUl0TFMwdExVSkZSMGxPSUZCVlFreEpReUJMUlZrdExTMHRMVTFHV1hkRlFWbElTMjlhU1hwcU1FTkJVVmxHU3pSRlJVRkJiMFJSWjBGRldERktWbTVxUlhkRldWVjNLM1ZPYnk5bVJGcDFjSFUzYldVd1JtbGhXVkp1VmxKclpWZDFSMjUyUlN0VU5ESjVZbEpCVDJWRVpXSkRVVlZsU1U1S1NsRlJZek1yVmxaUlozQktUVkI1TmtOVWIzQjJTVkU5UFMwdExTMHRSVTVFSUZCVlFreEpReUJMUlZrdExTMHRMU0lzSW5OaGJIUWlPaUl3Y205b1VsQmlUbVJSV0hsVmIyNUdVbGdyVjNsSlpIaDJVMngwT0hoNE5rTnhOekZKZVhKWVptOUZQU0lzSW1GamRHbDJaU0k2TVN3aWNtVjJiMnRsWkNJNk1Dd2laR1ZtWVhWc2RITWlPbnNpZG05cFkyVWlPaUpoSWl3aVkyaGhkQ0k2SW1JaUxDSjJhV1JsYnlJNkltTWlmWDA.3Wdz9z6xfkMV2z9MkmKJef-2bmqQ8MsPplouMtI0eRe5hU6wrBSMxFyUJ7uwDNPd_nQO2kt9Tl712BeNnAH8Qg

If you see some errors in this elements I would like know where they are

Thanks

sgoendoer commented 7 years ago

OK I guess I found your error:

When creating the JWT, you need to set a "private claim" called "data" (https://tools.ietf.org/html/rfc7519#section-4.3), which has to have the base64URL-encoded dataset as a value. Looks like you just set the payload of the JWT plain to be the base64URL-encoded dataset. This will cause the server to throw an "invalid dataset" error.

You can check easily via https://jwt.io/

Apart from that, the dataset / jwt looks fine

KCorre commented 7 years ago

@AlexTouze the JWT is formed of three parts separated by a dot. i.e: header.payload.signature As @sgoendoer said, you can verify your JWT on jwt.io. Alternatively you can also decode each part separatly with the javascript atob(b64string) function.

When decoding your example token, we get

{ "alg": "ES256", "typ": "JWT"} . B64_STUFF_ENCODED . SIGNATURE

As Sebastian said, it should be: { "alg": "ES256", "typ": "JWT"} . {"data": B64_STUFF_ENCODED} . SIGNATURE

create JWT

Create the dataset as a JSONObject as described above
serialize the JSONObject
encode it via Base64URL
create a JWT
set a claim "data" with the Base64URL-encoded JSONObject as value
sign the JWT using the private key matching the enclosed public key
the result can be sent to the gReg via PUT

The error is on the create JWT and set data claim steps.

KCorre commented 7 years ago

However, I'm not sure why it is done like that. In practice, what we are actually doing is including the JSON dataset into another JSON object with a single "data" member. And the payload is then twice encoded in B64. There is a substantial overhead in terms of message size: +33% in Alexandre example.

If it is for compatibility with other reThink components, the serialize and encoding steps seems unnecessary.

sgoendoer commented 7 years ago

To answer the "why":

A JWT's payload has to be a JSON object with claims. Hence the "data" claim. As of https://tools.ietf.org/html/rfc7519#section-4.3, allowed types of claims are not specified. So in theory, a nested JSON object would do just fine. Anyhow, we ran into several implementation issues doing this as of limitations of some JWT libraries, which are apparently not able to handle JSON objects as values for claims. Hence the encoding of the claim's payload (meaning the JSON dataset itself).

AlexTouze commented 7 years ago

@sgoendoer I tried to follow your recommandations but I still have an 500 error when I call the api. However I verify the jwt that I send like this :

jwt.verify(rToken, currentUser.publickey, {algorithms: ['ES256']}, function(err, decoded) { console.log(decoded) // bar console.log(err) });

With:

So I don't see where is my errors because the jwt is valid. You see some problems ?

sgoendoer commented 7 years ago

There are \r\n linebreaks in the public key as UTF8 characters. I guess that's at least not helping. Apart from that, I don't spot any other errors. I guess, this will cause the validation to fail on the server side.

In the logs, there are no traces of a PUT for this GUID. All I find is something like:

2016-12-21 12:30:44 INFO RestService:81 - GET Request received for GUID OxYHdymW84P8IToxJRKdpgq8TDT2CMHtgucPPBoxlDA 2016-12-21 15:50:13 INFO RestService:136 - PUT Request received: 2016-12-21 15:50:13 ERROR RestService:249 - Error while putting data into DHT: A JSONObject text must begin with '{' at 1 [character 2 line 1] org.json.JSONException: A JSONObject text must begin with '{' at 1 [character 2 line 1]

AlexTouze commented 7 years ago

Hello

@sgoendoer I watched the RestService.java file and the line with the logs

@PUT @Path("guid/{guid}") // @Consumes("application/json") // there is no application/json+jwt content // type yet public Response putData(String jwt, @PathParam("guid") String guid) { LOGGER.info("PUT Request received: " + jwt);

I can see that the jwt element is null. What is the name of parameter which to be in the ajax request ? Currently my request is like this :

request( { proxy: 'http://proxy.rd.francetelecom.fr:3128/', method: 'PUT', uri: urlRequest, port: '5002', headers: { 'Content-Length': rToken.length, 'Content-Type': 'application/json' }, data : rToken }, function (error, response, body) { if (response.statusCode != 200) { console.log('error ' + response.statusCode) console.log(JSON.stringify(req.body.token)) } else { console.log('statusCode: ' + response.statusCode) console.log(JSON.stringify(req.body.token)) } } )

Maybe I forgot a parameter or I use a wrong one ?

sgoendoer commented 7 years ago

There is no parameter name for the jwt. The jwt has to be put AS IS into the body of the HTTP PUT request as used here: https://github.com/reTHINK-project/dev-registry-global/blob/tmp_master/README.md#put-guidguid

fbeierle commented 7 years ago

please re-open if needed