Generate Azure SAS Token on Android

白昼怎懂夜的黑 提交于 2019-12-04 16:03:41

问题


Trying to generate Azure SAS token in order to be able to use Service Bus REST Api.

Found this link:

http://blog.simontimms.com/2015/01/30/sending-message-to-azure-service-bus-using-rest/

How to achieve the same on Android?

My Current attempt looks like this:

private String generateSasToken(String uri, String keyName, String key){
    String ret = "";

    long tokenExpirationTime = (System.currentTimeMillis() / 1000) + (10 * 365 * 24 * 60 * 60);

    try {
        String stringToSign = new URL(uri).toString() + "\n" + tokenExpirationTime;
        SecretKey secretKey = null;

        byte[] keyBytes = key.getBytes("UTF-8");

        Mac mac = Mac.getInstance("HMACSHA256");

        secretKey = new SecretKeySpec(keyBytes, mac.getAlgorithm());

        mac.init(secretKey);

        String signature = Base64.encodeToString(mac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT);
        ret = String.format("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s",
                URLEncoder.encode(uri),
                URLEncoder.encode(signature),
                String.valueOf(tokenExpirationTime),
                keyName);
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    return ret;
}

After calling the Rest API of service bus using Postman i get the following :

401 40103: Invalid authorization token signature Time 261 ms


Update: Found this link

https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-android-get-started/

Under section 6 the code for android


回答1:


I have no Android environment to test, I have a similar scenario in only java environment, it works fine, the following is my code:

private static String generateSasToken(String uri, String keyName, String key){
        String ret = "";

       // long tokenExpirationTime = (System.currentTimeMillis() / 1000) + (10 * 365 * 24 * 60 * 60);

        Date now = new Date();
        Date previousDate=new Date(1970);
        long tokenExpirationTime = ((now.getTime() - previousDate.getTime()) / 1000 )+3600;

        try {
            String stringToSign = URLEncoder.encode(new URL(uri).toString(),java.nio.charset.StandardCharsets.UTF_8.toString()) + "\n" + tokenExpirationTime;

            System.out.println(stringToSign);
            SecretKey secretKey = null;

            byte[] keyBytes = key.getBytes("UTF-8");

            Mac mac = Mac.getInstance("HMACSHA256");

            secretKey = new SecretKeySpec(keyBytes, mac.getAlgorithm());

            mac.init(secretKey);

            byte[] digest = mac.doFinal(stringToSign.getBytes());
            //We then use the composite signing key to create an oauth_signature from the signature base string
            String signature = Base64.encodeBase64String(digest);
            System.out.println( URLEncoder.encode(signature, java.nio.charset.StandardCharsets.UTF_8.toString()));
           // String signature = Base64.encodeBase64String(mac.doFinal(stringToSign.getBytes("UTF-8")));
            ret = String.format("SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s",
                    URLEncoder.encode(uri, java.nio.charset.StandardCharsets.UTF_8.toString()),
                    URLEncoder.encode(signature, java.nio.charset.StandardCharsets.UTF_8.toString()),
                    String.valueOf(tokenExpirationTime),
                    keyName);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return ret;
    }

I have changed two places, 1) the tokenExpirationTime 2) URLEncoder.encode the String stringTosign, please try with my suggestion, hope this could give you some tips.




回答2:


I don't know if this helps you, but here is an example in C#:

class Program
{

    static void Main(string[] args)
    {

        var sasToken = createToken("yournamespace.servicebus.windows.net”,  
           "device_send_listen", "xxxxxxx");
    }

    private static string createToken(string resourceUri, string keyName, string key)
    {

        TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
        var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //EXPIRES in 1h 
        string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
        HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
        var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        var sasToken = String.Format(CultureInfo.InvariantCulture,
        "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
            HttpUtility.UrlEncode(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);

        return sasToken;
    }
}


来源:https://stackoverflow.com/questions/31180367/generate-azure-sas-token-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!