[SOLVED] Cosmos DB Emulator and Uniface

Author: tommy.balkis@gmail.com (tommyb42)

Hi all ,  I am trying to develop a Restfull Api call with Uniface  to microsoft Cosmos Db emulator. They have a complex  Authorization token which i construct it  according to microsft 's instructions. I'm always getting an error from the token validation from server but i cannot find a possible reason. I make the same call from visual studio with .Net Sdk and it works fine  Please find below the uniface code for the http call  ;-------------------------------------------------------------------- Variables String vsUsername String vsPassword String vsUrl String vsHttpHeader String vsHttpContent String vsResponse String vsmaster numeric vnHour String vsHash String vsVerb String vsKey String vsDate String vsResType String vsResLinks EndVariables vnHour =$datim[H]-3 vsmaster="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" vsmaster =$decode("BASE64", "%%vsmaster") vsVerb="GET" vsResType="dbs" vsResLinks ="" vsDate ="%%$datim[Aaa]%%%,%%% %%$datim[d]%%% %%$datim[Mmm]%%% %%$datim[y]%%% %%FixSize("%%vnHour ",2,"0",1)%%%:%%FixSize("%%$datim[n]",2,"0",1)%%%:%%FixSize("%%$datim[s]",2,"0",1)%%% GMT" vsHash ="%%$Lowercase(vsVerb)%%^%%$lowercase(vsResType)%%^%%vsResLinks%%^%%$Lowercase(vsDate)%%^%%% %%^" vskey=$encode("HMAC_SHA256","%%vshash","%%vsmaster") vskey=$encode("BASE64","%%vsKey") vskey=$encode("URL","type=master&ver=1.0&sig=%%vskey") NewInstance "UHTTP" , "CosmosDb" Activate "CosmosDb".Set_Flags(10) vsResponse = "" vsUrl = "https://localhost:8081/dbs" putitem/id/case vsHttpHeader, "Authorization","%%vsKey" putitem/id/case vsHttpHeader, "x-ms-date","%%vsDate" putitem/id/case vsHttpHeader,"Content-Type", "application/json;charset=UTF-8" putitem/id/case vsHttpHeader, "x-ms-version","2017-02-22" Activate "CosmosDb".send(vsUrl, %\ "GET", %\ vsUsername, %\ vsPassword , %\ vsHttpHeader, %\ vsHttpContent, %\ vsResponse) If ($Status !=200) message/info "%%vsHttpContent" Endif If ($Status=200 ) message/info "%%vsResponse" Endif ;-------------------------------------------------------------------- I am using uniface 9.7.1 and i also run it from uniface 9.7.3 You can download the emulator from here : https://docs.microsoft.com/en-us/azure/cosmos-db/local-emulator and  the Api Referece from here :https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources   I would appreciate every help to make it  work  from uniface.   Regards Thomas

