dmyers87 / Commercial-Marketplace-SaaS-Manual-On-Boarding

Contoso Sample
MIT License
0 stars 0 forks source link

Build .NET Core

Deploy to App Service

Microsoft commercial marketplace SaaS offers sample - Manual on-boarding of customers

Some solutions require out-of-band or manual on-boarding steps, such as validating a customer, running scripts manually for deploying resources needed for a new customer etc. This sample uses notifications for a new customer, or any changes on the subscription status made outside of the solution code.

Please note the sample uses a personal NuGet package based on the preview version of .NET client library for Commercial Marketplace.

You can also find a short video published on the Azure Friday channel to see the experience and a brief explanation.

Prerequisites

The sample requires .NET 5.*.*, and an Azure Storage account.

Table of contents

In the sections below you will find:

Let's first start with mentioning how to integrate a SaaS solution with Azure Marketplace.

Integrating a software as a service with commercial marketplace

Many different types of solution offers are available on Microsoft commercial marketplace for the customers to subscribe. Those different types include options such as virtual machines (VMs), solution templates, and containers, where a customer can deploy the solution to their Azure subscription. Commercial marketplace also provides the option to subscribe to a Software as a Service (SaaS) solution, which runs in an environment other than the customer's subscription.

A SaaS solution publisher needs to integrate with the marketplace commerce capabilities for enabling the solution to be available for purchase.

Commercial marketplace talks to a SaaS solution on two channels:

The SaaS solution in turn uses the REST API exposed on the marketplace side to perform corresponding operations. Those can be activating, cancelling, or updating a subscription.

To summarize, we can talk about three interaction areas between the Azure Marketplace and the SaaS solution,

  1. Landing page
  2. Webhook endpoint
  3. Marketplace REST API interactions

overview

Landing page

On this page, the subscriber provides additional details to the publisher so the publisher can provision required resources for the new subscription. A publisher provides the URL for this page when registering the offer for commercial marketplace.

The publisher can collect other information from the subscriber to onboard the customer, and provision additional resources as needed. The publisher's solution can also ask for consent to access other resources owned by the customer, and protected by AAD, such as Microsoft Graph API, Azure Management API, etc.

:warning: IMPORTANT: the subscriber can access this page after subscribing to an offer to make changes to his/her subscription, such as upgrading, downgrading, or any other changes to the subscription from Azure portal.

Azure AD Requirement: Multi-Tenant Application Registration

This page should authenticate a subscriber through Azure Active Directory (AAD) using the OpenID Connect flow. The publisher should register a multi-tenant AAD application for the landing page.

Webhook endpoint

The commercial marketplace calls this endpoint to notify the solution for the events happening on the marketplace side. Those events can be the cancellation or modification of the subscription through commercial marketplace, or suspending it because of the unavailability of a customer's payment method. A publisher provides the URL for this webhook endpoint when registering the offer for Azure Marketplace.

:warning: IMPORTANT: This endpoint is not protected. The implementation should call the marketplace REST API to ensure the validity of the event. This endpoint also receives a JWT token. You can validate the token against AAD, and check the audience to make sure this call is addressed to you. Please see the startup.cs file to see the implementation.

Marketplace REST API interactions

The Fulfillment API is documented here for subscription integration, and the usage based Metered Billing API documentation is here.

Azure AD Requirement: Single-Tenant Registration

The publisher should register an AAD application and provide the AppID (ClientId) and the Tenant ID (AAD directory where the app is registered) during registering the offer for the marketplace.

The solution is put on an access control list so it can call the marketplace REST API with those details. A client must use client credentials grant to get a token.

:warning: Important: The marketplace fulfillment API V2.0's resource ID is 20e940b3-4c77-4b0b-9a53-9e16a1b010a7.

If you are using the V1 end point for AAD, use the value 20e940b3-4c77-4b0b-9a53-9e16a1b010a7 for the resource parameter. If you are using AAD V2 endpoint (recommended), use 20e940b3-4c77-4b0b-9a53-9e16a1b010a7/.default for value of the scope parameter.

Please note the different requirements for the Azure AD interaction for the landing page and calling the APIs. I recommend two separate AAD applications, one for the landing page, and one for the API interactions, so you can have proper separation of concerns when authenticating against Azure AD.

This way, you can ask the subscriber for consent to access his/her Graph API, Azure Management API, or any other API that is protected by Azure AD on the landing page, and separate the security for accessing the marketplace API from this interaction as good practice. The certification policy requires the use of "User.Read" for signing on the user, and incremental consent pattern should you need to request other permissions.

