SaaS Resolve API failing with 403

Alex 41 Reputation points
2020-09-07T16:27:36.227+00:00

Hi, I am trying to test out the SaaS Resolve API to activate a subscription to a marketplace offering my team is developing, using the steps listed here: https://learn.microsoft.com/en-us/azure/marketplace/partner-center-portal/pc-saas-fulfillment-api-v2#resolve-a-purchased-subscription

I am able to find my offering on the marketplace (with our users being the preview audience), and clicking configure account from Azure portal correctly takes me to our SaaS offering landing page with the marketplace token in the URL - (https://my.website/landing-page?token=<ms-token>)

We are then using MSAL library to get the user authorization token, which makes a POST call to https://login.microsoftonline.com/common/oauth2/v2.0/token with the following form data:

client_id: <our Azure App ID>
redirect_uri: https://my.website/landing-page
scope: openid profile
code: <code>
code_verifier: <code_verifier>
grant_type: authorization_code
client_info: 1
client-request-id: 039a3648-53ca-432c-b005-311a777048c7

This returns a 200, and we are then saving the response.accessToken to be used in the SaaS resolve API:

POST https://marketplaceapi.microsoft.com/api/saas/subscriptions/resolve?api-version=2018-08-31

Request Headers:
Authorization: 'Bearer ' + accessToken
Content-Type: application/json
x-ms-marketplace-token: decodeURIComponent(<token in url>),

However, this is returning 403 Forbidden back. Is there any insight into what we are doing wrong? If it helps, the x-ms-requestid response header generated by MS during the resolve subscription request is 0fb4fe86-f4bb-4125-ae42-a4cd18ad098d

Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
19,102 questions
0 comments No comments
{count} vote

Accepted answer
  1. 2020-09-07T18:25:41.563+00:00

    I see you're using the authorization grant flow to request a token but you need to use the client credentials flow as described in Get the token with an HTTP POST.

    --
    Please let us know if this answer was helpful to you. If so, please remember to mark it as the answer so that others in the community with similar questions can more easily find a solution.


2 additional answers

Sort by: Most helpful
  1. Alex 41 Reputation points
    2020-09-07T22:25:48.827+00:00

    Thanks @alfredo-revilla-msft , this is helpful. Looking over the client credentials flow, it looks like the token acquisition is meant to happen on the web server instead of client? I have updated the flow to work as follows:

    1) https://my.website/landing-page?token=\<ms-token> is opened from the Azure Portal subscription manage

    2) The user is redirected to https://login.microsoftonline.com/adminconsent?client_id=\<app-id>&state=12345&redirect_uri=https://my.website/landing-page (from https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#request-the-permissions-from-a-directory-admin)

    3) After logging in successfully, the user is redirected back to https://my.website/landing-page

    4) I then call our server API that proxies to token acquisition on the backend (from https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow#first-case-access-token-request-with-a-shared-secret). Here is the proxy call done from our backend:

    POST https://login.microsoftonline.com/common/oauth2/v2.0/token

    Headers:
    Content-Type: application/x-www-form-urlencoded

    Body:
    grant_type: 'client_credentials',
    client_id: <app-id>,
    client_secret: <app-secret>,
    scope: 'https://graph.microsoft.com/.default'

    This returns an access_token in the response, which I return back to our web client

    5) I call the SaaS resolve API with the bearer token returned above, and the ms token provided in step 1. This still returns 403 forbidden.

    If it's helpful, the generated x-ms-requestid response header value is 001bdd37-0bfe-4760-93bf-834c5297ecb0

    I think I may be misunderstanding the flow still. When I acquire the token server side (step 4), I am not passing through any of the data from steps 2-3, and since this is server side none of the client side login during step 2-3 should matter? Thank you for your help.

    1 person found this answer helpful.
    0 comments No comments

  2. Alex 41 Reputation points
    2020-09-09T22:58:25.407+00:00

    UPDATE:

    Thank you for contacting us to help clarify the issue. We have been able to resolve the issue of 403 Forbidden when trying to resolve a SaaS subscription by making the following updates to the client credentials flow from my last post:

    1) Changing the scope value in the body of the token acquisition call from https://graph.microsoft.com/.default to 20e940b3-4c77-4b0b-9a53-9e16a1b010a7/.default (corresponding documentation at https://learn.microsoft.com/en-us/azure/marketplace/partner-center-portal/pc-saas-registration#request-body)

    2) Updating the token acquisition URL from https://login.microsoftonline.com/common/oauth2/v2.0/token to https://login.microsoftonline.com/<azure-tenant-id>/oauth2/v2.0/token

    We are now able to resolve the token and use the response data to activate a subscription to our SaaS offering. Thanks again!

    0 comments No comments