PowerApps Portals: How to Hide or Show Content based on Logged in User

For those just starting out configuring PowerApps Portals, the question will eventually come up as to how to show or hide content based on the logged in user.

For example, if you are showing a page with registration to a private event or showing user specific data like support cases or invoices.  You will want to ensure that this CDS based data is not exposed to the general public.

In this example I have setup a “super secret” web page and I want to limit who can actually see it and the data.

Unprotected PowerApps Portal Page

User Authentication

The first thing to consider is user authentication. This is the process of allowing someone from the outside world the ability to login to your portal, typically with a username and password.

The way authentication works in PowerApps Portals is that every authenticated portal visitor (users that will login to the portal using some kind of credentials) must have a corresponding CDS Contact record. 

By default, PowerApps Portals are configured to automatically use forms based authentication. 

An anonymous portal visitor can register on the portal, which will create a contact record, that will store a username and an encrypted password. 

Alternatively, an existing contact in the CDS/Dynamics 365 system can be given an invitation code that can be used to associate the existing contact to a portal login and password.

CDS Contact record with web authentication details

Using Site Settings, you can configure the various aspects of the registration/authentication experience for you portal depending on requirements.  For example, you may not want to allow anonymous portal visitors to create user accounts, or you may want to force the users to use their email address as a portal login.

PowerApps Portals Login Page

The recommended method for authentication is to configure Azure AD B2C and not use the out of the box forms authentication.  I recently wrote a post how to setup PowerApps Portal Authentication using Azure AD B2C.

Web Roles

A contact can be assigned a web role.  A web role is very similar to a CDS security role that we would assign to a user.  When a portal is provisioned, the administrator, authenticated users and anonymous users web roles are created.  You can also create your own custom web roles.  For the most part, you would assign a contact to the web role much like a CDS user is assigned a security role for specific privileges. 

The exceptions are if the web role has been marked as “authenticated users” or “anonymous users” which means that it is implied that either (or both) authenticated and anonymous users

In our example, I have created an Instructors Web Role.

Instructor Web Role

Once the Web Role is created, it can be assigned to the Contact record.

Web Role assigned to Contact

Web Page Access Control Rule

There are two different features of the Portal that are used to protect content and data.  The first concept is the Web Page Access Control Rule.  This is linked to a web page record and also linked to a particular web role.  The web page access control rule can be set to levels or privileges, “restrict read” which basically means any portal contact with a web role linked to the web page access control rule can “read” the web page on a portal.  The other is “Grant Change” which means that users have the ability to modify any of the editable static content (content snippets, page title, page copy, etc) from the legacy front side editing tools, if they have the content editor permissions.  For the most part, if you want to allow a user to view or not view the page, choose “restrict read”.

Web Page Access Control Rule

Once the Web Page Access Control Rule is created, then assign specific Web Role(s).

Web Roles assigned to Web Page Access Control Rule

If a portal user belongs to the particular web role, linked to a web page access control rule with “restrict read” permission, they can view the particular web page and the corresponding web link will be visible in the menu for that user for that web page, but it will not be visible to anyone else.

If you just want to restrict access to a page, then web page access control rule is all you need.

Web link not visible due to Web Role
Web Link Visible to logged in Portal user

Note: You can still show the web link to a protected page by selecting “Disable Page Validation” in the web link record’s Link Options section. The portal user will still need to login to access the page.

However, you might want to limit visibility to specific data in an entity list, entity form, web form or some other method of dynamic content (e.g. retrieving data via a Liquid/FetchXML)

While you can filter an entity list via a relationship to the contact (current user) this still won’t necessarily completely protect your data.

Entity List filtered by logged in Portal User

Once the filter is setup, the logged in Portal user will only see records in an entity list that apply to them based on the filter.

Entity List showing only related CDS data

Entity Permissions

Setting up Entity permissions links a specific CDS entity to a web role.  On the entity permission record you can specify the scope and permissions.  This will allow you to secure CDS data on the portal.

For example, if you did not protect a specific entity with a corresponding entity permission record, if you could determine the GUID of specific record you, could still manipulate the URL to view data (hack) on the portal.

With entity permissions enabled, you would be not be able to view the record. The entity permission record specifies the entity, the scope and the privleges.

Setup Entity Permissions with scope set to Contact

Once the entity permissions are setup, attempting to hack to the entity form page again will prompt the user that they do not have permissions

Blocked due to entity permissions

By default, any dynamically generated content (via Liquid) is automatically protected by entity permissions.  For data surfaced on entity forms or entity lists, you do need to enable the entity permission check box.

A full overview of entity permissions on PowerApps Portals will be the topic of a future post.

Cover Photo by marcos mayer on Unsplash