Activating a Subscription

Let's go through the steps of activating a subscription to an offer.

AuthandAPIFlow

  1. Customer subscribes to an offer on commercial marketplace.
  2. Commerce engine generates a marketplace token for the landing page. This is an opaque token, unlike a JSON Web Token (JWT) that is returned when authenticating against Azure AD, and does not contain any information. It is just an index to the subscription and used by the resolve API to retrieve the details of a subscription. This token is available when the user clicks "Configure Account" for an inactive subscription or "Manage Account" for an active subscription.
  3. Customer clicks on "Configure Account" (new and not activated subscription) or "Manage Account" (activated subscription) and accesses the landing page.
  4. Landing page asks the user to logon using Azure AD OpenID Connect flow.
  5. Azure AD returns the id_token. There needs to be additional steps for validating the id_token — just receiving an id_token is not enough for authentication. Also, the solution may need to ask for authorization to access other resources on behalf of the user. We are not covering them for brevity and ask you to refer to the related Azure AD documentation.
  6. Solution asks for an access token using the service-to-service access token request of the client credential workflow to be able to call the API.
  7. Azure AD returns the access token.
  8. Solution prepends "Bearer " (notice the space) to the access token, and adds it to the Authorization header of the outgoing request. We are using the marketplace token previously received on the landing page to get the details of the subscription using the resolve API.
  9. The subscription details are returned.
  10. Further API calls are made, again using the access token obtained from the Azure AD, in this case to activate the subscription.

Scenario for the Sample

This sample can be a good starting point, assuming the solution does not have requirements of providing a native experience for cancelling or updating a subscription by a customer.

It exposes a landing page that can be customized for branding. It provides a webhook endpoint for processing the incoming notifications from the Azure Marketplace. It also provides a privacy policy and support page to meet the partner center requirements. The rest of the integration is done via notifications.

The landing page can also used for adding new fields to gather more information from the subscriber; for example: what is the favored region. When a subscriber provides the details on the landing page, the solution generates a notification to the configured operations contact. The sample has both the email and Azure storage queue notification implementation. The operations team then provisions the required resources, on-boards the customer using their internal processes, and then comes back to the generated notification and clicks on the link to activate the subscription.

Please see my overview for the integration points in Integrating a software as a service with Microsoft commercial marketplace.

Architecture Overview and Process Flow of the Solution

Architecture Overview and Process Flow of the Solution

Remember, this scenario is useful when there is a human element in the mix, for situations such as:

Walking-through the Scenario Subscription Process

  1. The prospective customer is on the Azure Portal going through the Azure Marketplace in-product experience. They find the solution and subscribe to it after deciding on a plan. A placeholder resource is deployed on the customer's (subscriber's) Azure subscription for the new offer subscription. Note: Please notice the overloaded use of the "subscription", there are two subscriptions at this moment, the customer's Azure subscription and the subscription to the SaaS offer. I will use subscription only when I refer to the subscription to the offer from now on.
  2. Subscriber clicks on the Configure Account button on the new subscription, and gets transferred to the landing page.
  3. Landing page uses Azure Active Directory (with OpenID Connect flow) to log the user on.
  4. Landing page uses the client library to resolve the subscription to get the details, using the marketplace token on the landing page URL token parameter.
  5. Client library gets an access token from Azure Active Directory (AAD).
  6. Client library calls resolve operation on the Fulfillment API, using the access token as a bearer token.
  7. Subscriber fills in the other details on the landing page that will help the operations team to kick of the provisioning process. The landing page asks for a deployment region, as well as the email of the business unit contact. The solution may be using different data retention policies based on the region (e.g. GDPR in Europe), or the solution may be depending on a completely different identity provider (IP), such as something in-house developed, and may be sending an email to the business unit owner asking them to add the other end users to the solution's account management system. Please keep in mind that the person subscribing, that is the purchaser (having access to the Azure subscription) can be different than the end users of the solution.
  8. Subscriber completes the process by submitting the form on the landing page. This sends notification using the configured notification handler.
  9. Operations team takes the appropriate steps (qualifying, provisioning resources, etc.).
  10. Once complete, operation team clicks on the activate link in the message.
  11. The sample uses the client library to activate the subscription.
  12. Client library gets an access token from Azure Active Directory (AAD).
  13. Client library calls the activate operation on the Fulfillment API.
  14. The subscriber may eventually unsubscribe from the subscription by deleting it, or may stop fulfilling their monetary commitment to Microsoft.
  15. The commerce engine sends a notification on the webhook at this time, to notify the publisher know about the situation.
  16. The sample sends a notification to the operations team, notifying the team about the status.
  17. The operations team may de-provision the customer.

