Skip to main content

In this post, we will look at using JWT, or JSON Web Tokens, with Power Apps Portals to implement a single sign-on (SSO) scenario when integrating with an external Web API. In a previous post, we went through an introduction to JSON Web Tokens. If you not familiar with JWT, please start here.

Power Apps Portals have an ability to generate a JWT token which can be verified using a public key. If we run the code below in the browser console, we get back a JWT token from Power Apps Portals:

$.get("/_services/auth/token").then(function(token) { console.log(token)
})

Note we can also get the token by going to https://<portalurl>/_services/auth/token:

This downloads a file:

And if we open this we also see a token:

We can take this token and paste it into jwt.io to look at it. We can see it is a JWT token divided into the header, payload and signature:

Power Apps Portals supplies several claims in the payload, including the name, customer id, email, issuer, etc. We see in the header that the algorithm used is RS256, and if we scroll down we see that the signature is invalid, as we have not supplied the key:

The public key can be accessed at https://<portalurl>/_services/auth/publickey:

If we paste this into jwt.io, we get a signature verified:

The token can then be sent to a 3rd party, and they can decode it and verify the signature which will confirm its authenticity. They can then examine the claims that were passed, which can determine which resources the token has access to. For example, there is a “role” claim which is set to “admin”.

The Microsoft documentation links to a GitHub called ExternalWebApiConsumingPortalOAuthTokenSample. Let’s look at how to use it.

Download the ZIP file and unblock and extract it, then, open the solution:

Restore any nuget packages. Note, there are some deprecated packages. We will continue to use them just for this exercise, but you may want to upgrade these for production scenarios.

Also, the project has long path names, so be sure to open it in a lower directory.

Build the project and run it. The project will run on the port below, if the port is already in use, change it:

In the web.config, change the Microsoft.Dynamics.AllowedPortal to your portal. I.e. change from:

To:

Now, in the startup.cs, set ValidateAudience to false. We will look at passing a client id later:

Now, in the WhoAmI method, I ran into an error which meant updating this line, removing List below:

To this:

And removing indexing on the line below:

Now run the code so the browser is up and running. The portal loads below showing the public key that is being read from our Power Apps Portal using the public key URL at https://<portalurl>/_services/auth/publickey:

Now let’s try to run this from Postman. We’re going to hit the URL http://localhost:60718/api/external/whoami. If we run this, we see we get the response “Authorization has been denied for this request”:

Let’s generate a new token like above using the browser console or the _services/auth/token url, then under Headers add a new header for Authorization and a value of Bearer then add the JWT token, like below:

Running this, we get data returned from our API:

We can now authenticate with our app using the JWT token from Power Apps Portals.

Now let’s look at securing this further with a client id. In the Power Apps Portals admin, there is a setting for ImplicitGrantFlow called Connector/ImplicitGrantFlowEnabled. You may not have this setting, if not, you can create it like below:

Next, you need to register a client id. You can do this like below with the name ImplicitGrantFlow/RegisteredClientId:

Then there is the redirect setting ImplicitGrantFlow/myclientid/RedirectUri like below:

Update the portal cache once the settings are entered.

Now, in the code, change the valid audience from the Client Id provided to the one in your org:

New client id:

Let’s get the JWT token again but this time passing client_id as a parameter:

$.get("/_services/auth/token?client_id=myclientid").then(function(token) { console.log(token)
})

Now sent this token through in Postman we get the same authenticated result:

THANKS FOR READING. BEFORE YOU LEAVE, I NEED YOUR HELP.

 

I AM SPENDING MORE TIME THESE DAYS CREATING YOUTUBE VIDEOS TO HELP PEOPLE LEARN THE MICROSOFT POWER PLATFORM.

IF YOU WOULD LIKE TO SEE HOW I BUILD APPS, OR FIND SOMETHING USEFUL READING MY BLOG, I WOULD REALLY APPRECIATE YOU SUBSCRIBING TO MY YOUTUBE CHANNEL.

THANK YOU, AND LET’S KEEP LEARNING TOGETHER.

CARL

https://www.youtube.com/carldesouza

ABOUT CARL DE SOUZA

Source