SharePoint 2010 Business Connectivity Services (BCS) – Breakdown of Authentication Modes and other Security ConsiderationsPosted: April 5, 2010
The Microsoft Business Connectivity Services Team Blog is quickly becoming one of my favorite SharePoint blogs. Their most recent posting, Authenticating to Your External System, does an excellent job of breaking down the available authentication modes available.
Security is one of the most important things to consider when connecting to external systems using Business Connectivity Services, and this article is a great place to get started. Check it out at: http://blogs.msdn.com/bcs/archive/2010/03/12/authenticating-to-your-external-system.aspx
There are several good posts out there providing examples and step by step instructions on how to create external content types with SharePoint 2010 BCS. Unfortunately most fail to provide any warnings or guidance around Authentication; which should be, without a doubt, one of the most important things to consider. Most of these examples work flawlessly… until you try to view your external content type with another user account lacking some sort of access to the external system; and you encounter an error that resembles the following: Cannot connect to the LobSystem (External System)
Fortunately, the solution is likely simple… But you’ll have many thing to consider; what kind of access you need to grant to which accounts, do those accounts need to be mapped back to equivalent accounts in the external system, whether or not to map AD groups rather than individual accounts to accounts in the external systems, and many more that will quickly become apparent fairly quickly.
Of course if you are reading this post, you’ve likely ran into the error and are looking for a solution. Unfortunately there isn’t a one size fits all, and I wouldn’t necessarily consider it an error; more of a warning, a heads up, that you may have not thought the whole thing through. This will definitely be a subject upon which many best practices will come to surface. But, while I can’t give you the right solution for your particular scenario (there are many ways to skin this cat;) I should be able to point you in the right direction.
Chances are that if you followed one of the many posts which describe how to do this, you chose “Connect with User’s Identity” when creating your connection.
You’ll quickly come to realize that in most scenarios not all users have direct read or write access to external systems, often times they don’t even use a Windows Identity. Fortunately, our solution (or at least part of it,) is right under our noses:
If you are wondering what the Secure Store Application ID is, it refers the Secure Store Service, which you’ll want to do some reading on. I recommend you start here (http://msdn.microsoft.com/en-us/library/ee557754(office.14).aspx) for a short but good description, and follow up here (http://technet.microsoft.com/en-us/library/ee806866(office.14).aspx) for detailed steps on how to set it up.
Essentially, you’ll need to create a Secure Store Service Application of type “Individual” or “Group” with several options for each. An application of type “Individual” will require you to map each user to a unique set of credentials (there is an option to create a page from where users can specify there own credentials.) An application of type “Group” will allow you to map a unique set of credentials to a specific AD Group; I suspect this will be the most common scenario.
You’ll then be prompted to configure the various fields which may be required to provide credentials to the external data source. If the external system uses Windows Authentication, the default ones should work just fine.
Next, you’ll need to specify the administrators and members of the target application (read the description of each carefully)
Finally, select your application and specify the credentials that will be used to connect. The Secure Stored Service Application will use these credentials whenever anybody from the specified group tries to connect to the external system.
Now, reconfigure your connection to use the ID of the Secure Store Application in my case “My Secure Store Application”, perform an IIS Reset, and you are likely done.
If by any chance you are not, and instead you receive: “Access denied by Business Data Connectivity.” You’ll need to go to Central Admin > App Management > Manage Service Applications > Business Data Connectivity; and grant your users access to your External Content Type.
Let me start by saying that while executing code via RunWithElevatedPrivileges may help you overcome certain “access denied” exceptions in your code, using it should be the exception not the norm. This is not meant to be a “how to” posting on RunWithElevatedPrivileges, there are plenty of articles out there that already cover just that. Instead I’d like to focus on a subject that I consider to be just as important; when is the right (and wrong) time to use this command.
I recently wrote an article for the MSDN on “Securing Application Pages for Windows SharePoint Services 3.0”. In it, I provided several code samples on how to do just what its title implies; some of which included calls to RunWithElevatedPrivileges. A respected colleague was quick to point out a concern; that some of the information contained in the article (specifically references to RunWithElevatedPrivileges) might result in certain individuals using the command without giving it sufficient thought.
The very reason I wrote the article, stems from how often I’ve seen this command used, and the security risks it presents. I’d hate for the article to be seen as a case or excuse for calling this command, when in large part is the very thing it tries to protect developers from.
SharePoint provides a very extensive and well thought out API, at least from a security standpoint . It uses impersonation, meaning that the code you write will execute under the context of the user viewing the page where your code resides. If you write a web part or application page that reads or writes information from a SharePoint List, Library, or Site that does not grant the user such rights; your web part or application page will throw an error… as it should. Your first instinct should not be to rewrite your code so that this logic executes via the RunWithElevatedPrivileges command. Doing so might be considered a hack.
That’s not to say using RunWithElevatedPrivileges is a “hack” every time, there are certain unique cases where you don’t have much of a choice. But first consider checking if the user has the necessary permissions via the DoesUserHavePermission method of either the SPSite, SPWeb, SPList, or even SPListItem your accessing with your code, and avoid doing anything further on that item if the method returns false for the required permission level. Alternatively (although often cause for debate) consider handling the access denied exception. Ultimately, don’t hurry too much writing your code, the quickest way is not always the best way.
Happy Coding. Oh.. and thanks for the pointer Matt.
An article I recently wrote has just been published on MSDN. It covers the basic principles of securing application pages, and why they are often at risk; as well as providing code samples on how to properly secure your application pages, including:
- How and when to validate page requests
- How to verify Base Permissions
- How to verify Role Definitions
- How to verify Group Memberships
Not to be confused with SharePoint groups; Roles, also known as Permission Levels or Role Definitions, are logical groupings of base permissions. These are typically assigned to SharePoint Groups but can also be assigned to individual users. Some samples of out-of-the-box roles or permission levels include; Read, Contribute, Design, Full Control, and Limited Access.
The following code demonstrates how to verify if the current user is in a particular role or has been assigned a specific permission level. The code sample uses SPContext.Current to get a reference to the current site, as such it must be ran under the context of SharePoint (in a web part, or custom application page), to run the code in a console application or windows application you will need to change how the reference to the SPWeb object is obtained.
So, I’ve been asked about this subject several times (this being; how to give specific users full control over a web application.) The topic usually comes up when administrators or support personnel find themselves unable to access specific content in SharePoint, sometimes because they should not have access to the content (such as confidential HR documents, or the Clam Chowder Recipe at Monterey’s Fisherman’s Warf), and other times because an unknowing user with way too many privileges accidentally removes the administrators permissions from the site collection (this behavior is by no means a bug or limitation of the system, it is by design.) Either way there is an easy fix and way to get around this restriction: Policy for Web Application.
Policy for Web Application is a link located in Central Administration > Application Management under the Application Security section. It essentially allows farm administrators to create security policies allowing them to override standard SharePoint permissions for all sites in a web application, for any or all web application zones, regardless of what permission are given (or denied) at the site collections or sites.
You will find that some accounts are automatically given rights, typically the NT AUTHORITY\LOCAL SERVICE and the Search Crawling/Content Access Account. Be careful not to remove these. The Search Crawling account will automatically be given Full Read access, it needs it to properly crawl content.
A brief how to can be found at: http://technet.microsoft.com/en-us/library/cc179366.aspx