Running the Sample

Creating a web application on Azure App Service and deploying the sample with Visual Studio

I am assuming you have already cloned the code in this repo. Open the solution in Visual Studio, and follow the steps for deploying the solution starting from this step.

The following is how my Visual Studio Publish profile looks:

publishprofile

Creating a web application on Azure App Service and deploying the sample with Visual Studio Code

Make sure you have Azure Tools or Azure App Service extension.

:warning: Important: Open Visual Studio Code at the src/CommandSenter folder, not at the repo root.

Create a new Web App with the Azure App Service extension.

Deploy to the new Web App with the extension.

Alternatively, follow the tutorial, and modify the process as you see fit.

Registering Azure Active Directory Applications

I usually maintain a separate Azure Active Directory tenant (directory) for my application registrations. If you want to register the apps on your default directory, you can skip the following steps and go directly to Registering the Apps.

Creating a New Directory

  1. Login to the Azure Portal.

  2. Click Create a Resource and type in Azure Active Directory in the search box:

    createdirectory

    Select Create Directory then fill in the details as you see fit after clicking the Create button

  3. Switch to the new directory.

    switchdirectory

  4. Select the new directory, if it does not show under "Favorites" check "All directories":

    gotodirectory

  5. Once you switch to the new directory (or if you have not created a new one, and decided to use the existing one instead), select the Active Directory service (1 on the image below). If you do not see it, find it using "All services" (2 on the image below).

    findactivedirectory

  6. Click on "App registrations", and select "New registration". You will need to create two apps.

    registerappstart

Registering the Apps

As I mentioned in the landing page and webhook sections above, I recommend registering two applications:

  1. For the Landing Page: Commercial marketplace SaaS offers are required to have a landing page, authenticating through Azure Active Directory. Register it as described in the documentation. Make sure you register a multi-tenant application, you can find the differences in the documentation. Select the "ID tokens" on the "Authentication" page. Also, add two Redirect URLs: the base / URL of the web app and another web app URL with /signin-oidc added.

  2. To authenticate marketplace fulfillment APIs, you can register a single tenant application.

    A screenshot of a computer Description automatically generated

Creating and Configuring a SendGrid Account when using email notifications

Follow the steps in the tutorial, and grab an API Key. Set the value of the ApiKey in the configuration section, "CommandCenter:Mail", either using the user-secrets method or in the appconfig.json file.

Creating a Storage Account

Create an Azure Storage account following the steps here. The solution uses the storage account to keep references to the operations returned by actions done on the fulfillment API, as well as offering a place to store Leads generated from the Marketplace offer (via Table Storage).

Change the Configuration Settings

You will need to modify the settings with the values for the services you have created above.

You will need to replace the values marked as CHANGE, either by editing the appconfig.json file in the solution, or by using dotnet user-secrets if you are planning share your work publicly.

