In my last post, I demonstrated how to enable Windows Identity Foundation (WIF) on a WCF web service and configure it to require a SAML 1.1 “ActAs” token from a SharePoint 2010 server. In this post, I’ll demonstrate how this web service and the data it provides can be integrated with SharePoint 2010 in a manner that supports this security model.
Let’s start with a scenario where we need to surface the sales data stored a SQL database but we want to lock down what the user sees based on their role within the company. Ordinarily, you would have to either implement row-level security in SQL (difficult) or front-end the data using dimensional security using with something like Analysis Services (maybe a bit easier, but still a fair amount of work. Requires Kerberos). These aren’t terribly attractive options. Knowing this, we created a simple WCF service and configured it to be “claims aware” using Windows Identity Foundation (WIF). Since both SharePoint and WCF support WIF, we’d need to move forward with integration.
The component of SharePoint 2010 that will help us here is Business Connectivity Services (BCS). BCS is one of the service applications within SharePoint allows for integration with three types of data: .NET types, SQL data, and WCF services. And it turns out it’s a claims aware application…in a way no different from our custom web service. Microsoft has a nice slide that expresses what this support looks like:
In a nutshell, BCS ensures users are authenticated (using claims in this case) before accessing the External Content Type via a web part. It then brokers the connection to the back end resource. Authentication to the resource could happen in various ways; perhaps using a Trusted System account, Kerberos delegation, the Secure Store, or (wait for it!) claims. Let’s take a look at setting this up.
NOTE: If you want to follow along with this post in your own lab, be sure you review and implement Part 1 of this two-part series.
I’ll start by launching SharePoint Designer (SPD) 2010. After connecting to my extranet site, I create a new External Content Type called “Adventureworks Sales Data”.
Next, I’ll add a new connection with a data source type of: WCF Service.
In the WCF Connection window, the following settings are used:
- Service Metadata URL: http://pbdev.com/WCFService/service.svc?wsdl
- Service Endpoint URL: https://pbdev.com/WCFService/service.svc
Next SPD will validate the connection and add it to the list of data sources. We now have access to all the “get” and “set” methods offered by our web service. We kick off the process by adding a new External Content Type Operation by right-clicking GetCustomerById and selecting “New Read Item Operation”.
At the next window, we’ll define the “customerId” field as the identifier for the record by selecting the “Map to Identifier” checkbox.
We’ll do something similar on the next screen by highlighting CustomerId and clicking the “Map to Identifier” checkbox. We’ll also need to use the drop-down list box for “Identifier” to map it to our previous selection, which was “customerId” with a lower case “c”.
After clicking “Finish”, we need to add a new Read List operation so we can get all customers. This is done in a very similar manner as before.
The only thing we need to do in this case is to add the identifier mapping and select “customerId” as our identifier (lower-case “c” ).
We can now save the External Content type and at this point, it should look like the following:
We need to do some final configuration for our web service connection. This is done by clicking the “Adventureworks Web Service” link just to the right of “External System”. Two things need to be changed here: (1) Enable claims-based authentication and (2) Set the Impersonation Level to “Delegation”.
After saving everything, we’ll next need to add permissions to allow users to view the external content type (see step 5 in the above diagram). This is done by selecting “Manage Service Applications” in Central Admin, highlighting Business Data Connectivity Services, and clicking the Manage icon.
We will then see the external content type and can use the drop-down list box to get to “Set Permissions”
Since this is just a demo, I’m going to select the magnifying glass in the User Picker so I get the option for “All Authenticated Users”.
And I’ll grant “All Authenticated Users” “Execute” and “Set Permissions” rights.
Now, we should be able to load our list of customers from SharePoint.
To see what’s going on under the hood, open the WCF service in Visual Studio 2010 and set a breakpoint at line 37 or 38 of Service.cs.
You will be able to inspect either variable and see the user’s claims. In this example, you can see I’m accessing the list data using a federated account (OpenID) with a special user role of “Program Blue Contributor”.
Now that I have SAML 1.1 token delegation working, I can enhance the authorization logic within the web service to only return data relevant to users holding certain roles within the organization (“Program Blue” as an example).