Compartir a través de


Conceptos comunes

En este artículo se proporcionan conceptos comunes al desarrollar aplicaciones que usan la API REST de Azure Notification Hubs.

Nota:

Para garantizar un mayor nivel de seguridad, Notification Hubs deshabilitará la compatibilidad con las versiones 1.0 y 1.1 de TLS el 30 de abril de 2020. Para más información, consulte Seguridad de la capa de transporte (TLS) en la documentación de Azure Notification Hubs.

Analizar la cadena de conexión

Para acceder a un centro de notificaciones, debe tener dos partes de información: el nombre del centro y una cadena de conexión. La cadena de conexión contiene información sobre el punto de conexión del centro de conectividad y las credenciales de seguridad usadas para acceder a ella (para SAS, contiene un nombre de regla y un valor de clave).

El código siguiente analiza la cadena de conexión para extraer la información pertinente:

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);
}
});

Creación de un token de seguridad de SAS

Para autenticarse mediante SAS, un cliente debe especificar un token de SAS en el encabezado de autorización de sus solicitudes. El token se construye a partir de la información extraída de la cadena de conexión y la solicitud actual que se debe autenticar. El token tiene el siguiente formato:

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

El token hace referencia a un keyName (para enviar notificaciones, normalmente se usa la propiedad DefaultFullSharedAccessSignature que se crea automáticamente en todos los centros de notificaciones).

La firma del token de SAS se calcula mediante el HMAC-SHA256 de un valor de cadena a signo con la propiedad PrimaryKey de una regla de autorización. El valor de cadena a signo consta de un URI de recurso y una expiración, con el formato siguiente:

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

Use el URI de recursos sin codificar para esta operación. El URI de recurso es el URI completo del recurso de Service Bus al que se solicita el acceso. El formulario es el siguiente:

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

Por ejemplo:

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

La caducidad se representa como el número de segundos transcurridos desde el tiempo base 00:00:00 UTC el 1 de enero de 1970.

La regla de autorización de acceso compartido usada para la firma debe configurarse en la entidad especificada por este URI. En el ejemplo anterior, el URI es http://contoso.servicebus.windows.net/myHub o http://contoso.servicebus.windows.net.

El resourceURI con codificación URL debe ser el mismo que el URI usado en la cadena para firmar durante el cálculo de la firma. Debe estar codificado en porcentaje y en minúsculas.

El código siguiente, dado un URI de solicitud, crea un token de SAS. La versión de Java usa El códec de Apache Commons y la versión de 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;
};