public override async Task <IActionResult> Handle(HandlerContext context, CancellationToken cancellationToken)
        {
            try
            {
                _authorizationCodeGrantTypeValidator.Validate(context);
                var oauthClient = await AuthenticateClient(context, cancellationToken);

                context.SetClient(oauthClient);
                var code            = context.Request.Data.GetAuthorizationCode();
                var previousRequest = await _grantedTokenHelper.GetAuthorizationCode(code, cancellationToken);

                if (previousRequest == null)
                {
                    // https://tools.ietf.org/html/rfc6749#section-4.1.2
                    var searchResult = await _grantedTokenHelper.SearchTokens(new SearchTokenParameter
                    {
                        AuthorizationCode = code
                    }, cancellationToken);

                    if (searchResult.Content.Any())
                    {
                        await _grantedTokenHelper.RemoveTokens(searchResult.Content, cancellationToken);

                        _logger.LogError($"authorization code '{code}' has already been used, all tokens previously issued have been revoked");
                        return(BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_GRANT, ErrorMessages.AUTHORIZATION_CODE_ALREADY_USED));
                    }

                    return(BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_GRANT, ErrorMessages.BAD_AUTHORIZATION_CODE));
                }

                var previousClientId = previousRequest.GetClientId();
                if (!previousClientId.Equals(oauthClient.ClientId, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_REQUEST, ErrorMessages.REFRESH_TOKEN_NOT_ISSUED_BY_CLIENT));
                }

                await _grantedTokenHelper.RemoveAuthorizationCode(code, cancellationToken);

                var scopes = previousRequest.GetScopesFromAuthorizationRequest();
                var result = BuildResult(context, scopes);
                foreach (var tokenBuilder in _tokenBuilders)
                {
                    await tokenBuilder.Refresh(previousRequest, context, cancellationToken);
                }

                _tokenProfiles.First(t => t.Profile == context.Client.PreferredTokenProfile).Enrich(context);
                foreach (var kvp in context.Response.Parameters)
                {
                    result.Add(kvp.Key, kvp.Value);
                }

                return(new OkObjectResult(result));
            }
            catch (OAuthException ex)
            {
                return(BuildError(HttpStatusCode.BadRequest, ex.Code, ex.Message));
            }
        }
        public override async Task <IActionResult> Handle(HandlerContext context)
        {
            try
            {
                _authorizationCodeGrantTypeValidator.Validate(context);
                var oauthClient = await AuthenticateClient(context);

                context.SetClient(oauthClient);
                var code            = context.Request.Data.GetAuthorizationCode();
                var previousRequest = _grantedTokenHelper.GetAuthorizationCode(code);
                if (previousRequest == null)
                {
                    return(BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_REQUEST, ErrorMessages.BAD_AUTHORIZATION_CODE));
                }

                var previousClientId = previousRequest.GetClientId();
                if (!previousClientId.Equals(oauthClient.ClientId, StringComparison.InvariantCultureIgnoreCase))
                {
                    return(BuildError(HttpStatusCode.BadRequest, ErrorCodes.INVALID_REQUEST, ErrorMessages.REFRESH_TOKEN_NOT_ISSUED_BY_CLIENT));
                }

                _grantedTokenHelper.RemoveAuthorizationCode(code);
                var scopes = previousRequest.GetScopesFromAuthorizationRequest();
                var result = BuildResult(context, scopes);
                foreach (var tokenBuilder in _tokenBuilders)
                {
                    await tokenBuilder.Refresh(previousRequest, context).ConfigureAwait(false);
                }

                _tokenProfiles.First(t => t.Profile == context.Client.PreferredTokenProfile).Enrich(context);
                foreach (var kvp in context.Response.Parameters)
                {
                    result.Add(kvp.Key, kvp.Value);
                }

                return(new OkObjectResult(result));
            }
            catch (OAuthException ex)
            {
                return(BuildError(HttpStatusCode.BadRequest, ex.Code, ex.Message));
            }
        }
Exemple #3
0
        public async Task <bool> Handle(AuthenticateInstruction authenticateInstruction, OAuthClient client, string expectedIssuer, CancellationToken cancellationToken)
        {
            var codeVerifier = authenticateInstruction.RequestData.GetCodeVerifier();

            if (string.IsNullOrWhiteSpace(codeVerifier))
            {
                throw new OAuthException(ErrorCodes.INVALID_REQUEST, string.Format(ErrorMessages.MISSING_PARAMETER, TokenRequestParameters.CodeVerifier));
            }

            var code = authenticateInstruction.RequestData.GetAuthorizationCode();

            if (code == null)
            {
                return(false);
            }

            var previousRequest = await _grantedTokenHelper.GetAuthorizationCode(code, cancellationToken);

            if (previousRequest == null)
            {
                return(false);
            }

            var codeChallenge       = previousRequest.GetCodeChallengeFromAuthorizationRequest();
            var codeChallengeMethod = previousRequest.GetCodeChallengeMethodFromAuthorizationRequest();

            if (string.IsNullOrWhiteSpace(codeChallengeMethod))
            {
                codeChallengeMethod = PlainCodeChallengeMethodHandler.DEFAULT_NAME;
            }

            var codeChallengeMethodHandler = _codeChallengeMethodHandlers.First(c => c.Name == codeChallengeMethod);
            var newCodeChallenge           = codeChallengeMethodHandler.Calculate(codeVerifier);

            if (newCodeChallenge != codeChallenge)
            {
                throw new OAuthException(ErrorCodes.INVALID_GRANT, ErrorMessages.BAD_CODE_VERIFIER);
            }

            return(true);
        }