The OpenID Provider in this case is … Azure AD?
Which actor is Apigee? The “Relying party”?
There is something not quite aligned, I think. You said
as per the sequence I am able to get the ID token, access token and…
If you (the Relying Party) are able to get the ID token and access token, then the OIDC flow is complete. That step falls AFTER the verification of the authorization code to the OpenID Connect provider. So there is no need to check any authorization code, if you already have the ID token and access_token.
trying to validate it but OAuthV2 policy is failing with 400.
Not clear which token you are trying to validate. I suppose the ID token is a JWT, since this is an OIDC flow. You can validate a JWT with VerifyJWT policy in Apigee, and you cannot validate a JWT with the OAuth2 policy. though… in the flow depicted in this diagram, there is not much need to validate the token, since the Relying Party JUST GOT the token from the OpenID Connect provider. There’s no real need to validate it RIGHT THEN. It came directly from the provider, it’s going to be valid.
Then there is the other token, the access token. In some cases this is a JWT, in which case, the same applies. 1. You can validate it with the VerifyJWT policy, not the OAuth2 policy, and 2. you don’t need to validate it AT THAT TIME. Some OIDC providers issue opaque access_tokens, and in that case, statement #1 does not apply, but #2 does apply.
In no case can you expect to use the OAuth2 policy to verify or validate a token (JWT or opaque) that you obtained from a third-party OIDC provider, like Azure AD. The OAuthV2 policy in Apigee is a multi-purpose policy. Check the documentation for full details. It CAN be used for
- generating a new opaque token
- validating/verifying an existing opaque token that was issued by Apigee
- generating an authorization code (for use within authorization code grant)
- refreshing an access_token
It IS possible to import an opaque token that has been generated by an external system, like Azure, into Apigee. In which case, you could use the OAuthV2 policy to verify that token. It seems like you’re trying to do that, judging from the policy configuration you showed, which has the ExternalAccessToken element.
But if you use the policy that way, for authorization_code grant… then… Apigee checks the authorization code, and the code must be one that Apigee itself has generated! If you get an authorization code from Azure, that’s not known by Apigee. Therefore using OAuthV2/GenerateAccessToken with GrantType authorization_code, passing in a code that is generated by Azure, will not work. It will always fail with 400 “invalid authorization code”. Apigee doesn’t know about Azure’s codes.
I think you can avoid the entire issue though; the authorization code is there to support the 3-legged dance, which … at this point is complete. You don’t need authorization_code grant type in Apigee. You used the authorization_code grant type with Azure (OIDC provider) but for importing the Azure-generated token into Apigee, you can use client_credentials grant_type and attach the user attributes to that Apigee-generated token.
That’s what I would do.
<OAuthV2 name="Oauth2.ImportAccessToken">
<ExternalAuthorization>true</ExternalAuthorization>
<Operation>GenerateAccessToken</Operation>
<!--
ExpiresIn, in milliseconds. The ref is optional. The explicitly
specified value is the default, when the variable reference
cannot be resolved. eg,
2400000 = 40 minutes
3600000 = 60 minutes
-->
<ExpiresIn ref='flow.variable'>1800000</ExpiresIn>
<ClientId>request.formparam.client_id</ClientId>
<ReuseRefreshToken>false</ReuseRefreshToken>
<SupportedGrantTypes>
<GrantType>client_credentials</GrantType>
</SupportedGrantTypes>
<GrantType>request.formparam.grant_type</GrantType>
<GenerateResponse enabled="true"/>
<ExternalAccessToken>externalAccessToken</ExternalAccessToken>
<StoreToken>true</StoreToken>
<Attributes>
<Attribute name='username' ref='flow.variable' display='true'/>
</Attributes>
</OAuthV2>
You need to set request.formparam.grant_type to client_credentials, and also set the Authorizationheader with the right basic auth value, prior to invoking this policy, in order for it to work.
The result will be the token issued by Azure, will be imported into Apigee, so that in the future, an OAuthV2/VerifyAccessToken will work with that opaque Azure-generated token.