web
You’re offline. This is a read only version of the page.
close
Skip to main content
Community site session details

Community site session details

Session Id : f7xIhVngdXCaMjnAqB079u
Power Pages - Power Apps Portals
Answered

How to generate JWT token in Power App Portals

Like (0) ShareShare
ReportReport
Posted on 3 Dec 2021 16:38:29 by 17

I'm trying to implement SSO (Single sign-on) in Power App Portals.

I have another e-commerce web application that includes customers from the master Power App. When the user logged into the Power app, I'm going to display a link to redirect to the separate e-commerce web application and need to skip the login part, and the customer should be signed in.

SO, I'm planning to display a link button that includes the JWT token. Then I can deserialize the redirect URL and trigger the customer sign-in part in the e-commerce application.

This is the first time I'm trying power app development and couldn't find a proper reference to generate JWT token in Power App Portal.

It's a big help if anyone can instruct me with some steps or provide some resource URLs.

I have the same question (0)
  • Christian Leverenz Profile Picture
    1,214 on 05 Dec 2021 at 11:33:49
    Re: How to generate JWT token in Power App Portals

    Hi @IsankaPT ,

    i think what you request is something like https://docs.microsoft.com/en-us/powerapps/maker/portals/oauth-implicit-grant-flow . This to my understanding somehow enables the portal to act as an oauth provide one the user is logged in (or requires a login if not). 

    Well, i am not to judge, but may be let me ask the following: when i got it right i think, this is not what you really want (doesn't lucifer always ak this? 🙂 ). When i talk to customers about single sign on, i usually recommend seperating the authenticatioon from the other stuff. So, for example if you use azure b2c as an authentication provider, the user effectively logs in into azure b2c and is known there. Whenever any application needs a signin it sends the user to the azure b2c and if the user is already logged it the application directly receives a token.

    So, if you set up the portals using azure b2c and switching off local authentication, most of the single singn-on should be handled automatically.
    Just my thought about it, hopefully it helps you finding a good solution for you.

     

    Have fun and happy portalling,

      Christian

  • Verified answer
    Isanka Thalagala Profile Picture
    17 on 07 Dec 2021 at 09:59:17
    How to generate JWT token in Power App Portals

    I have referred @chleverenz link and I have solved it like below, 

     
    Used HTML button to trigger goto GoToCommerceApp()
     

    This is the javascript code to generate the JWT token.

     

    <script type="text/javascript"> 
    // Define Callback function and call window.auth.getAuthenticationToken to fetch the token.
     function callback (data, err) { 
     if(data) {
     //Token received
     console.log('Token received',data);
     window.open("http://localhost:15536/api/ExternalWebApi/ValidateToken?userToken="+data);
     }
     else {
     console.log("Error");
     if(err){
     // 401 is returned for anonymous users.
     if(err.status == 401){
     console.log("Login required");
     redirectToLogin();
     }
    
     // To handle any other error
     else{
     console.log(err.responseJSON.ErrorId + " : " + err.responseJSON.ErrorMessage);
     }
     }
     }
     }
    
     function getAuthenticationToken() {
     	let clientId = "56756948ec-22041987612021"; //Add the Client ID registered on CRM. 
     $.ajax({
     type: 'GET',
     url: `/_services/auth/token?client_id=${clientId}`,
     cache: false,
     success: handleGetAuthenticationTokenSuccess,
     error: jqXHR => callback(null, jqXHR)
     });
     }
    
     function handleGetAuthenticationTokenSuccess(data, status, jqXHR) { 
    
     var jsonResult = JSON.parse(jqXHR.getResponseHeader('X-Responded-JSON'));
     if (jsonResult && jsonResult.status == 401) { 
     // If the user is not logged in, redirect to login page
     //redirectToLogin(); 
     callback(null,jsonResult); //Run callback method with error message 
     } else {
     // Pass the token to the callback function
     callback(data,null);
     }
     }
    
     function redirectToLogin() {
     var redirectUrl = window.location;
     var loginUrl = window.location.origin + '/SignIn?returnUrl=' + encodeURIComponent(redirectUrl);
     window.location = loginUrl;
     }
     
     function GoToCommerceApp(){// Fetch Token Call 
     getAuthenticationToken();
     } 
    </script>

     

     

    asp .net class to decode JWT token

     

     

    	public class ExternalWebApiController : ApiController
    	{
    		[AllowAnonymous]
    		[HttpGet]
    		[HttpsRequirement(SslRequirement.Yes)]
    		[Route("api/ExternalWebApi/PowerAppPortalLogin")]
    		public virtual IActionResult PowerAppPortalLogin(string userToken)
    		{
    			try
    			{
    				var email = DynamicsPortalBearerAuthenticationProvider.DecodePowerAppPortalToken(userToken);
    				return Json(email);
    			}
    			catch (Exception ex)
    			{
    				return Json(ex.Message);
    			}
    		}
    
    
    		public class DynamicsPortalBearerAuthenticationProvider
    		{
    			public static string DecodePowerAppPortalToken(string userToken)
    			{
    				try
    				{
    					// Retrieve the JWT token 
    					var jwt = userToken;
    					var handler = new JwtSecurityTokenHandler();
    					var token = new JwtSecurityToken(jwt);
    					var claimIdentity = new ClaimsIdentity(token.Claims, DefaultAuthenticationTypes.ExternalBearer);
    					var _signingKey = DynamicsPortalBearerAuthenticationProvider.GetSigningKey();
    					var param = new TokenValidationParameters
    					{
    						ValidateAudience = true, // Make this false if token was generated without clientId
    						ValidAudience = "6578954f948ec-544556920212021", //Replace with Client Id Registered on CRM. Token should have been fetched with the same clientId.
    						ValidateIssuer = true,
    						IssuerSigningKey = _signingKey,
    						IssuerValidator = (issuer, securityToken, parameters) =>
    						{
    							var allowed = DynamicsPortalBearerAuthenticationProvider.GetAllowedPortal().Trim().ToLowerInvariant();
    							if (issuer.ToLowerInvariant().Equals(allowed))
    							{
    								return issuer;
    							}
    
    							throw new Exception("Token Issuer is not a known Portal");
    						}
    					};
    
    					SecurityToken validatedToken = null;
    					handler.ValidateToken(token.RawData, param, out validatedToken);
    
    
    					string email = ((JwtSecurityToken)validatedToken).Payload["preferred_username"].ToString();
    					return email;
    				}
    				catch (Exception exception)
    				{
    					System.Diagnostics.Debug.WriteLine(exception);
    					return "";
    				}
    			}
    
    			public static string GetAllowedPortal()
    			{
    				return "abc.powerappsportals.com";// ConfigurationManager.AppSettings["Microsoft.Dynamics.AllowedPortal"];
    			}
    			
    			private static string GetAllowedPortalSigningKey()
    			{
    				return "";// ConfigurationManager.AppSettings["Microsoft.Dynamics.AllowedPortalSigningKey"];
    			}
    
    			public static RsaSecurityKey GetSigningKey()
    			{
    				var val = GetAllowedPortalSigningKey();
    				if (string.IsNullOrEmpty(val))
    				{
    					var portalUrl = GetAllowedPortal();
    					WebClient client = new WebClient();
    					var url = "https://" + portalUrl + "/_services/auth/publickey";
    					val = client.DownloadString(url);
    				}
    
    				var x = new PemReader(new StringReader(val));
    				var y = (RsaKeyParameters)x.ReadObject();
    				var rsaInfo = new RSAParameters
    				{
    					Modulus = y.Modulus.ToByteArrayUnsigned(),
    					Exponent = y.Exponent.ToByteArrayUnsigned()
    				};
    
    				var rsa = new RSACryptoServiceProvider();
    				rsa.ImportParameters(rsaInfo);
    				return new RsaSecurityKey(rsa);
    			}
    		}
    	}

     

     

     

     

     

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Chiara Carbone – Community Spotlight

We are honored to recognize Chiara Carbone as our Community Spotlight for November…

Leaderboard > Power Pages

#1
Fubar Profile Picture

Fubar 46 Super User 2025 Season 2

#2
Michael E. Gernaey Profile Picture

Michael E. Gernaey 43 Super User 2025 Season 2

#3
Jerry-IN Profile Picture

Jerry-IN 38

Last 30 days Overall leaderboard
Loading complete