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

Notifications

Announcements

Community site session details

Community site session details

Session Id :
Power Platform Community / Forums / Power Pages / How to generate JWT to...
Power Pages
Unanswered

How to generate JWT token in Power App Portals

(0) ShareShare
ReportReport
Posted on 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.

Categories:
I have the same question (0)
  • Christian Leverenz Profile Picture
    1,214 on at

    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 at

    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

Forum hierarchy changes are complete!

In our never-ending quest to improve we are simplifying the forum hierarchy…

Ajay Kumar Gannamaneni – Community Spotlight

We are honored to recognize Ajay Kumar Gannamaneni as our Community Spotlight for December…

Leaderboard > Power Pages

#1
Jerry-IN Profile Picture

Jerry-IN 71

#2
Fubar Profile Picture

Fubar 62 Super User 2025 Season 2

#3
sannavajjala87 Profile Picture

sannavajjala87 31

Last 30 days Overall leaderboard