private SecureString GetAppSecret(string appId) { SecureString secret = appSecretProvider.GetSecret(appId); if (secret == null || secret.Length == 0) { throw new HmacAuthenticationException($"App secret key not found: '{appId}'"); } return(secret); }
protected override async Task <HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { var req = request; var h = req.Headers; if (mixedAuthMode && h.Authorization?.Scheme != Schemas.HMAC) { return(await base.SendAsync(request, cancellationToken)); } var appId = h.Contains(Headers.XAppId) ? h.GetValues(Headers.XAppId).FirstOrDefault() : null; var authValue = h.Authorization?.Parameter; var date = h.Date ?? DateTimeOffset.MinValue; if (appId != null && authValue != null && time.UtcNow - date <= tolerance) { var builder = new CannonicalRepresentationBuilder(); var content = builder.BuildRepresentation( h.GetValues(Headers.XNonce).FirstOrDefault(), appId, req.Method.Method, req.Content.Headers.ContentType?.ToString(), string.Join(", ", req.Headers.Accept), req.Content.Headers.ContentMD5, date, req.RequestUri); SecureString secret; if (content != null && (secret = appSecretRepository.GetSecret(appId)) != null) { var signature = signingAlgorithm.Sign(secret, content); if (authValue == signature) { return(await base.SendAsync(request, cancellationToken)); } } } return(new HttpResponseMessage(HttpStatusCode.Unauthorized) { Headers = { { Headers.WWWAuthenticate, Schemas.HMAC } } }); }
public override async Task Invoke(IOwinContext context) { var req = context.Request; var res = context.Response; var h = req.Headers; var appId = h.Get(Headers.XAppId); var auth = h.Get(Headers.Authorization)?.Split(' '); var authSchema = auth?.Length == 2 ? auth[0] : null; var authValue = auth?.Length == 2 ? auth[1] : null; DateTimeOffset date = DateTimeOffset.TryParse(h.Get(Headers.Date), out date) ? date : DateTimeOffset.MinValue; if (appId != null && authSchema == Schemas.HMAC && authValue != null && time.UtcNow - date <= tolerance) { var builder = new CannonicalRepresentationBuilder(); var content = builder.BuildRepresentation( h.Get(Headers.XNonce), appId, req.Method, req.ContentType, req.Accept, Convert.FromBase64String(h.Get(Headers.ContentMD5)), date, req.Uri); SecureString secret; if (content != null && (secret = appSecretRepository.GetSecret(appId)) != null) { var signature = signingAlgorithm.Sign(secret, content); if (authValue == signature) { await Next.Invoke(context); return; } } } res.StatusCode = 401; res.Headers.Append(Headers.WWWAuthenticate, Schemas.HMAC); }
internal static bool Validate(IOwinRequest req, ISigningAlgorithm algorithm, IAppSecretRepository appSecretRepository, ITime time, TimeSpan tolerance) { var h = req.Headers; var appId = GetAppId(req); var nonce = GetNonce(req); var auth = h.Get(Headers.Authorization)?.Split(' '); var authSchema = auth?.Length == 2 ? auth[0] : null; var authValue = auth?.Length == 2 ? auth[1] : null; DateTimeOffset date = DateTimeOffset.TryParse(h.Get(Headers.Date), out date) ? date : DateTimeOffset.MinValue; if (appId != null && authSchema == Schemas.HMAC && authValue != null && time.UtcNow - date <= tolerance) { var contentMd5 = h.Get(Headers.ContentMD5); var builder = new CannonicalRepresentationBuilder(); var content = builder.BuildRepresentation( nonce, appId, req.Method, req.ContentType, req.Accept, contentMd5 == null ? null : Convert.FromBase64String(contentMd5), date, req.Uri); SecureString secret; if (content != null && (secret = appSecretRepository.GetSecret(appId)) != null) { var signature = algorithm.Sign(secret, content); if (authValue == signature) { return(true); } } } return(false); }