Setting Change/Keep Notes
AzureAd:Instance Keep This is used by the library
AzureAd:Domain Change You can find this value on the "Overview" page of the Active Directory you have registered your applications in. If you are not using a custom domain, it is in the format of \<tenant name>.onmicrosoft.com
AzureAd:TenantId Keep Common authentication endpoint, since this is a multi-tenant app
AzureAd:ClientId Change Copy the clientId of the multi-tenant app from its "Overview" page
AzureAd:CallbackPath Keep Default oidc sign in path
AzureAd:SignedOutCallbackPath Keep Default sign out path
MarketplaceClient:ClientId Change Copy the clientId of the single-tenant app from its "Overview" page. This AD app is for calling the Fulfillment API
MarketplaceClient:TenantId Change Copy the tenantId of the single-tenant app from its "Overview" page.
MarketplaceClient:ClientSecret Change Go to the "Certificates & secrets" page of the single-tenant app you have registered, create a new client secret, and copy the value to the clipboard, then set the value for this setting.
WebHookTokenParameters:Instance Keep This is used by the library
WebHookTokenParameters:TenantId Change Set the same value as MarketplaceClient:TenantId
WebHookTokenParameters:ClientId Change Set the same value as MarketplaceClient:ClientId
CommandCenter:OperationsStoreConnectionString Change Copy the connection string of the storage account you have created in the previous step. Please see Client library documentation for details
CommandCenter:Mail:OperationsTeamEmail Change Use this section if ActiveNotificationHandler is EmailNotifications. The sample sends emails to this address.
CommandCenter:Mail:FromEmail Change Use this section if ActiveNotificationHandler is EmailNotifications. Sendgrid requires a "from" email address when sending emails.
CommandCenter:Mail:ApiKey Change Use this section if ActiveNotificationHandler is EmailNotifications. Sendgrid API key.
CommandCenter:CommandCenterAdmin Change Change it to the email address you are logging on to the dashboard. Only the users with the domain name of this email is authorized to use the dashboard to display the subscriptions.
CommandCenter:ShowUnsubscribed Change Change true or false, depending on if you want to see the subscriptions that are not active.
CommandCenter:ActiveNotificationHandler Change Active notification handler the solution uses. It can be EmailNotifications or AzureQueueNotifications.
CommandCenter:AzureQueue:StorageConnectionString Change Use this section if ActiveNotificationHandler is AzureQueueNotifications. Add the storage account connection string for the queue.
CommandCenter:AzureQueue:QueueName Change Use this section if ActiveNotificationHandler is AzureQueueNotifications. Name of the queue the messages will go to.
CommandCenter:EnableDimensionMeterReporting Change Use this section to enable manually sending usage events on a dimension for a customer subscription through this App. Default: false, change to true if there is at least one dimension enabled on an Offer-Plan and would like to trigger usage events manually. More information on Marketplace Metering Service dimensions.
CommandCenter:Dimensions:DimensionId Change Use this section if the above EnableDimensionMeterReporting setting is true. Add DimensionId of the enabled custom meter.
CommandCenter:Dimensions:PlanIds Change Use this section if the above EnableDimensionMeterReporting setting is true. Add PlanId's of the plans for which the above DimensionId is enabled.
CommandCenter:Dimensions:OfferIds Change Use this section if the above EnableDimensionMeterReporting setting is true. Add OfferId's of the plans for which the above DimensionId is enabled.

Create an Offer on Commercial Marketplace Portal in Partner Center

Once your AAD directory, AAD applications, and web application are setup and ready to use, an offer must be created in the Commercial Marketplace Portal in the Microsoft Partner Center.

Documentation on creating an offer can be found on Microsoft Docs: Create a New Saas Offer in the Commercial Marketplace. Documentation is also available for all fields and pages for the offer on Docs as well.

You will need the following information to complete the offer:

Additionally, you will need assets, such as logos and screenshots, to complete the offer listing as well. They can be found in this code repository under /resources.

Example Offer Setup in Commercial Marketplace Portal

These are sample configuration values for the offer to pass certification of the sample SaaS solution to help you get started with a sample offer.

:warning: IMPORTANT: This is just meant to be a sample. You will need to make adjustments based on your specific offer, even for this sample (e.g. contact information). Real information needs to be entered; using "Lorem ipsum" style information will not pass the certification steps if you want to preview your offer in the marketplace. Again, reference the Microsoft Docs for a more thorough overview of each section.

Offer Setup

Microsoft Partner Center - Offer Setup

  1. Selling Through Microsoft: to simplify for this sample, choose "Yes".

  2. Customer Leads: unless you already have a CRM or other system setup that you'd like to use, choose Azure Table storage and use the connection string for the storage account you created earlier:

    Microsoft Partner Center - Offer Setup - Customer Leads

    1. Lead Destination: Azure Table.
    2. Contact Email: your email address.
    3. Storage Account Connection String: the connection string for the storage account you created earlier.
    4. Validate: ensure you can actually connect to the storage account.
    5. OK: close the dialog and you're set.
  3. Save Draft: Between each screen, be sure to save a draft.

Properties

Microsoft Partner Center - Properties

  1. Category: choose any category. Web is appropriate for this sample.
  2. Industried: again, choose any.
  3. Legal: optional, but choosing the Standard Contract may help with the certification process.
  4. Save Draft: as always, save a draft.

Offer Listing

This is where most of your configuration for the offer will be. Pay attention to all the fields, taking care to fill them out as fully as you can.