Summary

Protecting and securing data is critical for any business system, apps built on PowerApps Portals are no exception. Using web roles, web page access control rules and entity permissions allows portal makers to be able to easily and consistently build an app where the data is secure.

Nick Doelman is a Microsoft Business Applications MVP and has presented sessions and classes on PowerApps Portals around the world. Follow Nick on twitter at @readyxrm.

25 thoughts on “PowerApps Portals: How to Hide or Show Content based on Logged in User

  1. This is great. I am coming from the land of SharePoint and so was curious as to the security trimming of links in particular.

    The features offered by PowerApps Portals and Model Driven Apps are just amazing, aside from your own fantastic blog are there any other resources I could use to get up to speed? Would it be worthwhile to go through all of the existing Dynamics Portals documentation as we await more and more PowerApps Portals documentation?

    Like

    1. Most of the Dynamics 365 Portals or Adxstudio documentation, blogs, videos, etc. still apply to PowerApps Portals. Here are some links to MS Learn that are near impossible to find via a search but are great resources (full disclosure -> I helped with some of the content)

      https://docs.microsoft.com/en-us/learn/paths/extend-dynamics-365-portals/
      https://docs.microsoft.com/en-us/learn/paths/work-with-portals-in-dynamics-365/
      https://docs.microsoft.com/en-us/learn/paths/get-started-dynamics-365-portals/

      Blogs:
      https://colinvermander.com/
      https://www.engineeredcode.com/blog

      I also teach a Portals Masterclass, Currently, have one tentatively scheduled for the UK in October. My goal is to have this as an online course before end of the year. https://www.expertcrm.co.uk/courses/dynamics-365-portals-jump-start/

      Liked by 1 person

    1. If you create an invitation record, you can specify web roles. Other than that, users will be automatically added to any “authenticated user” role. You could setup a Power Automate flow to assign users to web roles (using the Common Data Service – current environment connector, and the “relate records” action) HTH

      Like

  2. Hi Greatest name ever,

    Do you have any idea why my contact scope is greyed out? I am not able to choose the recordentity sadly enough. Will my trial version have to do something with this? I have used multiple browsers but no luck/

    Kind regards,

    Nick

    Like

    1. I am guessing that the entity for which you are setting up the entity permission record does not have a relationship to the contact entity. For example, if you created a custom entity called “Donations” and had a lookup field to the Contact record, when you add an entity permission, you could set the scope to Contact and you would need to specify the relationship between donation and contact. If there is no relationship between donation and contact (e.g. no contact lookup field), then when you choose the contact scope, the relationship field is greyed out, and you would need to use global scope instead. I hope that makes sense. Cheers, Nick

      Liked by 1 person

  3. Hmmmm how do I specify the relationship is my main question? My situation: I created and entity from a sharepoint list via power query. The column that needs to be the contact/lookup field has an data type of text/multilines, which I cannot change to a lookup field when the entity is created. Sure I can add a field in this entity which can be defined as a lookup field, still I cannot choose this lookup field because it is greyed out. I even tried to make a lookup field in the sharepoint list, but this way it gives me an error when refreshing the data when creating a data flow, therefor I do not know if the column is an lookup field or not. Maybe you do have more ideas to point me in the right direction?

    Like

    1. Ok, here is my understanding of the problem; You are using Power Query to read data from a SharePoint list to a Common Data Service (CDS) entity (Dataflow?). The Contact field on the SharePoint list is text. In order for the Entity Permission to work, the CDS entity needs a lookup to the Contact (system entity – the contact entity is part of the Common Data Model by default). It sounds like you need to update the Contact entity from a SharePoint list as well. Full disclosure, I have not used Power Query in Dataflows before, and I just did some Googling to find out how to update lookup/relationship fields in PQ and not finding anything (not that it doesn’t exist, but that is where you need to look, I think). The key is that portals pull data exclusively from CDS. Entity permissions Contact scope is tied directly to CDS Contacts. Once you get your CDS contacts updated and linked to the custom entity, the field will be selectable in EP. Does that help?

      Liked by 1 person

      1. I got this message when I want to reply your comment. Duplicate comment detected; it looks as though you’ve already said that!

        Goodmorning! First I would like to know if you are somehow related to Dutch/Belgium? Your lastname is very Dutchie!

        You are all correct by understanding the issue. It seems I am one step forward and 3 three steps back. I do understand now the relationship with Contact entity. So this is not greyed out anymore, but it seems I cannot add data in the lookup column, not via PQ(what the most preferable way is), not via export/import excel data(what curious about this I cannot use the export/import via modern portals view, but only via the admin center), not by adding a record manual in portals. I get an error(code -2.147.220.653) when adding data via import/export, the error only occurs when adding data specific to the lookup column. Is there a way to connect the lookup column/field to an another column or duplicate the values from one column to the lookup column, is it? In this case I want to connect the lookup column to the clients column, the clients column I am able to PQ. I have looked into your suggestion, the only thing I could find was using some kind of lookup function in PQ but not creating a column with the datatype lookup. I’ll look into CDS and find out if creating a database suits with our workflows at the moment. But if you have some knowledge you could share that will help me that would be great.

        Like

      2. Hi Nick,
        I found something interesting, https://dynamicscitizendeveloper.com/2020/04/21/how-to-map-a-lookup-field-in-a-power-platform-dataflow/
        I believe this is the kind of solution I am looking for, but I was not able to reproduce the method. And I cannot comment on this article. Maybe you are able to point me in the right direction?
        When reproducing the method I do get the destination fields, but I cannot select the Unit and Unit Group as the source column. I cannot find were I went wrong, but I do got confused by last step. The author created an alternate key with the name apr_ProductID, but he don’t get the name apr_ProductID but ProductNumber when he select the entity Product in dataflow. This don’t seems to add up for me to understand the method, I do get the c52e_opdrachtgever that I did give the name’s alternate key. Do you have any idea why I can’t select the Unit and Unit Group as source column?

        My steps:
        create entity: Totaaloverzicht(same as your entity Product)
        create lookup fields Default Unit & Unit Group and text fields Opdrachtgever & Jobnummer on the entity Totaaloverzicht.
        create alternate key in Totaaloverzicht, called cr52e_opdrachtgever on text field Opdrachtgever

        create entity Unit
        create primairy text field Name
        create alternate key in Unit, called cr52e_name on text field Name

        create entity Unit Group
        create primairy text field Name
        create alternate key in Unit, called cr52e_name on text field Name

        In dataflow I would like to connect the data(from sharepoint) to the enity Totaaloverzicht.
        Were the key fields is automatic detected as cr52e_opdrachtgever, but I cannot select the Unit & Unit Group were he has the destination fields DefaultUoMId.Name and DefaultUoMSchedulID

        Like

  4. Hi Nick, You are getting deeper into Dataflows and Power Query than my experience and knowledge! I took a quick look at the blog link and there is a “contact form” at the top of the blog article. It appears to be written by Hamish Shield who is well known in the New Zealand Power Platform community and great guy, I would suggest you reach out via the contact form on his blog as he likely much better at answering this than I am! Once you get your data setup if you are still having issues with the entity permissions, please let me know. Cheers, Nick

    Like

  5. Hi Nick,

    My entity list has multiple views. I want to add a dynamic filter based on a logged in user custom attribute on all the views.

    my custom entity “Classes” has a field “user_age”
    my Contacts entity has attribute “my_age”

    i want to display list of classes in each view of my entity list on the portal ONLY IF the age of the logged in user.my_age matches the user_Age field value on Classes entity.

    Like

    1. Take a look a Nick Hayduk’s post on adding FetchXML to an Entity List, I haven’t tried it but it might be a solution; https://www.engineeredcode.com/blog/dynamics-365-portal-filter-criteria-and-action-buttons Another idea is to create a custom view, take a look my post here: https://readyxrm.blog/2018/09/03/dynamics-365-portals-overcoming-entity-list-roadblocks-with-html-and-liquid/ and then you can extract the “my_age” from the logged in contact (something like {{user.my_age}}

      Like

  6. Thanks for your article! I have got a question – according to your suggestion, Contacts should be individually linked to Web Roles. That sounds quite manual. Is there anyway to link existing Azure AD Groups to Web Roles? That would imply that all users related to a given Azure AD Group would have the same Web Role. Thanks in advanced!

    Like

    1. Sorry for the delayed reply. Unfortunately there is no out of the box way to link Azure AD groups with web roles. That being said, these portal contacts would normally not be a part of your Azure AD (unless they are internal employees, etc). There might be a way to setup a Power Automate flow to link everything up, but I haven’t actually tried it.

      Like

    1. Hi David, The sign-in button seems to persist based on any site settings nor is it an item in the default menu weblinkset. I think you would likely need to inject some CSS in the header or footer to hide the sign-in button. I haven’t tried it specific for that, but that would be my first approach. HTH.

      Like

  7. Hi Nick,

    I want to create a custom Login page as per the client requirement. I am not sure how to add login functionality on our Login page. I want to store the user details in contact records in Dynamics 365. Can you please help me in this.

    Right now we get deafult sign in option, it’s only that I want to add my own sign in page. Hope to get help soon.

    Thanks

    Like

Leave a comment