com.microsoft.azure.iot.service.auth.IotHubServiceSasToken Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of iothub-java-service-client Show documentation
Show all versions of iothub-java-service-client Show documentation
The Microsoft Azure IoT Service SDK for Java
/*
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
package com.microsoft.azure.iot.service.auth;
import com.microsoft.azure.iot.service.sdk.IotHubConnectionString;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* Grants device access to an IoT Hub for the specified amount of time.
*/
public final class IotHubServiceSasToken
{
long TOKEN_VALID_SECS = 365*24*60*60;
/**
* The SAS token format. The parameters to be interpolated are, in order:
* the signature
* the resource URI
* the expiry time
* the key name
* Example: {@code SharedAccessSignature sr=IOTHUBURI&sig=SIGNATURE&se=EXPIRY&skn=SHAREDACCESSKEYNAME}
*/
public static final String TOKEN_FORMAT = "SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s";
/* The URI for a connection to an IoT Hub */
protected final String resourceUri;
/* The value of the SharedAccessKey */
protected final String keyValue;
/* The time, as a UNIX timestamp, before which the token is valid. */
protected final long expiryTime;
/* The value of SharedAccessKeyName */
protected final String keyName;
/* The SAS token that grants access. */
protected final String token;
/**
* Constructor. Generates a SAS token that grants access to an IoT Hub for
* the specified amount of time. (1 year specified in TOKEN_VALID_SECS)
*
* @param iotHubConnectionString Connection string object containing the connection parameters
*/
public IotHubServiceSasToken(IotHubConnectionString iotHubConnectionString)
{
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_001: [The constructor shall throw IllegalArgumentException if the input object is null]
if (iotHubConnectionString == null)
{
throw new IllegalArgumentException();
}
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_002: [The constructor shall create a target uri from the url encoded host name)]
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_003: [The constructor shall create a string to sign by concatenating the target uri and the expiry time string (one year)]
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_004: [The constructor shall create a key from the shared access key signing with HmacSHA256]
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_005: [The constructor shall compute the final signature by url encoding the signed key]
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_006: [The constructor shall concatenate the target uri, the signature, the expiry time and the key name using the format: "SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s"]
this.resourceUri = iotHubConnectionString.getHostName();
this.keyValue = iotHubConnectionString.getSharedAccessKey();
this.keyName = iotHubConnectionString.getSharedAccessKeyName();
this.expiryTime = buildExpiresOn();
this.token = buildToken();
}
/**
* Helper function to build the token string
*
* @return Valid token string
*/
private String buildToken()
{
String targetUri;
try
{
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_002: [The constructor shall create a target uri from the url encoded host name)]
targetUri = URLEncoder.encode(this.resourceUri.toLowerCase(), String.valueOf(StandardCharsets.UTF_8));
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_003: [The constructor shall create a string to sign by concatenating the target uri and the expiry time string (one year)]
String toSign = targetUri + "\n" + this.expiryTime;
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_004: [The constructor shall create a key from the shared access key signing with HmacSHA256]
// Get an hmac_sha1 key from the raw key bytes
byte[] keyBytes = Base64.decodeBase64(this.keyValue.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);
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_005: [The constructor shall compute the final signature by url encoding the signed key]
// Compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8"));
// Convert raw bytes to Hex
String signature = URLEncoder.encode(
Base64.encodeBase64String(rawHmac), "UTF-8");
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_006: [The constructor shall concatenate the target uri, the signature, the expiry time and the key name using the format: "SharedAccessSignature sr=%s&sig=%s&se=%s&skn=%s"]
String token = String.format(TOKEN_FORMAT, targetUri, signature, this.expiryTime, this.keyName);
return token;
} catch (Exception e)
{
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_007: [The constructor shall throw Exception if building the token failed]
throw new RuntimeException(e);
}
}
/**
* Helper function to calculate token expiry
*
* @return Seconds from now to expiry
*/
private long buildExpiresOn()
{
long expiresOnDate = System.currentTimeMillis();
expiresOnDate += TOKEN_VALID_SECS * 1000;
return expiresOnDate / 1000;
}
/**
* Returns the string representation of the SAS token.
*
* @return The string representation of the SAS token.
*/
@Override
public String toString()
{
// Codes_SRS_SERVICE_SDK_JAVA_IOTHUBSERVICESASTOKEN_12_008: [The constructor shall return with the generated token]
return this.token;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy