简体   繁体   中英

SAS token generation for calling azure rest API in JAVA

I am trying to generate an SAS token using the code snippet given in the azure IoT Hub documentation, to call a GET devices API in IoT Hub( https://iot-hub-name.azure-devices.net/devices?api-version=2020-03-13 ). The code is

private static String GetSASToken(String resourceUri, String keyName, String key)
    {
        long epoch = System.currentTimeMillis()/1000L;
        int week = 60*60*24*7;
        String expiry = Long.toString(epoch + week);

        String sasToken = null;
        try {
            String stringToSign = URLEncoder.encode(resourceUri, "UTF-8") + "\n" + expiry;
            String signature = getHMAC256(key, stringToSign);
            sasToken = "SharedAccessSignature sr=" + resourceUri +"&sig=" +
                    URLEncoder.encode(signature, "UTF-8") + "&se=" + expiry + "&skn=" + keyName;
        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();
        }

        return sasToken;
    }


  public static String getHMAC256(String key, String input) {
      Mac sha256_HMAC = null;
      String hash = null;
      try {
          sha256_HMAC = Mac.getInstance("HmacSHA256");
          SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
          sha256_HMAC.init(secret_key);
          Encoder encoder = Base64.getEncoder();

          hash = new String(encoder.encode(sha256_HMAC.doFinal(input.getBytes("UTF-8"))));

      } catch (InvalidKeyException e) {
          e.printStackTrace();
      } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
      } catch (IllegalStateException e) {
          e.printStackTrace();
      } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
      }

      return hash;
  }

Then i have called the generate SAS token method as,

String sasToken= GetSASToken("https://<iot-hub-name>.azure-devices.net", "shared access policy name", "primary key of the shared access policy");

But the SAS token generated is giving a 401 Unauthorised, which means the token generated isnt proper. Can anyone help me out on this?

I think you're using the code in this documentation ? While IoT Hub does expose an EventHub, this is not the correct SAS Token to call the API.

You can use the Java SDK to generate your token. If you insist on writing the code yourself, this class holds the code you're looking for. The class will retrieve the values you need from a service connection string, but you can easily leave that out. A connection string just has the values you also have:

HostName=<hub-name>;SharedAccessKeyName=<policy-name>;SharedAccessKey=<access-key>

The class I linked extracts the values from that string and uses them in the private String buildToken() method, that method contains the code you're re-implementing.

Please also note, in your question you were using https://<iot-hub-name>.azure-devices.net as the resource name, for this token (just like in the connection string), you can leave out the https://

To complete my answer, you can change the constructor to this and you will have your token:

public IotHubServiceSasToken(String hubName, String keyValue, String keyName)
    {            
        this.resourceUri = hubName;
        this.keyValue = keyValue;
        this.keyName = keyName;
        this.expiryTime = buildExpiresOn();
        this.token =  buildToken();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM