Clayton's SharePoint Madness

All About SharePoint, InfoPath, and SharePoint Designer!

Posts Tagged ‘security’

InfoPath – User Roles in Browser-Enabled Forms Using AD Groups

Posted by Clayton Cobb on July 19, 2009


MAJOR REVISION – Now using GetCommonMemberships web method to determine group memberships for users without needing to use contact lists or any other manual data source!

So, you need to restrict certain controls in your InfoPath form, but it’s browser-enabled, and you just found out that User Roles are not supported, huh?  You also see that SharePoint permissions do not help restrict specific areas within your form, so what do you do?  There are probably several methods, but here is the one I have come up with that uses all built-in functions of InfoPath and MOSS 2007 without any code and leverages Active Directory Security Groups.

Special thanks to a co-worker of mine – Irene Clark – who I taught to use the UserProfileService and subsequently figured out on her own that GetCommonMemberships could help with User Roles.  She showed it to me, and I immediately jumped on it to come up with what you see here.   Thank you very much, Irene!

Here is an outline of the steps with the assumption that you already have a working, browser-enabled form.  If anyone needs me to write up the basic steps of doing creating a browser-enabled form from scratch, let me know via the Blog Request Log:

  1. Add GetCommonMemberships data connection
  2. Add necessary fields to form template and configure them
  3. Add conditional formatting to applicable controls

User Profile Service – GetCommonMemberships Method

We must add this superb web service to our form template as a data connection.  Please use the first 8 steps of Itay’s writeup to get this done as I can only give him credit for my extensive knowledge of this web service.  Once you’ve added it successfully, we need to do a few things with it using the later steps in Itay’s blog.  Here are the steps.  They are only text with no screens, so I will just paste them here.  Remember that we are leveraging a different web method than Itay, but it’s the same web service:

  • With InfoPath opened go to Tools > Data Connections, and click ‘add…’ to add a new data connection to the form. This opens up the Data Connection Wizard.
  • We want to receive data from the WS about the current user, so choose receive data’ and click next.
  • Our data source is a WS so choose ‘Web Service’ and next.
  • Now you will have to point the wizard to the WS. Type an address similar to this: http://ServerName/_vti_bin/UserProfileService.asmx  and click next.
  • Here you get a list of all methods for that WS, choose GetCommonMemberships and click next.
  • In this screen you can specify what parameters are sent to the method, we are relying on the method’s ability to return the current user name if no value is passed to it, so we will leave this as is (no value is passed to the method) and click next.
  • Click next and make sure ‘Automatically retrieve data when form is opened’ is checked.
  • Finish the wizard.

In this solution, the GetCommonMemberships (GCM) method of the UserProfileService will provide the values we need to check a user’s Active Directory (AD) Security Group (SG) and Distribution List (DL) membership.  This method also provides SharePoint (SP) Site membership, but that is not as useful as if it provided SP group membership, which it does not.  I will be focusing only on the AD group memberships for this write-up.  Here are some steps showing how to use and see what this method provides:

  • View this method’s node structure
  • Drag the whole repeating group to the canvas and preview to see the result
  • Reduce the table to the most useful fields and decide which ones you want to leverage
  • Filter to show only the AD groups
  • Create a dropdown control bound to an element in your main data source that will show a selectable list of groups for a given user
  • Use this information to apply conditional formatting on other controls

Notice that the node structure in the GCM method (Fig 1) is much more friendly than GetUserProfileByName.  You can clearly see the information that is available, and the nodes are self-explanatory for the most part.

URG1

Fig 1 – GCM Node Structure

Grab the MembershipData repeating group onto the canvas and choose Repeating Table when prompted.  This lays out the entire node structure nicely, although you will need to expand the table and the columns in order to clearly see the data (Fig 2).

URG2  

Fig 2 – Full GCM Repeating Table Structure with Sample Data