Microsoft Partner Center - Offer Listing

  1. Name: the name of your offer. This is what will be listed in the Marketplace. Since this is just a demo, something along the lines of Marketplace Demo - {YOUR ORG NAME} could work here.
  2. Search Results Summary: this is the text that shows when you search for your offer in the marketplace – a short sentence should suffice.
  3. Description: this needs to be a real description (i.e. no Lorem Ipsum). Feel free to use something similar to what's in the screenshot above.
  4. Getting Started Instructions: again, this needs to be real text. Also feel free to use something similar to what's in the screenshot above.
  5. Search Keywords: add your organization name, "marketplace demo", or something similar.
  6. Privacy Policy Link: This needs to be your web application's privacy policy URL that was called out earlier. It will be in the format of https://{YOUR_APP_SERVICE_NAME}.azurewebsites.net/privacy.
  7. Contact Information: Use your details for Name, Email, and Phone for both the Support Contact and Engineering Contact sections. For Support URL, you'll need to use the support URL that was called out earlier. It will be in the format of https://{YOUR_APP_SERVICE_NAME}.azurewebsites.net/support.
  8. Supporting Documents: upload the PDF resources/OfferListing-SupportDocuments-SupportInformation.pdf provided in this repository and name it "Support Information".
  9. Marketplace Media - Logos: upload all logos using the PNG files provided under resources/ in this repository. They are named according to their sizes.
  10. Marketplace Media - Screenshots: a screenshot has been provided under the resources/ directory – name it "All Offer Subscriptions".
  11. Save Draft: as always, save a draft when finished editing the page.

Preview Audience

Microsoft Partner Center - Preview Audience

  1. Azure Active Directory or Microsoft Account Email Address: add any AAD or Microsoft account email addresses that you would like to access this application. These will be the accounts that have access to viewing the offer in its preview phase. At a minimum, add your own account.
  2. Add Another Email: if there are others you'd like to see the offer in the preview phase, add up to 10 total accounts.
  3. Save Draft: save before moving forward.

Technical Configuration

This page has the landing page and webhook configuration for your offer that was deployed in earlier steps.

Microsoft Partner Center - Technical Configuration

  1. Landing Page URL: this is the Landing Page URL that was called out earlier. It will be in the format of https://{YOUR_APP_SERVICE_NAME}.azurewebsites.net/LandingPage.
  2. Connection Webhook: this is the Webhook Endpoint URL that was called out earlier. It will be in the format of https://{YOUR_APP_SERVICE_NAME}.azurewebsites.net/api/webhook.
  3. Azure Active Directory Tenant ID: the Tenant ID hosting the Single-Tenant Application.
  4. Azure Active Directory Application ID: the Application (Client) ID from the Single-Tenant Application that was created.
  5. Save Draft: save the current page.

How does it map?

Plan Overview

Microsoft Partner Center - Plan Overview

  1. Create New Plan: add a new plan to the offer to allow for signing up. We'll add one that's \$0 to avoid billing.
  2. Selecting Previous Plan: if you've already created a plan, you can edit them by selecting from the list.
  3. Stop Selling: if you need to "remove" a plan, you can stop selling it.

Creating a new plan:

  1. Plan Listing:

    Microsoft Partner Center - Plan Overview - Plan Listing

    1. Plan Name: choose a plan name that will be listed when selecting it in the subscription process.
    2. Plan Description: a basic, real description is required for certification.
    3. Save Draft
  2. Pricing and Availability:

    Microsoft Partner Center - Plan Overview - Pricing and Availability

    1. Markets: Choose the markets in which this plan will be available:

      Microsoft Partner Center - Plan Overview - Pricing and Availability - Markets

      1. Market Selection: Search for your current market(s).
      2. Save: save to close the dialog with your selection.
    2. Pricing - Pricing Model: choose "Flat Rate".

    3. Pricing - Billing Term: choose "Monthly" and set the cost to \$0.

    4. Plan Visibility: set to "Private".

    5. Restricted Audience: use the Tenant ID that hosts the Single-Tenant and Multi-Tenant AAD applications (the same that was used in previous steps).

    6. Save Draft

Co-Sell with Microsoft

Nothing needs to be configured here for the purpose of this solution.

Resell Through CSPs

Nothing needs to be configured here for the purpose of this solution.

Review and Publish

Under Offer Overview, verify that all available information looks correct. Then choose to Review and Publish the offer to start the certification process. Correct any errors that come back and work to the Publisher Signoff step; this is where you'll be able to sign up for your offer before going live (with your real SaaS offer in the future).

Microsoft Partner Center - Offer Overview - Review and Publish

Signing Up for Your Offer

Customer searches for the offer on Azure Portal

  1. Go to Azure Portal and add a resource

    purchaser1

  2. Find the search text box

    purchaser2

  3. Type in your offer name

    purchaser3

  4. Select the plan

    purchaser4

  5. Subscribe

    purchaser5

  6. Find the subscription after the deployment is complete, and go the subscription

    purchaser6

  7. Subscription details, notice it is not active yet

    purchaser7

  8. Landing page

    purchaser8

  9. Purchaser submits the form, and Contoso ops team receives an email

    purchaser9

  10. Contoso team takes the appropriate action to qualify and onboard the customer

    purchaser10