18 Comments

  1. I've no major clue, but $encode returns a raw value. Have you tried making the vskey variable a raw datatype?


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  2. Yes Iain , i ve tried  same error responce.Cry


    Author: tommyb42 (tommy.balkis@gmail.com)
  3. I've done something similar, using a somehow different syntax for the sending. But that's probably the same functionality. ; Call the UHTTP.SEND operation vUHTTP->SET_FLAGS(8) ;Send headers with all methods. By default, headers are sent only on the POST and PUT methods. vStatus = vUHTTP->SEND(vURI, "GET", "", "", vHeaders, vContent, vResponse) Can't see any other way than comparing what you send from VS to what you send from Uniface. Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  4. Hi Roger ,  The Problem actualy it is on the authorization token, by the way it is produced from uniface and how it's read from the cosmos db.


    Author: tommyb42 (tommy.balkis@gmail.com)
  5. What's the Uniface version in question?


    Author: Knut (knut.dybendahl@gmail.com)
  6. 9.7.1 and also tested with 9.7.3


    Author: tommyb42 (tommy.balkis@gmail.com)
  7. So, application/json wasn't fixed (from what I understand) until 9.7.2. (https://unifaceinfo.com/forum/uniface9/restful-service-in-uniface/) What does the IIS error logs say? Knut


    Author: Knut (knut.dybendahl@gmail.com)
  8. So you had you tried this: raw vskeyRaw string vskey vskeyRaw=$encode(“HMAC_SHA256″,”%%vshash”,”%%vsmaster”) vskey=$encode(“BASE64″,”%%vsKey”) I haven't digged into this now, but I found some testing I did some months ago, finding that SHA1 and HMAC_SHA256 works in Uniface, except for empty "" value. We tested somehow like this: variables raw tRaw string tBase64 endvariables debug ;tRaw = $encode("HMAC_SHA256", "f95fa8b05c6747ffff790d7c4444f6d8|POST|https://changedapi/changed/changed|1446723703|983fchanged71a8f9e|2jmj7l5rchangedK/YBwk=", "dj4qUsjchangedTvchangedM=") ;tBase64 = $encode("BASE64", tRaw) tRaw="" tRaw = $encode("SHA1", tRaw) tBase64 = $encode("BASE64", tRaw) perhaps you can learn something from this. Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  9. Hi Knut ,  The error message is : "{"code":"Unauthorized","message":"The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign: 'get dbs tue, 22 may 2018 7 :47:08 gmt ' ActivityId: c33075ef-a447-4cae-b803-a24a62b60d8e, Microsoft.Azure.Documents.Common/1.20.108.4"}"


    Author: tommyb42 (tommy.balkis@gmail.com)
  10. Hi Roger ,  If there is a problem with the "" for  HMAC_SHA256 encoding  perhaps this is a probably answear beacause according the instructions you have to pass this to the key  StringToSign = Verb.toLowerCase() + " " + ResourceType.toLowerCase() + " " + ResourceLink + " " + Date.toLowerCase() + " " + "" + " ";


    Author: tommyb42 (tommy.balkis@gmail.com)
  11. Hi, There is not a problem with the encoding, except if you try to encode an empty/null string. Otherwise we have got the same result as with VS. Ok, now I saw what you meant. Strange.... You probably have to hardcode the "", but I'm not sure what + "" + "" really mean..... Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  12. Hi Thomas, There are two issues here: 1. The $encode function expects the key as RAW and not BASE64 2. The default (internal) new line character is CR (0x0D) and not LF (0x0A) When I use the example encoding from the mentioned API reference page (https://docs.microsoft.com/en-us/rest/api/cosmos-db/access-control-on-cosmosdb-resources) then the following code will give the same result:

    variables   string vVerb, vResourceType, vResourceLink, vDate, vKey, vKeyType, vTokenVersion   raw vKeyRaw, vPayLoadRaw, vHashPayLoad   string vSignature, vOutput endvariables vVerb = "GET" vResourceType = "dbs" vResourceLink = "dbs/ToDoList" vDate = "Thu, 27 Apr 2017 00:51:12 GMT" vKey = "dsZQi3KtZmCv1ljt3VNWNm7sQUF1y5rJfC6kv5JiwvW0EndXdDku/dkKBp8/ufDToSxLzR4y+O/0H/t4bQtVNw==" vKeyRaw = $decode("BASE64", vKey) vPayLoadRaw = $concat($encode("URAW", $lowercase(vVerb)), $decode("HEX", "0A")) vPayLoadRaw = $concat(vPayLoadRaw, $encode("URAW", $lowercase(vResourceType)), $decode("HEX", "0A")) vPayLoadRaw = $concat(vPayLoadRaw, $encode("URAW", vResourceLink), $decode("HEX", "0A")) vPayLoadRaw = $concat(vPayLoadRaw, $encode("URAW", $lowercase(vDate)), $decode("HEX", "0A0A")) vHashPayLoad = $encode("HMAC_SHA256", vPayLoadRaw, vKeyRaw) vSignature = $encode("BASE64", vHashPayLoad) vKeyType = "master" vTokenVersion = "1.0" vOutput = $encode("URL", $concat("type=", vKeyType, "&ver=", vTokenVersion, $concat("&sig=", vSignature)))

    I hope this helps. Regards, Daniel


    Author: diseli (daniel.iseli@uniface.com)
  13. Ok, this ” + Date.toLowerCase() + “ ” + “” + “ “; was a bit strange in your example. But you can probably just ignore + "" + as Daniel has done. The fact that Uniface encodes an empty string wrong, didn't have anything with your problem to do. Regards RogerW.


    Author: rogerw (roger.wallin@abilita.fi)
  14. Hi Daniel,  You are right but still i am getting the same error. I will investigate it further i'll come back. Anyway thanks a lot for your help.


    Author: tommyb42 (tommy.balkis@gmail.com)
  15. Hi Thomas, This is working for me:

    ;——————————————————————– Variables   String vsUsername   String vsPassword   String vsUrl   String vsHttpHeader   String vsHttpContent   String vsResponse   String vsmaster   raw vsmasterraw   numeric vnHour   raw vsHashRaw   String vsVerb   raw vsKey   string vsSignature   datetime vsDatim   String vsDate   String vsResType   String vsResLinks EndVariables vsDatim = $datim vnHour=vsDatim[H]-2 vsmaster="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" vsmasterraw=$decode("BASE64", vsmaster) vsVerb="GET" vsResType="dbs" vsResLinks ="" vsDate ="%%vsDatim[Aaa]%%%,%%% %%vsDatim[d]%%% %%vsDatim[Mmm]%%% %%vsDatim[y]%%% %%n99("%%vnHour")%%%:%%n99(vsdatim[n])%%%:%%n99(vsdatim[s])%%% GMT" vsHashRaw = $concat($encode("URAW", $lowercase(vsVerb)), $decode("HEX", "0A")) vsHashRaw = $concat(vsHashRaw, $encode("URAW", $lowercase(vsResType)), $decode("HEX", "0A")) vsHashRaw = $concat(vsHashRaw, $encode("URAW", vsResLinks), $decode("HEX", "0A")) vsHashRaw = $concat(vsHashRaw, $encode("URAW", $lowercase(vsDate)), $decode("HEX", "0A0A")) vskey=$encode("HMAC_SHA256",vshashraw,vsmasterraw) vsSignature=$encode("BASE64",vsKey) vsSignature=$encode("URL","type=master&ver=1.0&sig=%%vsSignature") NewInstance "UHTTP" , "CosmosDb" Activate "CosmosDb".Set_Flags(10) vsResponse = "" vsUrl = "https://localhost:8081/dbs" putitem/id/case vsHttpHeader, "Authorization","%%vsSignature" putitem/id/case vsHttpHeader, "x-ms-date","%%vsDate" putitem/id/case vsHttpHeader,"Content-Type", "application/json;charset=UTF-8" putitem/id/case vsHttpHeader, "x-ms-version","2017-02-22" Activate "CosmosDb".send(vsUrl, %\ "GET", %\ vsUsername, %\ vsPassword , %\ vsHttpHeader, %\ vsHttpContent, %\ vsResponse) If ($Status !=200)   message/info "%%vsHttpContent" Endif If ($Status=200 )   message/info "%%vsResponse" Endif return(0) ;——————————————————————– entry n99 returns string params   string pSrc : IN endparams   ; $N99$ => Display Format: DIS(99)   $N99$ = pSrc   return("%%$N99$") end

    Please note that I had to adjust the time (my time zone is UTC+1). Hope this helps. Daniel


    Author: diseli (daniel.iseli@uniface.com)
  16. And here's the result from the call: vsResponse = "HTTP/1.1 200 Ok" vsHttpContent = "{"_rid":"","Databases":[{"id":"ToDoList","_rid":"QfBiAA==","_self":"dbs\/QfBiAA==\/","_etag":"\"00000000-0000-0000-f1b9-b26f9bc401d3\"","_colls":"colls\/","_users":"users\/","_ts":1526985798}],"_count":1}"


    Author: diseli (daniel.iseli@uniface.com)
  17. By Changing the last Line of Daniels Code to vOutput = $encode("URL", $concat("type=", vKeyType, "&ver=", vTokenVersion, $concat("&sig=", vSignature))) Finaly I Get The Http 200 Ok. Thanks all of you for your help. 


    Author: tommyb42 (tommy.balkis@gmail.com)
  18. tommyb42 said By Changing the last Line of Daniels Code to vOutput = $encode("URL", $concat("type=", vKeyType, "&ver=", vTokenVersion, $concat("&sig=", vSignature))) Finaly I Get The Http 200 Ok. Thanks all of you for your help.   

    Thanks for your feedback. Good to hear that you've got it working now. I'm not sure what happened with my code example, but it seems that the editor converted the "&" to "&". I've corrected this now.


    Author: diseli (daniel.iseli@uniface.com)