Role Based Security In PowerApps using SharePoint Groups

Recently a customer asked if PowerApps can support role based security controlled by SharePoint Security Groups. For example, can you make an Admin screen that is visible only to users who belong to a specific SharePoint Security Group? Yes, you can and this is where Microsoft Flow comes to the rescue!

This blog post is an attempt to share an approach for finding out the SharePoint Group membership of a signed in user and make certain features or screens of an app available to them.

Prerequisites

Create a SharePoint security group with members that you would want to use for role based security in your PowerApps App and navigate to the group settings .

grpsetting
And enable “Everyone” access to view the members of this group
grpsec

We will be creating a Flow to check group membership using a SharePoint HTTP REST call. Users triggering the Flow from your app may not necessarily have admin privileges to read group membership details. To enable all users to read group membership it is necessary to allow “Everyone” to view members of the security group.

Steps

  • Create a blank flow using a Site Collection Admin/Flow owner account.
  • Add a PowerApps Trigger step so you can call this Flow from the app. Then add an Initialize variable step to store a boolean value (IsAdministrator). Next add another Initialize variable step with a string variable (UserGroupInfo) to store the user group information we will be retrieving in the next step.

1

  • Search for ‘Send an HTTP request to SharePoint’ action under SharePoint actions and add it. Now let’s configure this action to make a SharePoint REST call to determine user group membership.

Site Address: Select the site collection where your SharePoint Security group exists

Method: Get

Uri: api/web/sitegroups/getByName(‘SP Group Name’)/Users?$filter=Email eq ‘’

Replace ‘SP Group Name’ with your group name. Place cursor in between the single quotes after $filter=Email eq and select ‘Ask In PowerApps’ under manual content. This will auto generate a variable name that will be used as an input parameter for this Flow. The goal here is to pass the logged in user’s email id as a parameter from PowerApps to Flow.

Below is how the action looks after configuration. ‘RequestAdmins’ is the SharePoint User Group I used for this example.

chkUsergrp

This REST call will return an empty object if the user is not member of the group.

emptyresults

It will return an object with User properties in the following format if the user is a member of the group.

resultsjson

  • Now that we have an output from the REST call above, we can parse it to extract the results section. Add a ‘Set Variable’ action to set the variable ‘UserGroupInfo’ created earlier with the value set to expression body(‘CheckUserGroup’)[‘d’][‘results’]

extractUsrgrp

Here ‘CheckUserGroup’is the name of the previous action. If your action name has spaces, replace the spaces with underscore (_) character. At this stage, we have extracted the results which can be used to determine if the User is a member of the group.

  • Add a ‘Condition’ step to evaluate the results value. If the results object is empty then the user is not a member.

Use the expression @not(equals(variables(‘UserGroupInfo’), ‘[]’)) to evaluate the object.

‘UserGroupInfo’ is the variable used to store the object value and ‘[]’ compares to an empty object.

Set the variable ‘IsAdministrator’ that was initialized earlier to true if the condition evaluated to be true. If not, set it to be false.

isadmin

  • One final step in the flow would be to pass the results of our user group membership check back to PowerApps as an output parameter that can be used to enable certain features of the app for the logged in user. Add ‘Respond to PowerApps’ action and choose a text output. An output of type boolean would have been ideal but is not available at this time and we’ll stick to a text output. Provide a name for the text output parameter (I used ‘IsAdminUser’) and set the value to variable ‘IsAdministrator’.

respondtpPA

Here’s how entire Flow looks like and it’s time to save it and see it in action.

fullflow

  • Now that we have Flow ready, let’s implement and test it on the app. Navigate to your PowerApps app, create a new blank screen, click on Properties dropdown and select the ‘OnVisible’ event of the screen. Next click on the ‘Action’ tab and select ‘Flows’. Select the Flow you created to add it to the formula bar to associate the Flow to the ‘OnVisible’ event of the screen. Type the below functions on the ‘OnVisible’ formula bar.

PAFunction

First we are creating a variable (isAdmin) to store the user group membership status in Boolean format and setting the default value to be false. Next we are triggering the Flow ( ‘CheckUserPermission’ is the name of the Flow I created) and passing in an encoded format of the current logged in user’s email as the input parameter.

The output returned from Flow is being stored in a variable ‘UserGroupInfo’. Lastly, we are validating the value of the output parameter ‘isadminuser’ we configured earlier and setting the ‘isAdmin’ variable with Boolean equivalent.

  • Drop a button on the screen and set the “Visible’ property of the button to variable ‘isAdmin’. This will show/hide the button based on the value of the variable. You can set the ‘OnSelect’ event of the button to navigate to an Admin Only Screen.

