使用SAS令牌连接Azure EventHub

概述

事件中心使用在命名空间和事件中心级别提供的共享访问签名。SAS令牌是从SAS密钥生成的,它是以特定格式编码的URL的SHA哈希。 事件中心可以使用密钥(策略)的名称和令牌重新生成哈希,以便对发送者进行身份验证。通常,为事件发布者创建的SAS令牌只对特定的事件中心具有“发送”权限。

说明

目前关于直接使用SAS方式连接Azure EventHub,官方只是给出了原理性的介绍,并未给出具体的使用示例,下面分别使用Java SDK和Rest API演示其使用方法。


Java Sample
pom.xml
<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-eventhubs</artifactId>
    <version>1.0.2</version>
</dependency>

Code Sample

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.microsoft.azure.eventhubs.*;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Base64;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class SaSCodeSample {

    public static void main(String[] args)
            throws EventHubException, ExecutionException, InterruptedException, IOException {

        //Set parameters
        final String keyName = "RootManageSharedAccessKey";
        final String key = "v47cgE7VHVTnHQUhpWMtRKrrlQEJGVBr42**********";
        final String eventhubNamespace = "yueventhub";
        final String eventhubName = "yutest";
        final String resourceUri = "https://"+eventhubNamespace+".servicebus.chinacloudapi.cn/"+eventhubName;

        final String sasString = GetSASToken(resourceUri,keyName,key);
        final ConnectionStringBuilder connStr = new ConnectionStringBuilder()
                .setSharedAccessSignature(sasString)
                .setEventHubName(eventhubName)
                .setEndpoint(URI.create("sb://"+eventhubNamespace+".servicebus.chinacloudapi.cn"));

        final Gson gson = new GsonBuilder().create();
        final ExecutorService executorService = Executors.newSingleThreadExecutor();

        //Create EventHub Client
        final EventHubClient ehClient = EventHubClient.createSync(connStr.toString(), executorService);

        //Send messages to EventHub

        final int messageOfAccount = 10;
        try {
            for (int i = 0; i < messageOfAccount; i++) {

                String payload = "Message " + Integer.toString(i);
                byte[] payloadBytes = gson.toJson(payload).getBytes(Charset.defaultCharset());
                EventData sendEvent = EventData.create(payloadBytes);
                System.out.println("i : "+ i);
                ehClient.sendSync(sendEvent);
            }

            System.out.println(Instant.now() + ": Send Complete...");
            System.in.read();
        } finally {
            ehClient.closeSync();
            executorService.shutdown();
        }
    }

    //Create SharedAccessSignature
    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=" + URLEncoder.encode(resourceUri, "UTF-8") +"&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);
            Base64.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;
    }
}

Postman Test(使用工具生成JS Code)

var request = require("request");

var options = { method: 'POST',
  url: 'https://yueventhub.servicebus.chinacloudapi.cn/yutest/messages',
  headers: 
   { 'postman-token': 'df23522a-5cf9-7756-5442-de8387557f6f',
     'cache-control': 'no-cache',
     authorization: 'SharedAccessSignature sr=https%3A%2F%2Fyueventhub.servicebus.chinacloudapi.cn%2Fyutest&sig=3c39JXnSD3k2xktNKzRD/d6cBY%2BVg08a**********g%3D&se=1535965635&skn=RootManageSharedAccessKey',
     'content-type': 'text/plain' },
  body: '{ “Location”: “Redmond”, "Temperature":"37.0" }' };

request(options, function (error, response, body) {
  if (error) throw new Error(error);

  console.log(body);
});

参考

Event Hubs service REST

Generate SAS token

azure-event-hubs-java

posted @ 2018-09-03 17:33  taro_秋刀鱼  阅读(918)  评论(0编辑  收藏  举报