Skip to content

Instantly share code, notes, and snippets.

@ridomin
Created August 11, 2022 17:58
Show Gist options
  • Save ridomin/0800001605716ae614f49614a64724c2 to your computer and use it in GitHub Desktop.
Save ridomin/0800001605716ae614f49614a64724c2 to your computer and use it in GitHub Desktop.
IoTHub Device Http Client in one file
namespace DeviceHttpDemo;
public class Config
{
public string host = "";
public string did = "";
public string key = "";
}
internal class SasAuth
{
const string apiversion_2020_09_30 = "2020-09-30";
internal static string GetUserName(string hostName, string deviceId) =>
$"{hostName}/{deviceId}/?api-version={apiversion_2020_09_30}";
internal static string CreateSasToken(string resource, string sasKey, int minutes)
{
static string Sign(string requestString, string key)
{
using var algorithm = new System.Security.Cryptography.HMACSHA256(Convert.FromBase64String(key));
return Convert.ToBase64String(algorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(requestString)));
}
var expiry = DateTimeOffset.UtcNow.AddMinutes(minutes).ToUnixTimeSeconds().ToString();
var sig = System.Net.WebUtility.UrlEncode(Sign($"{resource}\n{expiry}", sasKey));
return $"SharedAccessSignature sr={resource}&sig={sig}&se={expiry}";
}
internal static (string username, string password) GenerateHubSasCredentials(string hostName, string deviceId, string sasKey,int minutes = 60) =>
(GetUserName(hostName, deviceId), CreateSasToken($"{hostName}/devices/{deviceId}", sasKey, minutes));
}
internal class IoTHubHttpClient
{
readonly Config _config;
public IoTHubHttpClient(Config c) => _config = c;
static string? ToJson(object o) => (o is string) ? o as string : System.Text.Json.JsonSerializer.Serialize(o);
public async Task<HttpResponseMessage> SendTelemetryAsync(object payload, string compo = "")
{
(_, string token) = SasAuth.GenerateHubSasCredentials(_config.host, _config.did, _config.key);
string urlTelemetry = $"https://{_config.host}/devices/{_config.did}/messages/events?api-version=2020-09-30";
var req = new HttpRequestMessage(HttpMethod.Post, urlTelemetry)
{
Headers = { { "authorization", token } }
};
if (!string.IsNullOrEmpty(compo))
{
req.Headers.Add("dt-subject", compo);
}
var serializedPayload = ToJson(payload);
if (serializedPayload != null)
{
req.Content = new StringContent(serializedPayload, System.Text.Encoding.UTF8, "application/json");
}
return await new HttpClient().SendAsync(req);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment