I have a Service Bus Relay (WCF SOAP) I want to consume in my Windows Store App. I have written the code to create a token as well as the client which is below.
The problem is that I get an AuthorizationFailedFault returned with a faultstring "InvalidSignature: The token has an invalid signature." And I can't figure it out.
My Create Token method:
private static string CreateSasToken() { TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970,1, 1); var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); string stringToSign = webUtility.UrlEncode(ServiceUri.AbsoluteUri) + "\n" + expiry; string hashKey = Encoding.UTF8.GetBytes(Secret).ToString(); MacAlgorithmProvider macAlgorithmProvider = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256); BinaryStringEncoding encoding = BinaryStringEncoding.Utf8; var messageBuffer = CryptographicBuffer.ConvertStringToBinary(stringToSign,encoding); IBuffer keyBuffer = CryptographicBuffer.ConvertStringToBinary(hashKey,encoding); CryptographicKey hmacKey = macAlgorithmProvider.CreateKey(keyBuffer); IBuffer signedMessage = CryptographicEngine.Sign(hmacKey, messageBuffer); string signature = CryptographicBuffer.EncodeToBase64String(signedMessage); var sasToken = String.Format(CultureInfo.InvariantCulture, "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", WebUtility.UrlEncode(ServiceUri.AbsoluteUri), WebUtility.UrlEncode(signature), expiry, Issuer); return sasToken; }
My Client class:
public partial class ServiceClient { public async Task<string> GetDataUsingDataContract(string item, string sasToken) { HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("ServiceBusAuthorization",sasToken); client.DefaultRequestHeaders.Add("SOAPAction",".../GetDataUsingDataContract"); client.DefaultRequestHeaders.Add("Host", "xxxxxxxxxxx.servicebus.windows.net"); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post,ServiceUri); var content =new StringContent(@"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/""><s:Header></s:Header><s:Body>"+ item +@"</s:Body></s:Envelope>",System.Text.Encoding.UTF8,"application/xml"); request.Content = content; HttpResponseMessage wcfResponse = client.SendAsync(request).Result; HttpContent stream = wcfResponse.Content; var response = stream.ReadAsStringAsync(); var returnPacket = response.Result; return returnPacket; } }I have been successful consuming the Relay using Http (via Fiddler) by copying an unexpired token created by Micorosft.ServiceBus in a console app.
John Donnelly