internal void AuthenticateCore(IHttpRequest request, IClientApiKey apiKey, DateTimeOffset now) { request.Headers.Add(StormpathDateHeaderName, Iso8601.Format(now, withSeparators: false)); var authorizationHeaderContent = $"{apiKey.GetId()}:{apiKey.GetSecret()}"; var authorizationHeaderEncrypted = Base64.Encode(authorizationHeaderContent, Encoding.UTF8); request.Headers.Authorization = new AuthorizationHeaderValue("Basic", authorizationHeaderEncrypted); }
internal static void ThrowIfJwtSignatureInvalid(string jwtApiKey, IClientApiKey clientApiKey, IJwt jwt) { if (!clientApiKey.GetId().Equals(jwtApiKey, StringComparison.InvariantCultureIgnoreCase)) { throw new JwtSignatureException("The client used to sign the response is different than the one used in this DataStore."); } var signingKey = Encoding.UTF8.GetBytes(clientApiKey.GetSecret()); if (!new JwtSignatureValidator(signingKey).IsValid(jwt)) { throw new JwtSignatureException("The JWT signature is invalid."); } }
internal void AuthenticateCore(IHttpRequest request, IClientApiKey apiKey, DateTimeOffset now, string nonce) { if (request == null) { throw new RequestAuthenticationException("Request must not be null."); } if (string.IsNullOrEmpty(request.CanonicalUri?.ToString())) { throw new RequestAuthenticationException("URL must not be empty."); } var uri = request.CanonicalUri.ToUri(); if (!uri.IsAbsoluteUri) { throw new RequestAuthenticationException("URL must be an absolute path."); } var relativeResourcePath = uri.AbsolutePath; var timestamp = Iso8601.Format(now, withSeparators: false); var dateStamp = now.ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture); // Add HOST header before signing var hostHeader = uri.Host; if (!uri.IsDefaultPort) { hostHeader = $"{hostHeader}:{uri.Port}"; } request.Headers.Host = hostHeader; // Add X-Stormpath-Date before signing request.Headers.Add(StormpathDateHeaderName, timestamp); var requestBody = request.Body.Nullable() ?? string.Empty; var requestBodyHash = ToHex(Hash(requestBody, Encoding.UTF8)); var sortedHeaderKeys = GetSortedHeaderNames(request.Headers); var canonicalRequest = new StringBuilder() .Append(request.Method.ToString().ToUpper()) .Append(Newline) .Append(CanonicalizeResourcePath(relativeResourcePath)) .Append(Newline) .Append(request.CanonicalUri.QueryString.ToString(canonical: true)) .Append(Newline) .Append(CanonicalizeHeaders(request)) .Append(Newline) .Append(sortedHeaderKeys) .Append(Newline) .Append(requestBodyHash) .ToString(); var id = new StringBuilder() .Append(apiKey.GetId()).Append("/") .Append(dateStamp).Append("/") .Append(nonce).Append("/") .Append(IDTerminator) .ToString(); var canonicalRequestHash = ToHex(Hash(canonicalRequest, Encoding.UTF8)); var stringToSign = new StringBuilder() .Append(Algorithm) .Append(Newline) .Append(timestamp) .Append(Newline) .Append(id) .Append(Newline) .Append(canonicalRequestHash) .ToString(); var secretFormat = $"{AuthenticationScheme}{apiKey.GetSecret()}"; byte[] secret = Encoding.UTF8.GetBytes(secretFormat); byte[] signedDate = SignHmac256(dateStamp, secret, Encoding.UTF8); byte[] signedNonce = SignHmac256(nonce, signedDate, Encoding.UTF8); byte[] signedTerminator = SignHmac256(IDTerminator, signedNonce, Encoding.UTF8); byte[] signature = SignHmac256(stringToSign, signedTerminator, Encoding.UTF8); var signatureHex = ToHex(signature); var authorizationHeaderValue = new StringBuilder() .Append(SAUTHC1Id).Append("=").Append(id).Append(", ") .Append(SAUTHC1SignedHeaders).Append("=").Append(sortedHeaderKeys).Append(", ") .Append(SAUTHC1Signature).Append("=").Append(signatureHex) .ToString(); request.Headers.Authorization = new AuthorizationHeaderValue(AuthenticationScheme, authorizationHeaderValue); }