The end of xRM Portals Community Edition

As 2020 comes to an end, so does xRM Portals Community Edition. On December 19th, 2020, I marked the GitHub project as archived, so that everything would become read-only, including the code, wiki, and issue management features.

I was a little hesitant to take this step because of my personal connection to the code, my career, and all the unsung developers that worked tirelessly to build it from its inception at Adxstudio all the way until its acquisition and one-time release by Microsoft. Nostalgia aside, I feel it was the right time, given the ever-increasing inactivity on the project and my judgement of it having accomplished the project’s goal of providing a migration path to Microsoft’s online portals service.

What follows is my retrospective of the project.

The project was initiated on August 25, 2017, giving it a lifetime of 3 years and 4 months. While I can’t recall us having a pre-planned duration for the project, I think this duration is about as long as we would have envisioned if we’d tried to.

The main objective for the project was:

…to provide a way of upgrading from Adxstudio Portals 7 to this supported version of portals, and that provides a migration path to Microsoft’s hosted offering of Portal Capabilities for Microsoft Dynamics 365.

…Using Microsoft’s online version should be the primary goal of existing and new users, and using this version is primarily intended for those with special circumstances where they need to stay on premise for a longer time period while preparing to move online.

https://github.com/Adoxio/xRM-Portals-Community-Edition#objectives

I think 3+ years was a sufficient amount of time for those seriously intending to move online to perform that task. For those who haven’t yet, the source code is still available if needing to make any additional changes for their particular needs.

As an open source project, some interesting statistics are:

  • There were 72 commits, covering bug fixes, addressing compatibility issues, and general maintenance efforts.
  • There were 105 issues, of which 76 were closed and 29 remained open. The issues were a mix of bug reports and general questions.
  • There were 20 pull requests, of which 18 were closed and 2 remained open.
  • There were 7 contributors. This may not be a lot of people or as many as I’d hoped for, but I don’t think it’s unexpected as it confirms what I’ve anecdotally seen from other open source projects that most users who submit issues don’t participate in contributing.
  • There were 50 forks. It’s hard to draw any conclusions from this but when looking through the forks it’s interesting to see the changes some people made in their forks.
  • There were 99 stargazers. I would have loved to have hit the 100 mark, but 99 will have to do!
  • There were 48 watchers. This is perhaps a better gauge of who took an active interest in the project than stargazers since watchers can receive notifications for issues.
  • We created 10 wiki pages. The documentation from Microsoft had a few gaps and the wiki served as a good place to add supplementary content.

When the project was started, there were some obvious gaps in online portals for adding custom code that may have made it hard for users to switch to online. New features have since filled this gap and give alternate approaches to introduce custom code in ways that allow custom experiences that previously would have required changes to the portals code base itself.

  • The portal web API allows CRUD operations to be performed using client-side code, and with modern single page application (SPA) frameworks such as React, the user experience can be very sophisticated.
  • The OAuth 2.0 implicit grant flow allows for companion web apps to be implemented so that custom server-side code can be written, enabling complex business logic which shouldn’t be exposed to end-users.

One limiting factor to addressing issues was the omission of the unmanaged solutions from the initial open source one-time release. Several bugs couldn’t be fixed because the issues were contained within the managed components of the solutions (i.e. workflows, plugins, schema/customizations).

Part of the project scope was to limit changes to those that would remain compatible with the online version of portals. This meant some changes from pull requests couldn’t be merged. It was always enticing though to implement new features and venture down a different path than online portals goes. If Microsoft were to ever release the unmanaged solutions, or someone were to undertake the effort to reimplement the solutions, one could conceivably take the source code in any imaginable direction.

If you used the project, I hope it helped you. If you have any parting words for the project you’d like the rest of the world to see, please share them in the comments.

Good-bye xRM Portals Community Edition, it was fun while it lasted!

