Share via


Concetti comuni

Questo articolo fornisce concetti comuni per lo sviluppo di applicazioni che usano l'API REST di Hub di notifica di Azure.

Nota

Per garantire un livello di sicurezza superiore, Hub di notifica disabiliterà il supporto per tls versioni 1.0 e 1.1 il 30 aprile 2020. Per altre informazioni, vedere Transport Layer Security (TLS) nella documentazione di Hub di notifica di Azure.

Analizzare la stringa di connessione

Per accedere a un hub di notifica, è necessario disporre di due informazioni: il nome dell'hub e una stringa di connessione. La stringa di connessione contiene informazioni sull'endpoint dell'hub e le credenziali di sicurezza usate per accedervi (per la firma di accesso condiviso, contiene un nome di regola e un valore della chiave).

Il codice seguente analizza la stringa di connessione per estrarre le informazioni pertinenti:

public partial class ConnectionStringUtility
{
    public string Endpoint { get; private set; }
    public string SasKeyName { get; private set; }
    public string SasKeyValue { get; private set; }

    public ConnectionStringUtility(string connectionString)
    {
        //Parse Connectionstring
        char[] separator = { ';' };
        string[] parts = connectionString.Split(separator);
        for (int i = 0; i < parts.Length; i++)
        {
            if (parts[i].StartsWith("Endpoint"))
                Endpoint = "https" + parts[i].Substring(11);
            if (parts[i].StartsWith("SharedAccessKeyName"))
                SasKeyName = parts[i].Substring(20);
            if (parts[i].StartsWith("SharedAccessKey"))
                SasKeyValue = parts[i].Substring(16);
        }
    }
}
var parts = connectionString.split(';');
if (parts.length != 3)
throw "Error parsing connection string";

parts.forEach(function(part) {
if (part.indexOf('Endpoint') == 0) {
endpoint = 'https' + part.substring(11);
} else if (part.indexOf('SharedAccessKeyName') == 0) {
sasKeyName = part.substring(20);
} else if (part.indexOf('SharedAccessKey') == 0) {
sasKeyValue = part.substring(16);
}
});

Creare un token di sicurezza della firma di accesso condiviso

Per eseguire l'autenticazione tramite firma di accesso condiviso, un client deve specificare un token di firma di accesso condiviso nell'intestazione Authorization delle richieste. Il token viene costruito dalle informazioni estratte dalla stringa di connessione e dalla richiesta corrente che deve essere autenticata. Il token ha il formato seguente:

SharedAccessSignature sig=<signature-string>&se=<expiry>&skn=<keyName>&sr=<URL-encoded-resourceURI>

Il token fa riferimento a un keyName (per inviare notifiche, in genere si usa la proprietà DefaultFullSharedAccessSignature creata automaticamente in tutti gli hub di notifica).

La firma per il token di firma di accesso condiviso viene calcolata usando HMAC-SHA256 di un valore stringa-to-sign con la proprietà PrimaryKey di una regola di autorizzazione. Il valore da stringa a firma è costituito da un URI della risorsa e da una scadenza, formattato come segue:

StringToSign = <resourceURI> + "\n" + expiry;

Usare l'URI della risorsa non codificata per questa operazione. L'URI di risorsa è l'URI completo della risorsa del bus di servizio a cui si richiede l'accesso. Il modulo è il seguente:

http://<namespace>.servicebus.windows.net/<hubName>

Ad esempio:

http://contoso.servicebus.windows.net/myHub

La scadenza è rappresentata dal numero di secondi trascorsi dalle 00:00:00 UTC dell'1 gennaio 1970.

La regola di autorizzazione di accesso condiviso usata per la firma deve essere configurata nell'entità specificata da questo URI. Nell'esempio precedente l'URI è http://contoso.servicebus.windows.net/myHub o http://contoso.servicebus.windows.net.

L'URI della risorsa con codifica URL deve corrispondere all'URI usato nella stringa da firmare durante il calcolo della firma. Deve essere con codifica percentuale e minuscola.

Il codice seguente, dato un URI di richiesta, crea un token di firma di accesso condiviso. La versione Java usa Apache Commons Codec e la versione Javascript usa CryptoJS.

public partial class ConnectionStringUtility
{
    public string getSaSToken(string uri, int minUntilExpire)
    {
        string targetUri = Uri.EscapeDataString(uri.ToLower()).ToLower();

        // Add an expiration in seconds to it.
        long expiresOnDate = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
        expiresOnDate += minUntilExpire * 60 * 1000;
        long expires_seconds = expiresOnDate / 1000;
        String toSign = targetUri + "\n" + expires_seconds;

        // Generate a HMAC-SHA256 hash or the uri and expiration using your secret key.
        MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256);
        BinaryStringEncoding encoding = BinaryStringEncoding.Utf8;
        var messageBuffer = CryptographicBuffer.ConvertStringToBinary(toSign, encoding);
        IBuffer keyBuffer = CryptographicBuffer.ConvertStringToBinary(SasKeyValue, encoding);
        CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyBuffer);
        IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer);

        string signature = Uri.EscapeDataString(CryptographicBuffer.EncodeToBase64String(signedMessage));

        return "SharedAccessSignature sr=" + targetUri + "&sig=" + signature + "&se=" + expires_seconds + "&skn=" + SasKeyName;
    }
}
var getSelfSignedToken = function(targetUri, sharedKey, ruleId,
expiresInMins) {
targetUri = encodeURIComponent(targetUri.toLowerCase()).toLowerCase();

// Set expiration in seconds
var expireOnDate = new Date();
expireOnDate.setMinutes(expireOnDate.getMinutes() + expiresInMins);
var expires = Date.UTC(expireOnDate.getUTCFullYear(), expireOnDate
.getUTCMonth(), expireOnDate.getUTCDate(), expireOnDate
.getUTCHours(), expireOnDate.getUTCMinutes(), expireOnDate
.getUTCSeconds()) / 1000;
var tosign = targetUri + '\n' + expires;

// using CryptoJS
var signature = CryptoJS.HmacSHA256(tosign, sharedKey);
var base64signature = signature.toString(CryptoJS.enc.Base64);
var base64UriEncoded = encodeURIComponent(base64signature);

// construct autorization string
var token = "SharedAccessSignature sr=" + targetUri + "&sig="
+ base64UriEncoded + "&se=" + expires + "&skn=" + ruleId;
// console.log("signature:" + token);
return token;
};