Around the time of Codegarden, we released a new open-source, free-to-use, Umbraco package called Authorized Services.
We've worked on releasing several integrations over the past couple of years with various third-party SaaS services. And we'll continue to do so. If they match a service you also need to work with for a particular use case, they'll save you quite a bit of development time. Even if they don't match exactly, being open-source they'll be a useful starting point for anyone considering similar integrations with Umbraco.
There's a limit to the value we can provide here though. The number of available SaaS providers is enormous these days, so it's unlikely we'll be able to work on even a fraction of these. Plus of course, there are many services that can be integrated into an Umbraco solution, even if there's not a common use case for why you'd need an integration in the backoffice.
As such we decided to focus also on building the Authorized Services package. The idea is that we provide various aspects of the "plumbing" necessary for integration with third-party services - such as authorization, token storage, and serialization - leaving you able to focus on implementing the specific business features you need using the service's API.
If this package is new to you, it's worth first reading the blog post where we introduced it.
We also have a page on the Umbraco documentation website, where you can find full details of all configuration options - including all the new ones discussed in this article.
Otherwise, please read on to hear about how we've extended the functionality over the past few months.
New features in Umbraco.AuthorizedServices 0.3
Before diving into the features, we wanted to thank those who have tried out the package and offered suggestions as to how it could be extended and improved. Anders Bjerner In particular applied his considerable experience in building integrations with third-party services and provided some really useful feedback. Most of the updates come directly from his ideas for extending the scope of the package.
In summary, with the initial release, we focused on supporting services that offer authentication and authorization via an OAuth2 flow. With the update, we've offered more flexibility in this, improving the usability of the package and extending its scope to cover more services and use cases.
Manual Save of Access Tokens
With most services that offer OAuth2 as the means of authenticating with their API, it's necessary to go through a particular flow. This involves authentication at the provider's website, receiving a code that's swapped for a token, storing that token, and providing it with further requests to the API. Supporting that flow was the main purpose of the initial release of the Authorized Services package.
Some providers allow you to generate a token directly on their website. For those, we can allow the skipping of part of the process by supporting the direct entry and saving of the token to storage via the Umbraco backoffice.
To enable this feature you can set the CanManuallyProvideToken configuration value to true.
Authorization via API Key
Although many services are now moving to OAuth2 as their primary method for authentication and authorization, several also offer a simpler mode via an API key. In this case, the key is provided in the API requests rather than the token.
We've added support for these services that you can use by changing the configuration setting AuthenticationMethod from the default of OAuth2AuthorizationCode to ApiKey.
You can then add the API key itself to the configuration, along with details of how the key is provided to the service (via a query string or an HTTP header).
Manual Save of API Keys
It could be you prefer not to store the API key in configuration but instead would prefer to provide it via the backoffice. From there it will be stored, and encrypted in the Umbraco database, in a similar way that we do for tokens.
You can enable this feature by setting the CanManuallyProvideApiToken configuration value to true.
OAuth2 Client Credentials Flow
The OAuth2 protocol has a number of variations. With the original release of the package, we supported what seemed to be the main one in use today, which uses the grant type of authentication code. We also allowed for the use of the additional security step proof key of code exchange (PKCE).
With the latest release, we added support for the client credentials flow used by some services. With this option rather than redirecting the administrator to authenticate with the third-party service, the configured client ID and secret are formatted, encrypted, and passed. A token is received and from there follows the normal OAuth2 flow.
To use this option you can change the configuration setting AuthenticationMethod from the default of OAuth2AuthorizationCode to OAuth2ClientCredentials. The ClientCredentialsProvision configuration value allows customization for how the authentication request is made.
Long-Lived Access Tokens
Another variation used by some service's APIs, such as Instagram, is long-lived access tokens. With this flow, the first token received is considered short-lived, valid for just one hour. However, short-lived tokens can be exchanged for long-lived ones.
We've added seamless support for this by including a check to exchange the token for a new, long-lived one on first request to the API, as well as a subsequent verification of the new expiry to refresh the token again when needed.
You can enable this option for a service by setting the CanExchangeToken configuration value to true and updating as appropriate the ExchangeTokenProvision details.
Some services still support the older version of the OAuth protocol, OAuth1, so we've added support for that too. To use this option you can change the configuration setting AuthenticationMethod from the default of OAuth2AuthorizationCode to OAuth1.
Although some of the details of this flow differ, to use it with the package the process is exactly the same. Via the backoffice you'll have a button to authorize the service.
Clicking that will take you to the service's website where you'll sign in and agree to the integration having access to your account. A token will be generated, stored, and provided in subsequent API calls to the service.
The previous and current release have a major version of zero, and as such there are some breaking changes with this update. Most fit under the "unlikely to affect anyone" category, where we've made some changes to method names and interfaces that aren't typically something we expect users to replace.
There are a couple of important ones to note though.
Now we have introduced OAuth1 as well as OAuth2 support, we've amended the callback URLs you will need to configure with your service apps to:
- For OAuth2
- For OAuth1:
The second key change is that we've refactored the IAuthorizedServiceCaller methods to return results wrapped in Umbraco's Attempt construct. We felt this was a valuable change to make, as it offers you more flexibility in handling failed responses and avoids the necessity to use exceptions for "control of flow" in these situations.
The currently released version of the package is 0.3.0, with the "0" for the major version indicating that the status of the package is to an extent experimental. This purely reflects that it's still new work, we expect to receive feedback from people using it in their projects and perhaps will require minor breaking changes in future developments.
The package is released as an open-source offering and is not covered by official Umbraco support arrangements, being directly maintained by the DXP development team. That said, we are keen to have feedback, hear of any issues and will do our best to support anyone looking for advice in using the package.
How to get involved
The package is open-source on GitHub too where we've tried to document further not just how it's used, but also how it works, so if you want to dive into the innards you can too. We've added some diagrams so you can see how we've implemented the various authentication flows.
We'd be particularly keen to hear from anyone who used the package with services we haven't yet tried it with. Assuming you can do so successfully, we'd really appreciate a PR to the Umbraco documentation repository that updates the page listing the configurations needed for the various services we've verified the package with.
You may find that you run into one of the subtle differences between the authorization flows that the package doesn't currently support. If that's the case, an issue, or even a PR with a suggested additional configuration or other extension to support the service, would be happily received.