In my opinion, certain fields are not useful to us due to either not having data or not having data that is useful for determining User Roles.  I will delete the columns named Group Type, Privacy, ID, Member Group ID, and Group (Fig 3).  Notice that Member Group ID does have some unique info, but I am not yet sure how to leverage that data.  You may also want to remove the SourceInternal field from the MemberGroup section, because it shows the same GUID each time (at least in my system).  As for the remaining fields, here are my notes so far:

  • Source: This shows whether or not the record is an AD group (noted as “DistributionList”) – or a SharePoint site membership (noted as “SharePointSite”).  Notice, these are not SharePoint groups, but rather site memberships and only where the user has been specifically added to that site with permissions as opposed to inherting permissions through AD SG membership.  The AD groups include both SGs and DLs, which is important to know.
  • Member Group – Source Reference: This shows the Organizational Unit path in Active Directory of the DistributionLists and shows a GUID for SharePointSites.
  • Display name: This is the Display Name of the group as defined in AD.  In Outlook, this name can typically be used as an addressee for an email, and the name will resolve to the email address.  This name SHOULD be unique and will be what we use for our User Role matching later.  For SharePointSites, this is just the site name.
  • Mail NickName: This is the alias for that group in AD, and it also will resolve to the email address when used in Outlook.  However, I found in my system that there were _two_ separate contacts in the GAL with the same alias.  That should not happen, and I will be notifying the AD admins, but the fact that it did happen with a common SG I use means it is not a guarantee, so be wary of that.  The same could potentially happen for Display Name, but that is a much longer and more specific name while aliases are sometimes just a few letters.  There is no nickname for SharePointSites.
  • URL: This is the direct email address for the group in the form of mailto:name@domain.com.  This also could be a very good source for matching groups and/or for sending emails.  Again, the email address SHOULD be unique, but that all depends on how well your AD is maintained.  For SharePointSites, it shows the URL to the site.

URG3

Fig 3 – Partial GCM Table with Relevant Columns Only

If you ever plan to use this method for displaying a user’s list of group memberships, you may want to only show the DistributionList records.  To do so, simply right click on the repeating table itself and create a conditional formatting rule that hides the control if the Source node is equal to “SharePointSite” in it (Fig 4).  Interestingly, when going through the wizard to set this condition, the wizard automatically detected the available options for that node.  I am used to seeing that with my main data source, but it does not always happen when referencing a secondary data source node.  In this case, it helps to quickly choose the right selection without the potential for a syntax error.  The result will be that you only see DistributionList records in the repeating table, which is the information that would be useful.

URG4

 Fig 4 – Set Filter on GCM Table to Only Show AD groups

You may also at some point wish to show a user’s group memberships in a pulldown and then use a particular selection to trigger a rule or match some other condition elsewhere in the form.  You may even use it to see another user’s memberships (other than the current user) and then select a group to then invoke the UserGroup web service (or possibly other available web services/methods similar to this) to enumerate the users in the group.  That is outside the scope of this write-up, but it’s something to consider.  To set up the dropdown, follow these steps:

  • Create a text data element in your main data source with whatever name you prefer
  • Drag that field to the canvas, which makes a text box
  • Right-click that box and change it to a Drop-down List Box
  • Double-click the dropdown to get to its properties (Fig 5)
    • Select the radio button that says, “Look up values from an external data source
    • For the Data Source, choose GetCommonMemberships
    • For Entries, click the button, drill down through the groups, and select the MembershipData repeating group
    • For Value, choose whatever node you prefer as your primary key (unique value).  DisplayName, Nickname, and URL are all suitable.
    • For Display Name, choose the DisplayName node
  • Click OK until done and preview the form.  You should see the friendly names of your groups all listed in the dropdown.  Since this is a browser form, we cannot filter the dropdown (at least until we get SharePoint 2010!), so you will see the SharePointSites, too. 

    URG5

Fig 5 – Dropdown Bound to Main Data Source and Showing GCM Group Data

Add Necessary Fields to Form Template, Create Layout, and Configure Default Values

First, manually create all the fields and groups you see below (Fig 6).  Notice that strAdmin and strFinance have default values.  Do not mimic these in your real form, because they will depend on your group names, which we’ll get to shortly.

 URG6

Fig 6 – Data Structure

Next, we need to create our layout on the canvas (Fig 7).  For this example, I just simply have two sections that are bound to grpAdmin and grpFinance (do not include their child fields), respectively, along with some text and a color for differentiation.  I also have a repeating table bound to the MembershipData repeating group of the GetCommonMemberships method that is only showing the DisplayName element.  This is only on the form for now to show what is happening, but it would not be on the form when using this concept unless you have some reason for showing the current user’s groups.  You get this on the canvas by following the steps shown in Figures 2-4.

 URG7

Fig 7 – Form Layout

After that, we need to assign our initial values that will play a part in the security of our form.  For this exercise, we will use two Group Check Fields. This part is important, because this is what defines the group memberships in your form that will be leveraged for User Roles.  I am using “Sharepoint Admins” and “Finance,” because those are the _exact_ words that show up in the DisplayName field of GetCommonMemberships (refer to Fig 2).  In your case, you’ll want to add a field for each group that you want to define for your User Roles and set its default value accordingly:

  • strAdmin – Set the default value to the text “Sharepoint Admins” (no function used)
  • strFinance – Set the default value to the text “Finance”
  • Remember, please use proper values for your environment based off what you see in your equivalent of Figure 2 above

