Compartir a través de


Conceptos comunes

 

Analizar la cadena de conexión

Para obtener acceso a un centro de notificaciones, debe disponer de dos piezas de información: el nombre del centro (puede ser una ruta de acceso como "a, b y c") y una cadena de conexión. La cadena de conexión contiene información sobre el extremo de su centro y las credenciales de seguridad que se utilizan para tener acceso a él (en el caso de 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 relevante:

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); } } }  
  
String[] parts = connectionString.split(";"); if (parts.length != 3) throw new RuntimeException("Error parsing connection string: " + connectionString); for (int i = 0; i < parts.length; i++) { if (parts[i].startsWith("Endpoint")) { this.endpoint = "https" + parts[i].substring(11); } else if (parts[i].startsWith("SharedAccessKeyName")) { this.SasKeyName = parts[i].substring(20); } else if (parts[i].startsWith("SharedAccessKey")) { this.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); } });  

Crear SAS Token de seguridad

Para autenticar mediante SAS, un cliente debe especificar un token SAS en el Authorization encabezado 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 tiene que autenticarse. El token tiene el formato siguiente:

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

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

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

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

Tenga en cuenta que debe usar el URI del recurso sin codificar para esta operación. El URI de recurso es el URI completo de la CmdLets a la que se notifica el acceso de recursos. El formato es como sigue:

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

Por ejemplo:

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

La expiración se representa como el número de segundos transcurridos desde la época 00:00:00 UTC de 1 de enero de 1970.

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

La codificación URL resourceURI debe ser el mismo que el URI usado en la cadena para firmar durante el cálculo de la firma. Debería ser codificados con porcentaje y en minúsculas.

El código siguiente, dado un URI de solicitud, crea un token SAS. La versión de Java usa Apache Commons Codec 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; } }  
  
private String generateSasToken(URI uri) { String targetUri; try { targetUri = URLEncoder .encode(uri.toString().toLowerCase(), "UTF-8") .toLowerCase(); long expiresOnDate = System.currentTimeMillis(); int expiresInMins = 60; // 1 hour expiresOnDate += expiresInMins * 60 * 1000; long expires = expiresOnDate / 1000; String toSign = targetUri + "\n" + expires; // Get an hmac_sha1 key from the raw key bytes byte[] keyBytes = SasKeyValue.getBytes("UTF-8"); SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256"); // Get an hmac_sha1 Mac instance and initialize with the signing key Mac mac = Mac.getInstance("HmacSHA256"); mac.init(signingKey); // Compute the hmac on input data bytes byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8")); // using Apache commons codec for base64 String signature = URLEncoder.encode( Base64.encodeBase64String(rawHmac), "UTF-8"); // construct authorization string String token = "SharedAccessSignature sr=" + targetUri + "&sig=" + signature + "&se=" + expires + "&skn=" + SasKeyName; return token; } catch (Exception e) { throw new RuntimeException(e); } }  
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; };