Exemple #1
0
        private void ThrowIfTimestampNotVerified(string timestampStr)
        {
            var challengeTimestamp = OAuthServerHelper.ParseDateTime(timestampStr);

            if (challengeTimestamp + MaxChallengeAge < SystemTime.UtcNow || challengeTimestamp > SystemTime.UtcNow)
            {
                throw new InvalidOperationException(
                          "The challenge is either too old or from the future in 'ChallengeResponse' message" +
                          $"challengeTimestamp={challengeTimestamp}, MaxChallengeAge={MaxChallengeAge}, SystemTime.UtcNow={SystemTime.UtcNow}");
            }
        }
Exemple #2
0
        private async Task <AccessToken> ProcessToken(JsonOperationContext context, WebSocket webSocket)
        {
            using (var reader = await context.ReadFromWebSocket(webSocket, DebugTag, ServerStore.ServerShutdown))
            {
                var requestContents = ExtractChallengeResponse(reader);

                var encryptedData = ExtractEncryptedData(requestContents);

                var challengeDictionary = OAuthHelper.ParseDictionary(OAuthServerHelper.DecryptAsymmetric(encryptedData));

                var apiKeyName = challengeDictionary.GetOrDefault(OAuthHelper.Keys.APIKeyName);
                var challenge  = challengeDictionary.GetOrDefault(OAuthHelper.Keys.Challenge);
                var response   = challengeDictionary.GetOrDefault(OAuthHelper.Keys.Response);

                if (string.IsNullOrEmpty(apiKeyName) || string.IsNullOrEmpty(challenge) || string.IsNullOrEmpty(response))
                {
                    throw new InvalidOperationException(
                              "Got null or empty apiKeyName/challenge/response in 'ChallengeResponse' message");
                }

                var challengeData = OAuthHelper.ParseDictionary(OAuthServerHelper.DecryptSymmetric(challenge));

                var timestampStr = challengeData.GetOrDefault(OAuthHelper.Keys.ChallengeTimestamp);

                if (string.IsNullOrEmpty(timestampStr))
                {
                    throw new InvalidOperationException("Got null or empty encryptedData in 'ChallengeResponse' message");
                }

                ThrowIfTimestampNotVerified(timestampStr);

                string secret;
                var    accessToken = BuildAccessTokenAndGetApiKeySecret(apiKeyName, out secret);

                var expectedResponse = OAuthHelper.Hash(string.Format(OAuthHelper.Keys.ResponseFormat, challenge, secret));

                if (response != expectedResponse)
                {
                    if (_logger.IsInfoEnabled)
                    {
                        _logger.Info($"Failure to authenticate api key {apiKeyName}");
                    }
                    return(null);
                }
                return(accessToken);
            }
        }
Exemple #3
0
        private async Task SendInitialChallenge(WebSocket webSocket)
        {
            var challengeData = new Dictionary <string, string>
            {
                { OAuthHelper.Keys.ChallengeTimestamp, OAuthServerHelper.DateTimeToString(SystemTime.UtcNow) },
                {
                    OAuthHelper.Keys.ChallengeSalt,
                    OAuthHelper.BytesToString(OAuthServerHelper.RandomBytes(OAuthHelper.Keys.ChallengeSaltLength))
                }
            };

            var json = new DynamicJsonValue
            {
                [OAuthHelper.Keys.RSAExponent] = OAuthServerHelper.RSAExponent,
                [OAuthHelper.Keys.RSAModulus]  = OAuthServerHelper.RSAModulus,
                [OAuthHelper.Keys.Challenge]   =
                    OAuthServerHelper.EncryptSymmetric(OAuthHelper.DictionaryToString(challengeData))
            };

            await SendResponse(webSocket, json).ConfigureAwait(false);
        }