And we are done! Publish the app and run. If all goes well, you should see that the flow ran successfully.

On the app side, Flow is triggered (when the screen is visible) with the current user’s encoded email id as the input parameter which in turns makes a SharePoint Rest Call to determine the user’s membership.It returns a Text output of value “True” or “False”. The app then validates the returned value and shows/hides the button based on the user’s group membership.

Here’s how my sample app looks like if the current user is an admin:

PAScreen1.png

If the current user is not an admin then the admin button is hidden.

PAScreen2.png

Resources

Here are some resources I found to be very useful to help design this solution:

  • Doctor Flow’s post how you can use SharePoint REST APIs in Flow
  • For those interested in the SharePoint REST/OData API, you can find the complete set of REST/OData APIs here.

29 thoughts on “Role Based Security In PowerApps using SharePoint Groups

  1. Pingback: Role based Canvas Apps | Dreaming in CRM

  2. Pingback: Role based Canvas Apps - Microsoft Dynamics CRM Community

  3. Thanks for your quick response! I’m obviously doing something wrong and it is probably due to me being new to PowerApps. Unfortunately I can’t add a screenshot in the comments but I did upload one to my flicker account @ https://c1.staticflickr.com/5/4886/45183199304_cae95116ac_b.jpg. In PowerApps, I do the following:
    1. Add a blank screen.
    2. Immediately above the Screens frame on the left, there is a Properties dropdown – I scroll to that and select “OnVisible.”
    3. Next, I click the Action tab and select FLOWS and pick the Flow I created. It populates the formula bar with: ‘PowerApp->Initializevariable,Initializevariable2,SendanHTTPrequesttoSharePoint,Setvariable’.Run(
    4. I pasted your formula after the Run( as follows: Set(isAdmin,false);Set(UserGroupInfo,CheckUserPermission.Run(EncodeUrl((User().Email)));Set(isAdmin,If(UserGroupInfo.isadminuser=”true”,true)) and closed it with another ).
    5. I get error messages indicating that CheckUserPermission.Run(EncodeUrl((User().Email))) is an invocation of an unknown or unsupported function and that UserGroupInfo.isadminuser is an improper use of “.”

    I’m sure I’m making a silly mistake.

    Like

    • No worries. Been there and I’m still learning. Here’s what I think is happening. ‘CheckUserPermission’ is the name of the Flow I created. You may want to update occurrences of ‘CheckUserPermission’ with your Flow (name). Or You could rename your Flow to ‘CheckUserPermission’ and redo the step to add the Flow and update the formula bar.

      Like

  4. Thanks Geetha – with your help, I was able to get it working and it works great! I modified the flow a bit so that I pass the user’s email address and it checks membership in multiple security groups via parallel branches so that I can then trim controls in the form based on several different roles.

    Liked by 1 person

  5. Hi Geetha,
    Thanks for sharing this information. It was exactly what I was looking for, but I am having trouble getting it to work as my Flow is failing with a 401 UNAUTHORIZED error on the ‘Send an HTTP Request to SharePoint’ action, but I don’t understand why as I am the owner of the SharePoint site, and the creator of these SharePoint groups, and I have set the SharePoint group settings to be viewable by Everyone as advised in the Blog. Can you think of any other reason I might be having this problem?

    Thanks,
    Anne

    Like

      • Hi Leward, The user account logged into your PowerApp is the account that triggers the Flow. You should be able to verify that by looking at the Flow run history and expanding the first action to view the user email id that was passed as a parameter from PowerApps to Flow.

        Like

      • Hmm… the email being used is definitely me, and I created the Flow, the Sharepoint page, and the PowerApp, all using my corporate Office 365 account. Any other random thoughts?

        Like

      • Were you able to go through the steps in the Prerequisites to create a SharePoint User Group and enable “Everyone” access to view the members of this group?

        Like

    • I ran into the same issue and for me it was because there was a missing “_” in front of the API Url that was put in the text. If you take a look at the screenshot, you’ll see the “_” in front, so it should read like this:

      _api/web/sitegroups/getByName(‘SP Group Name’)/Users?$filter=Email eq ”

      Liked by 1 person

  6. Hi Geetha,

    I have one question – everything works great for the most part. However, there is one thing I haven’t been able to determine. Occasionally, there will be a user where this flow doesn’t work. For example, let’s say I have a group called “Managers” with Tom, Sally, and John in it. If Tom and John initiate a form with the Flow attached, the flow correctly resolves them in the Managers group. However, when Sally launches the form, the Flow does not find her in the Managers group even though she clearly is. To eliminate weird permission issues, I’ve also manually pasted the URI into a browser (while logged in as an admin user) and sure enough, Tom and John return results but Sally does not. The group is set for everyone to view membership. Any ideas?

    Liked by 1 person

    • Geetha, I found the issue and wanted to let you know. The issue is that PowerApps was returning the user’s UPN as the email address rather than the O365 email address and apparently, this is a known issue. If both of those fields match, the flow works perfectly; if they don’t, that’s an issue. What I did was change the filter parameter to Title and passed User().FullName rather than User().EmailAddress. This seems to work without additional changes.

      Liked by 1 person

      • Thanks for the update! You may also want to note that there might not be an issue with this approach until more than 1 user with the same Full Name exist in your tenant. It would be better to use the Office365 User connector in your PowerApp to get the current user profile and then the email address from there.

        Liked by 1 person

  7. Hi Geetha,
    Thanks for the detailed steps.
    But i’m facing an issue.
    I’m trying to implement Role based security in my SharePoint Power Apps list forms using Flows.
    When i save and open the form, i get the below error-

    UserBasedRoleSecurity.Run failed: { “error”: { “code”: 502, “source”: “europe-001.azure-apim.net”, “clientRequestId”: “dee98c8d-29e1-48d1-b305-457eb07d067e”, “message”: “BadGateway”, “innerError”: { “error”: { “code”: “NoResponse”, “message”: “The server did not received a response from an upstream server. Request tracking id ‘08586507545698914509316500698CU95’.” } } } }

    The issue is with the ‘Send an HTTP request to SharePoint’ step in the flow.

    The Uri is –

    api/web/sitegroups/getByName(‘TestUsers’)/Users?$filter=Email eq ‘@{triggerBody()[‘SendanHTTPrequesttoSharePoint_Uri’]}’

    Any help appreciated.
    Regards,
    Kevin

    Like

    • Hi Kevin, Are you encoding the email in PowerApps while trying to send it via Flow – EncodeUrl((User().Email))? Can you try hardcoding your email id in the ‘Send an HTTP request to SharePoint’ action by adding it as a param – pi/web/sitegroups/getByName(‘TestUsers’)/Users?$filter=Email eq ‘youremail@domain.com’? This will help validate if the http request works and if it’s something to do with permissions or group settings.

      Like

      • Hi Geetha and Kevin. I had exactly the same issue as Kevin and could not work out what the problem was until yesterday. Mine was a problem with the single quotes. If you copy and paste from a web page (like I did from yours) then apparently it is not uncommon that the single quotes look ok but are not recognised as being valid. I re-entered all the single quotes in my Flow actions and then my Flow ran.
        This has led me to another issue…it doesn’t work quite how I expected. We use AD security groups in our Sharepoint groups. I have a Sharepoint Group with the group “NZ All Users” in it which provides access to all our users. If I use the Sharepoint “Check Permissions” tool I can see that any NZ user name that I select is provided Read access via that group. However if I use this Sharepoint Send an HTTP Request function it returns an empty response. I have to add the user directly to the Sharepoint Group in order to get a response from this function saying the person is a member of the group. This does not seem like the correct functionality. Have you encountered this?

        Like

      • Thanks Geetha for the reply. The issue was with a missing “_” in Uri: api/web/sitegroups/getByName(‘SP Group Name’)/Users?$filter=Email eq ‘’.

        Liked by 1 person

  8. Hello,
    This is very helpful. Thanks for putting this together.
    Question, If we have multiple groups and users in each group want different buttons , How can we do that? Appreciate , if you can provide some inputs.

    Thanks,
    Angel

    Liked by 1 person

    • Hi Angel, You could use a single flow to check user memberships in different groups and return a comma delimited string of groups they have access to back to PowerApps where you can parse the results form the Flow and enable/disable buttons accordingly. You could also return a simple json back to PowerApps using the Request action in Flow. The response action is more flexible and powerful. But if you don’t prefer to go teh JSON route then the return to PowerApps action will help fit the purpose.

      Like

    • Hi Sara, Yes you can by using the Send an Http Request to SharePoint action in Flow.
      Http ‘POST’ to ‘_api/web/sitegroups({spgroupid})/users’ with the user loginname passed in the body.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s