Partager via


Concepts courants

 

Analyser la chaîne de connexion

Pour accéder à un concentrateur de notification, vous devez disposer de deux informations : le nom du concentrateur (qui peut être un chemin d'accès tel que « a/b/c ») et une chaîne de connexion. La chaîne de connexion contient des informations sur le point de terminaison de votre concentrateur et les informations d'identification de sécurité permettant d'y accéder (dans le cas de SAP, il contient un nom de règle et une valeur de clé).

Le code suivant analyse la chaîne de connexion pour extraire les informations pertinentes :

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

Créer des associations de sécurité jeton de sécurité

Pour s'authentifier à l'aide de SAS, un client doit spécifier un jeton SAS dans le Authorization en-tête de leurs requêtes. Le jeton est construit à partir des informations extraites de la chaîne de connexion et de la demande actuelle qui doit être authentifiée. Le jeton a la forme suivante :

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

Notez que le jeton fait référence à un keyName (pour envoyer des notifications, vous utilisez généralement le DefaultFullSharedAccessSignature propriété qui est créée automatiquement sur tous les concentrateurs de notification).

La signature du jeton SAP est calculée à l'aide de la HMAC-SHA256 d'une valeur de chaîne de connexion avec le PrimaryKey propriétés d'une règle d'autorisation. La valeur de chaîne de signature se compose d'un URI de ressource et un délai d'expiration, le format suivant :

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

Notez que vous devez utiliser l'URI de ressource non codé pour cette opération. L'URI de ressource est l'URI complet de le Service Bus les ressources auxquelles l'accès est demandé. Le formulaire est comme suit :

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

Par exemple :

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

L'échéance est représentée par le nombre de secondes depuis l'époque 00:00:00 UTC le 1er janvier 1970.

La règle de l'autorisation d'accès partagé utilisée pour la signature doit être configurée sur l'entité spécifiée par cet URI. Dans l'exemple précédent, c'est http://contoso.servicebus.windows.net/myHub ou http://contoso.servicebus.windows.net.

L'URL encodée resourceURI doit être le même que l'URI utilisé dans la chaîne de connexion lors du traitement de la signature. Il doit être codés en pourcentage et en minuscules.

Le code suivant, étant donné un URI de demande, crée un jeton SAP. La version Java utilise Apache Commons Codec et la version Javascript utilise 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; };