Add Conditional Formatting to Sections

  • Administrators Section – We are going to set conditional formatting on this control (Fig 8) so that if the user is not in the Sharepoint Admins security group, then this control will be hidden:
    • Double-click the Administrators section on the canvas to get to its Properties, click the Display tab, then click Conditional Formatting and click Add
    • In the first field, click Select a field or group
      • In the Data Source pulldown, select the GetCommonMemberships secondary data source
      • Drill down the dataFields path until you get to DisplayName, which you should single-click
      • At the bottom of this box where it says Select, choose the phrase All occurrences of DisplayName, then click OK
    • For the Operand, choose are not equal to
    • In the last box, click the pulldown and choose Select a field or group, then choose strAdmin from the main data source
    • Lastly, in the Formatting area, check the box for Hide this control

 URG8

Fig 8 – Conditional formatting to hide sections from unintended users

  • Finance Section – Do the same thing as with the Administrators Section except in the last box of the conditional formatting setup, choose strFinance.  This will compare the current user’s list of group memberships with the exact name of the Finance security group, which is what we set the value of strFinance to be.

Now, it’s time to show it in action.  In my scenario, I have two user accounts:

  • Clayton Cobb – I am in the Sharepoint Admins SG but not in Finance
  • SharePoint Tester – He is in the Finance SG but not in SharePoint Admins

I’ll start with SharePoint Tester being logged in (Fig 9) who will open a new browser form (Fig 10).

 URG9

Fig 9 – SharePoint Tester logged in

 URG10

Fig 10 – SharePoint Tester only sees the Finance section

After saving the file as the SharePoint Tester, I will now log in as myself (Fig 11) and open the existing form (Fig 12). 

 URG11

Fig 11 – Clayton Cobb logged in

URG12 

Fig 12 – My account only sees the Administrators section

**After it is all working, be sure to remove the repeating table from your form, or if you decide to show it for some reason, you may want to make that field read-only so that users can’t manually change it.

That’s all there is to it!  You can now leverage Active Directory distributon lists and security groups for providing a mock User Roles functionality in Browser Forms without writing any code and while maintaining Domain Trust. The key here is that when looking at the same form, two separate users will see different information that is available based on their group memberships in Active Directory.  Imagine the other ways you could leverage this by restricting individual controls, whole sections, or even entire views, which is very powerful!

Advertisements

Posted in InfoPath 2007, MOSS 2007 | Tagged: , , , , , , , , , , , , , | 187 Comments »

User Roles in Browser-Enabled InfoPath Forms Using Contacts List

Posted by Clayton Cobb on June 14, 2009


MAJOR REVISION that uses the GetCommonMemberships web method to determine group memberships for users without needing to use contact lists or any other manual data source!

InfoPath – User Roles in Browser-Enabled Forms Using Groups

So, you need to restrict certain controls in your InfoPath form, but it’s browser-enabled, and you just found out that User Roles are not supported, huh?  You also see that SharePoint permissions do not help restrict specific areas within your form, so what do you do?  There are probably several methods, but here is the one I have come up with that uses all built-in functions of InfoPath and MOSS 2007 without any code.

Here is an outline of the steps with the assumption that you already have a working, browser-enabled form:

  1. Contacts List
  2. Add GetUserProfileByName data connection to your form template if not already using it
  3. Add necessary fields to form template and configure them
  4. Add conditional formatting to applicable controls

Contacts List

In this solution, the Contacts list will provide the groupings of users for your “roles” within the form..  Here are the steps:

  • Create a new Contacts List
  • Click Actions > Connect to Outlook (this step only for Office 2007/IE 6-8 users) – Fig 1
  • Populate users from Global Address Book (or manually) – Fig 2 and 3
  • Add any extra columns for sub-grouping of users (i.e. Department) 

Fig 1 – Connecting to Outlook

Fig 2 – Add Contact from Global Address Book in Outlook

Fig 3 – Copy local Contacts to Synchronized SharePoint Contact List

 Fig 4 – Final View of Contacts List Synchronized with Outlook

