iink SDK Web

Answered

Authentication Failure: Access Not Granted

I'm attempting to authenticate to MyScript using the REST API but I seem to have a malformed request or i'm computing the HMAC incorrectly in Swift. I'm not exactly sure what the issue is. Here is the error:

["code": access.not.granted, "message": Access not granted]

"""swift

import Foundation

import CryptoSwift

import CommonCrypto


struct RecognitionService {

    let apiKey: String

    let hmacKey: String

    let exampleRequest: [String: Any] = [

 "contentType": "Math",

 "configuration": [],

 "strokeGroups": [

 [

                "strokes": []

 ]

 ]

 ]

 

    init(apiKey: String, hmacKey: String, header: [String: String]? = nil) {

        self.apiKey = apiKey

        self.hmacKey = hmacKey

 }

 

    func computeHmacSha512(requestBody: String) -> String {

        let userKey = apiKey + hmacKey

        let hmacResult: String = requestBody.hmac(algorithm: HMACAlgorithm.SHA512, key: userKey)

        return hmacResult

 }

 

    func post() {

        let session = URLSession.shared

        let hmac = self.computeHmacSha512(requestBody: asString(jsonDictionary: exampleRequest))

 let url = URL(string: "https://cloud.myscript.com/api/v4.0/iink/batch")

        var request = URLRequest(url: url!)

 request.setValue("application/vnd.myscript.latex,application/json", forHTTPHeaderField: "Accept")

        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        request.setValue(apiKey, forHTTPHeaderField: "applicationKey")

        request.setValue(hmac, forHTTPHeaderField: "hmacKey")

        request.httpMethod = "POST"

        request.httpBody = asJson(jsonDict: exampleRequest)

        let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

            guard error == nil else {

                return

 }

 

            guard let data = data else {

                return

 }

 

            do {

                if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {

                    print(json)

 }

            } catch let error {

                print(error.localizedDescription)

 }

 })

        task.resume()

 }


}


func asString(jsonDictionary: [String: Any]) -> String {

    do {

        if let json = asJson(jsonDict: jsonDictionary) {

            return String(data: json, encoding: String.Encoding.utf8) ?? ""

        } else {

            return ""

 }

    } catch {

        return ""

 }

}


func asJson(jsonDict: [String: Any]) -> Data? {

    do {

        let data = try JSONSerialization.data(withJSONObject: jsonDict, options: .prettyPrinted)

        return data

    } catch {

        return nil

 }

}

enum HMACAlgorithm {

    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

 

    func toCCHmacAlgorithm() -> CCHmacAlgorithm {

        var result: Int = 0

        switch self {

        case .MD5:

            result = kCCHmacAlgMD5

        case .SHA1:

            result = kCCHmacAlgSHA1

        case .SHA224:

            result = kCCHmacAlgSHA224

        case .SHA256:

            result = kCCHmacAlgSHA256

        case .SHA384:

            result = kCCHmacAlgSHA384

        case .SHA512:

            result = kCCHmacAlgSHA512

 }

        return CCHmacAlgorithm(result)

 }

 

    func digestLength() -> Int {

        var result: CInt = 0

        switch self {

        case .MD5:

            result = CC_MD5_DIGEST_LENGTH

        case .SHA1:

            result = CC_SHA1_DIGEST_LENGTH

        case .SHA224:

 result = CC_SHA224_DIGEST_LENGTH

        case .SHA256:

 result = CC_SHA256_DIGEST_LENGTH

        case .SHA384:

 result = CC_SHA384_DIGEST_LENGTH

        case .SHA512:

 result = CC_SHA512_DIGEST_LENGTH

 }

        return Int(result)

 }

}


extension String {

    func hmac(algorithm: HMACAlgorithm, key: String) -> String {

        let cKey = key.cString(using: String.Encoding.utf8)

        let cData = self.cString(using: String.Encoding.utf8)

        var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))

        CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, strlen(cKey!), cData!, strlen(cData!), &result)

        let hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength())))

 let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength76Characters)

        return String(hmacBase64)

 }

 

}

"""





Best Answer

Hi Maximilian,



To make sure whether issue is in your HMAC computation, what you can do is disable temporarily the HMAC in your application profile in order to test your request without the HMAC.

If you don't know how to modify your application settings, please refer to  this post 


Regards,


Gwenaëlle


Dear Maximilian,


thank you for your question.


In your code, can you please try to replace "request.setValue(hmac, forHTTPHeaderField: "hmacKey")" with "request.setValue(hmac, forHTTPHeaderField: "hmac")"?


Best regards,


Olivier

Hi,

Yes, I also tried it with just hmac; however, that does not work either.

Thank you.

Dear Maximilian,


is the error message still the same?


If so, is it possible to have the request you are posting? It will be easier to investigate.


Best regards,


Olivier

Hi Olivier,

Yes the same error is being thrown. Here is the request in cURL:


curl -X POST -H "Content-Type: application/json" -H "Accept: application/vnd.myscript.latex,application/json" -H "applicationKey: *******" -H "hmac: ******" -d "{\"contentType\": \"Math\", \"strokeGroups\": []}" https://cloud.myscript.com/api/v4.0/iink/batch

Hi Maximilian,


After checking your CURL command we found two issues:

the Accept for latex should be application/x-latex and the empty strokeGroups leads to an error.


Could you please give a try to the following CURL command, replacing the hmac and applicationKey by your values?


curl -X POST \
https://cloud.myscript.com/api/v4.0/iink/batch \
-H 'Accept: application/x-latex,application/json' \
-H 'Content-Type: application/json' \
-H 'applicationKey: xxx' \
-H 'hmac: xxx' \
-d '{"contentType": "Math", "strokeGroups": [ {"strokes": [ {"id": "string","p": [0.5, 0.82,0.71,0.67, 0.67, 0.67, 0.71, 0.68, 0.71,0.68, 0.68], "pointerId": 0,"pointerType": "PEN", "t": [ 1516717383637,1516717383677,1516717383694,1516717383711,1516717383727,1516717383744,1516717383761,1516717383777,1516717383794,1516717383811,1516717383827], "x": [289,290,290,290,290,290,290,291,291,292,293],"y": [215,218,222,225,228,231,235,238,242,245,248]}]}]}'


Regards,


Gwenaëlle




Thank you for the response. Unfortunately, I'm still getting access not granted. Do you believe it is an error in the generation of the hmac?

Answer

Hi Maximilian,



To make sure whether issue is in your HMAC computation, what you can do is disable temporarily the HMAC in your application profile in order to test your request without the HMAC.

If you don't know how to modify your application settings, please refer to  this post 


Regards,


Gwenaëlle