8 thoughts on “The end of xRM Portals Community Edition”

  1. We are sad to see that the repository has been archived. I have a little bit a good news for those that are still using the Portals Community Edition because there is no other viable option for your organization. I was getting ready to post the steps we took to enable S2S authentication to the repo when I found it was read-only. If anyone is interested in that information, please comment here.

      • Hi Chris,

        The steps that we took to enable S2S Authentication are as follows:

        1. Remove username and password from Xrm connection string in web.config.

        2. Add new app settings to web.config:

        3. Upgrade the NuGet package for Microsoft.IdentityModel.Clients.ActiveDirectory to v5.2.8. This will remove the synchronous routines for getting the authentication token. To remedy this change the following code:
        a. Adxstudio.Xrm > IdentityModel > ActiveDirectory > AuthenticationExtensions.cs > Line 79 to

        var task = authenticationContext.AcquireTokenAsync(resource, certificateCredential);
        task.Wait();
        var authResult = task.Result;

        b. Adxstudio.Xrm > IdentityModel > ActiveDirectory > AuthenticationExtensions.cs > Line 100 to

        var task = authenticationContext.AcquireTokenByAuthorizationCodeAsync(
        authorizationCode,
        new Uri(authenticationSettings.RedirectUri),
        certificateCredential,
        resource);
        task.Wait();
        var authResult = task.Result;

        3. Install a self signed certificate on your machine

        4. In Azure Active Directory
        a. Add an app registration
        i. Single tenant
        ii. Redirect Uri – root url of your app
        b. Record the Application (client) ID and Directory (tenant) ID to be used in app settings and when setting up the CRM Application User
        c. Under Certificates & secrets, upload the self signed certificate. Record thumbprint to be used in app settings.
        d. Under API permissions, add “Dynamics CRM” as a delegated permission

        5. In CRM, add an Application User (make sure the form is set to “Application User” to see the correct fields)
        a. User Name/Primary Email – use an email address that has not already been added to your Azure AD client
        b. Application Id – use the Application (client) ID for your app registration
        c. Other fields will be filled in automatically after user is saved
        d. Assign security roles to user

        6. If using Azure AD for user authentication, make sure this setting is added to Site Settings in CRM:
        a. Name – Authentication/OpenIdConnect/AzureAD/ObjectIdentifierAsNameIdentifierClaimEnabled
        Value – false

          • Looks like config file settings were removed from #2.

            !–settings that allow adxstudio to connect to CRM using server to server authentication —
            add key=”Azure.CrmSettings.PrimaryServiceUrl” value=”https://{crm instance}.crm.dynamics.com”
            add key=”Azure.Authentication.RootUrl” value=”https://login.microsoftonline.com”
            add key=”Azure.Authentication.TenantId” value=”{azure active directory tenant id}”
            add key=”Azure.Authentication.ClientId” value=”{registered application (client) id}”
            add key=”Azure.Authentication.RedirectUri” value=”{root url of your registered application}”
            add key=”Azure.Certificate.ThumbprintPrimary” value=”{thumbprint of installed certificate}”
            add key=”Azure.Certificate.ThumbprintSecondary” value=”{thumbprint of second installed certificate (optional)}”

    • Hi Candace,

      Thanks for posting the solution.

      I have followed the steps you have provided and I have the portal working on local machine. However, when I deploy the code to an Azure App Service, I find that it fails to retrieve the token. From further debugging, I can see the code finds the certificate, but the private key is null (“GetAuthenticationResult()” in CrmTokenManager.cs).

      The method this is failing at is “ApplyAuthenticationResult()” in CrmTokenManager.cs. The exception I am encountering is:

      NotSupportedException: The private key is not present in the X.509 certificate.

      Do you have any advice on how to get the certificate configured in Azure please?

      • Hi Sohail,

        Make sure that the Microsoft.IdentityModel.Clients.ActiveDirectory library is upgraded to v5.2.8. Also, try using a wildcard certificate in Azure.

  2. Sad to see this news… Curious to hear if there is anyone else out there that would have interest in forking and maintaining the repository.

Comments are closed.