I'm having issue with configuring OAuth 2.0 with external authorization.
The scenario I want to implement is simple and straightforward. I want to integrate Apigee with existing backend authentication and authorization service that implements OAuth 2.0 flows while keeping client_id / client_secret validation on Apigee.
I took the policy configuration from Using third-party OAuth tokens as basis for a reverse-proxy setup.
The API proxy has two flows: /authorization and /token.
The /authorization proxy flow loads related app info and redirects user agent to auth server login page.
<Flow name="authorize"> <Description/> <Request> <Step> <Name>Get-OAuth-v20-Info-1</Name> </Step> <Step> <Name>Access-To-Application-Entity</Name> </Step> <Step> <Name>Extract-App-Name-from-Entity</Name> </Step> <Step> <Name>Redirect-To-Login</Name> </Step> </Request> <Response/> <Condition>(proxy.pathsuffix MatchesPath "/authorize") and (request.verb = "GET")</Condition> </Flow>
The /token target flow is implemented as pass-through flow to backend auth server token endpoint. There are policies in response flow to parse server response, extract access and refresh token and store both in Apigee.
<Flow name="token"> <Description>token</Description> <Request/> <Response> <Step> <Name>Set-External-OAuth-Status</Name> </Step> <Step> <Name>Extract-Code</Name> </Step> <Step> <Name>Set-OAuth-Tokens</Name> </Step> </Response> <Condition>(proxy.pathsuffix MatchesPath "/token")</Condition> </Flow>
Extract-Code policy definition:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Code"> <DisplayName>Extract Code</DisplayName> <Properties/> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <JSONPayload> <Variable name="access_token"> <JSONPath>$.access_token</JSONPath> </Variable> <Variable name="refresh_token"> <JSONPath>$.refresh_token</JSONPath> </Variable> </JSONPayload> <Source clearPayload="false">message</Source> <VariablePrefix>apigee</VariablePrefix> </ExtractVariables>
Set-OAuth-Token policy definition:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <OAuthV2 name="Set-OAuth-Tokens" enabled="true" continueOnError="false" async="false"> <DisplayName>Set OAuth Tokens</DisplayName> <ExternalAuthorization>true</ExternalAuthorization> <Operation>GenerateAccessToken</Operation> <ReuseRefreshToken>false</ReuseRefreshToken> <SupportedGrantTypes> <GrantType>authorization_code</GrantType> <GrantType>client_credentials</GrantType> </SupportedGrantTypes> <GenerateResponse enabled="true"> <Format>FORM_PARAM</Format> </GenerateResponse> <ExternalAccessToken>apigee.access_token</ExternalAccessToken> <ExternalRefreshToken>apigee.refresh_token</ExternalRefreshToken> <StoreToken>true</StoreToken> <Tokens/> </OAuthV2>
Pretty much the same as config from doc page.
Yet call to /token endpoint fails with 400 error code. OAuth 2.0 policy generates the error with body content:
{"ErrorCode" : "invalid_request", "Error" :"Invalid Authorization Code"}
The question is - what is the reason of the issue? How could I configure the proxy and / or policies to get it working?
Let me know if some info is missing.
Thanks in advance!