What we have done is used Outlook 2007’s two-way  integration with SharePoint to ensure that our contact information in the SP Contacts List is exactly the same as what is in Active Directory, and since our profile import in this scenario is pulling from Active Directory, then our user information should all be synchronized.  Notice that I’ve added a Department column to the Contacts list, because this info is in AD, the GAL, and in the SP profile database. Note: other data has been removed but would usually be seen here (email address, phone #, etc).

User Profile Service – GetUserProfileByName method

Now we must add this superb web service to our form template as a data connection.  Please use the first 8 steps of Itay’s writeup to get this done as I can only give him credit for my extensive knowledge of this web service.  Once you’ve added it successfully, we need to do a few things with it using the later steps in Itay’s blog.

Add Necessary Fields to Form Template and Configure Them

First, create two basic text fields in your main data source: strCurrentUserEmail and strCurrentUserDepartment.  Next, drag two section controls to your canvas, and drag both text fields from above (Fig 5).

 Fig 5 – Sample Form Template

Next, we need to get those fields populated with the proper information for only the current user, which means each subsequent user who opens the form will make the data in these fields change accordingly.

strCurrentUserEmail – Tools > Form Options > Open and Save > Rules.  Add an action that sets the strCurrentUserEmail field to the WorkEmail value of the GetUserProfileByName data connection using the later steps from Itay’s writeup.  It should look like this (Fig 6).

 

Fig 6 – Setting field to WorkEmail value

What this does is pull the WorkEmail value from the profile database for the user who just opened the form and puts that email address in our designated field.  We could get this same value using the Default value function button on that field, but this would set the value once for the initial submitter and never change.  I leverage this notion in another field named strSubmitterEmail so that I can also check to see if the current user is the original submitter.

strCurrentUserDepartment – Tools > Form Options > Open and Save > Rules.  Add an action that sets the strCurrentUserDepartment field to the Department value of the GetUserProfileByName data connection the same way you did the previous step for WorkEmail. Note: You can add this action to the existing rule for email.

What this does is automatically pull the department of the current user and put it in the designated field.

Add Conditional Formatting to Applicable Controls

grpIT – Double-click this control on the canvas to get to its properties.  Click Display > Conditional Formatting.  Add a condition with two caveats.  The first will check the contact list against the current user.  The 2nd will check the contact list against the current user’s department.

  • After clicking Add, click “Select a field or group” in the first dropdown.  Change the data source to your Contact List, drill down to the data elements, click on E-mail_Address, and select “All occurrences of E-mail_Address” in the bottom dropdown (most people never notice this – Fig 7).

 

Fig 7 – Choosing All occurrences of a data connection field

For the operand, choose “are not equal to”, and for the last box, choose “Select a field or Group” again.  From your main data source, select strCurrentUserEmail

  • Click the “And” button on the right to add another caveat to the condition.  In this one, select strCurrentUserDepartment from your main data source in the first dropdown, “is not equal to” for the operand, and the text “IT” in the last dropdown.  Be sure to change the “and” on the right to an “or,” and lastly check the box for “Hide this control.”  It should look just like Figure 8.  

Fig 8 – Conditional formatting to hide sections from unintended users

What we are essentially doing is checking to see if the current user is in the overall list of approved users, and then we are breaking it down further to see what department that person is in.  If the current user is not in that list, then the section is hidden.  If the person is in the list but not in the specified department, then the section is hidden.  An alternative way to do the department filter is to make separate contact lists for each sub-group.  If you do it that way, it requires more lists and more maintenance, but it allows you to assign a regular user as the owner of his/her respective list in order to maintain it (removes the burden from us).  If you use one list with sub-categories, then you can’t as easily hand the maintenance over to regular users.

grpFinance – Do the same steps for this section as you did for grpIT except change the text “IT” to “Finance.”  Note: Be sure that the text you type in situations like this is EXACTLY the same as what Active Directory shows.  IT is not the same as it and Finance is not the same as finance.

Here is the final result.  If you reference Figure 4 above, you will see that my department is shown as Finance… 

Fig 9 – Finance user only sees the Finance section

Fig 10 – Manually changed Department to IT (demonstration purposes only)

Fig 11 – IT user only sees the IT section

 

Fig 12 – Log in as SharePoint Tester account

Fig 13 – SharePoint Tester not in Contacts list and sees nothing

**After it is all working, be sure to remove the text boxes from your form for strCurrentUserEmail and strCurrentUserDepartment, because they are only in this example for testing purposes.  You want to make sure you can see the data that is being put in there during testing.  Once it works, remove those text boxes, or if you want to show them, then make them read-only.

This is my first attempt at any blog post, so please feel free to critique and comment on any errors, bugs, typos, mistakes, fixes, questions, or confusions you may think of…

Posted in InfoPath 2007, MOSS 2007 | Tagged: , , , , , , , , , , | 21 Comments »