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);
        }
Esempio n. 2
0
        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 }
                }
            });
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }