Creating secured BCS objects with BCS Meta Man
We started using BCS in SP2010 to create External Content Types. This is really a powerfull system, and a huge improvement on the ‘old’ BDC approach.
For a project, I needed something more then just a BCS layer to get all the data. Data is being fetched from a 3rd party backend system in which customer data is stored. That data (customers, contacts, addresses, stuff like that) had to be available in SharePoint for reporting purposes. The entire site was accessible for Active Directory users, but also (and there lies the challenge) for external users. Those external users are all linked to a certain customer, but we definitely don’t want to give them access to the entire customer database!
With a tool called BCS Meta Man by LightningTools, you can generate your entire BCS layer. It’s capable of connecting to a SQL server or Oracle database and using that info to generate either a .NET assembly BCS type, or a ‘regular’ database model file.
Because I needed to add the security somehow, I decided to create .NET assemblies. BCS Meta Man generates a Linq to SQL model based upon the database (I filed in a feature request to change this to a Linq to Entities approach) and then adds classes for the objects you selected for querying. All methods needed for a BCS layer (Finder, Specific Finder, IdEnumerator and also a Creator and Updater) can be generated automatically.
The result is a set of classes which use the Linq model to query the database. You can create all this just by clicking, the tool saves a lot of time.
Ok, now for the security bit. The great thing about those .NET assemblies is that you can use your SPContext object to get the current SharePoint context. It supplies the current user in
Using that (probably the username) you can then apply some filtering in your Linq queries. Since I only needed to filter results for external users, I used the LoginName to check that. The syntax SharePoint now uses is:
I’m not quite sure what the ‘i:0#.f’ part means (probably the first forms auth provider), the second part is your providername and the third part is the loginname. So you can split this string, extract the username and use that to filter your data.
Using the generated classes, you can add custom code which extends the Linq query to add more filtering based on the username (or whatever property you’d like). One catch though: BCS meta man refreshed the entire class when you update your entity, so all your changes will be lost. I asked the guys at LightningTools to implement eventing or partial classes to be able to extend their generated code with your own code. I haven’t received a reply on that yet, but I’m sure they’ll come up with something!