Content Security in SharePoint

Security is a polarising topic in the SharePoint community. It seems that everyone has a slight variation to what would be considered a best practice approach to implementing security across a site. There are so many conditions that determine which approach would be the best to use that it’s difficult to outline a best practice approach in the first place. This article, while filed under the Best Practices category, should only be considered my personal best practice approach to implementing a security model across a SharePoint 2007 or 2010 site.

If you have the time, there is a tonne of background reading to get through on the subject. Technet includes pages dedicated to both versions of SharePoint including Security and protection for Office SharePoint Server 2007  and Security and protection for SharePoint Server 2010. In this article i’m focussing on securing site content which is more specifically targeted in the Downloadable book: Security for Office SharePoint Server 2007 and Security planning for sites and content (SharePoint Server 2010).

I’ve always favoured a simplistic approach to site security. I used to advocate maintaining security groups in active directory, assigning those security groups to SharePoint groups and then assigning the relevant permissions to those groups across the site where necessary. The premise behind this methodology was to have one source of truth (AD) which was often maintained more religiously when staff joined or left the organisation. It was to allow a ‘set and forget’ approach to security within SharePoint – the security across the site would ideally never change, only the staff members assigned to the security groups. In reality, this approach is far too idealistic.

I’ve since realised that a lot of the time the security methodology will be largely influenced by the context of the organisation. Security groups may make a lot of sense throughout the organisation, but they may not map ideally to the SharePoint site. Some organisations may not and will not assign email addresses to security groups which renders them a tad ineffectual when it comes to workflow notifications. Some will refuse to create SharePoint-specific security groups in AD altogether. AD maintenance may be carried out solely by an over-worked IT department at a low priority, so getting a particular user added to a group may take longer than necessary. Or you may want to display the members of a given site using the Site Users web part and notice you end up with the security group listed rather than the individuals (there is a way around this in SP2010 however, check out Robi Voncina’s Display members of AD group in SharePoint 2010  solution on CodePlex). You get the idea – there’s not necessarily a one size fits all approach that will work in every scenario.

There are however a few golden rules which can be followed with a few potential caveats to implement a solid security methodology across a site.

1. Plan your security

One of the biggest issues with security in SharePoint is it seems to be done ad-hoc initially and grows wildly once the site is live. Security is granted on an as-needed basis with little fore-thought which generally results in a sprawling mess which is hard to track and maintain. Initially the security implementation should be well thought out and planned – identify the levels of access required, the users which will need those levels of access and identify the logical groupings of those users. When security needs to be modified, assess how the change fits in to the initial model and implement the most logical option to affect the change.

2. Document your security

This is particularly important in terms of tracking the customisations to security – preferably everything should be documented. It allows you to have an over-arching view of what is in place – determine what users have access to which portions of the site – something which is otherwise difficult to ascertain. At the very least where ever inheritance has been broken should be clearly identified, especially at more granular levels such as list or item level security (which preferably should be avoided).

3. Inherit permissions where ever possible

Aside from making the job far easier for point 2, it really keeps the security structure a lot more clear and clean to identify which users have certain levels of access across the site. Breaking inheritance at the sub-site level is not too much of a concern but at the list and item level should be avoided if possible. SharePoint helps out in this regard seeing inheriting permissions is the default.

4. Always use SharePoint groups when applying security across a site

You may not be able to only use AD security groups as identified above, but you should always use the SharePoint groups. Permissions should only be assigned to these groups rather than individuals – you are able to add both AD users and security groups to the SharePoint groups. It keeps everything a bit neater and consistent across the site rather than having some SharePoint groups, some security groups and some individuals. It’s worth preventing group-sprawl if possible – maintaining as few logically seperated groups as possible will ensure ease of maintenance.

5. Use AD security groups where appropriate

I still prefer using security groups to keep the SharePoint security structure clean and concise – but only when it makes sense to do so. Leverage the Domain Users group to provide global read access across a site for instance.

6. Use the principle of least-privilege

This is just good practice in all forms of IT. No user should ever have access to functionality that they don’t need. I’ve seen plenty of implementations which give site ownership to a wide range of users so they can edit a particular page of a sub-site, then wonder where a certain list item disappeared to.

The goal for any security implementation should be simplicity, understandability, maintenance efficiency and most importantly effectiveness in securing the content. The best way to get there is to plan and document the approach, for the time invested in the beginning will save a lot of headaches moving forward.

301 vs 302 Redirects in SharePoint

Recently I was faced with the request to implement some permanent 301 redirects for a publically facing SharePoint website. It was more of an investigative request rather than a call for action and as yet there has been no resolution, so rather than presenting a solution to the issue, this post will serve more as a discussion around it.

Rather than focus the article on the differences between a 301 and 302 redirect I’d rather point you in the direction of some existing resources that explain the details better than I could myself. The article Redirects: Permanent 301 vs. Temporary 302 does a good job in doing so.

The main concern around the 301 vs 302 redirect in SharePoint is 2-fold. Predominantly, there is a lot of information floating around the net in regards to the SEO implications of the 2 redirect techniques. To cut a long story short, 301 redirects are generally preferred from an SEO standpoint to 302 redirects. The problem being, SharePoint uses 302 redirects for its ‘Redirect Page’ layout. You can get a more in depth explanation of this in Jeff Cate’s post MOSS for Internet and 301 Redirects.

Those wanting to implement 301 redirects rather than the default 302 redirects are left with 2 main options. Firstly, IIS can be used to re-write the URLS (which serves as a 301 redirect). This can be done natively via an add-on in IIS7 and with a 3rd party add-on in IIS6. Secondly, the option exists to write a custom HttpModule to perform the 301 redirect as per Waldek Mastykarz’s post on Using 301 instead of 302 redirects. Waldek’s post is focussing more on another MOSS 302 redirect phenomenon rather than the Redirect Page layout but the concepts are still applicable.

I have a bit of an issue with both solutions. I should be attracted to the custom code option being a developer by trade, but from a complexity and maintainability point of view it doesn’t really appeal to me. It may be possible to architect a solution whereby the redirects are maintained in a SharePoint list improving the functions extensibility, and that’s probably the angle I would have looked into had time allowed, but it still seems like a bit of an overkill considering the IIS solution existed. The problem with the IIS solution however is (aside from it not being native in IIS6 which was being used in my instance) that maintenance would need to be conducted on the server by IT rather than the site owners.

Jeff posed the question in his post ‘Will it be in SharePoint 2010?’ – unfortunately, the answer is no. Waldek points out in a follow up post Using 301 instead of 302 (without code!) that they can be handled in IIS7 (required for SharePoint 2010) natively, which is true and how Jeremy Thake at NothingButSharePoint implemented their 301 Redirects in IIS7.5, but doesn’t solve the issue of giving access to site owners to perform the function. You really don’t want this administrative overhead placed on IT.

To be honest in my opinion we seem to be left with no ideal option. It would be nice (but still not ideal) if 301 redirects could be set and maintained via Central Administration (at least ensuring server access would not be necessary). It would be even better if they could be set and maintained in the Site Settings of the relevant site. Better still, an option on the redirect page to indicate whether it should be a 301 or 302 redirect would be perfect.

For now we’re left with the options presented. Having a personal interest in SEO myself it would be nice to see future versions of SharePoint tailored towards this goal in anyway possible, and making it easier to perform 301 redirects out of the box would be one way of getting there. Assuming SharePoint vNext is based on .NET 4.0 we should be a lot more likely to have this feature considering the 301 Redirects in .NET 4.0.

If it so happens that this piece of work is given the green light i’ll post a follow up on how the solution was achieved.

Application Settings in SharePoint

One of the most commonly neglected features in SharePoint I find across a number of different projects is the manner in which application settings are managed. Far too often it is left to manually modifying the <AppSettings> section of the web.config file for the relevant web application. Perhaps this is due to legacy behaviour of ASP.NET developers moving into the SharePoint sphere, perhaps its due to environments being small and the risks of manually modifying the file not being exposed. It may be due to organisational process or procedure, or (most likely) it may be because on face value it appears to be the most simple, quick and easy option to maintain some configuration values.

It’s ironic that in projects laced with features and solutions to deploy resources ‘the right way’ that configuration is overlooked and remains a manual process. Aside from wanting to avoid any manual modification of files directly on the server by principle, dangers exist in terms of ensuring the web.config files are the same on all web front end servers. Maintaining application settings this way also requires access to the web.config file (and hence server) itself which wouldn’t be considered best practice, and the act of changing a variable in the web.config directly would cause the application pool to refresh and cause the site to load slowly on the next hit.

I write this post with a tinge of regret – I too have been guilty on multiple occassions of maintaining the status quo and leaving (and even adding to) configuration values maintained manually in a web.config file. So not only should this post serve as a source of information regarding the best practice methods to maintain application settings, but it should also serve as a motivator to myself and others to practice what I/we preach on all future greenfield projects.

Anyone who has studied for or taken the application development exam (70-576) would have noticed that 4 main options consistently get presented for application configuration: web.config, lists, property bags and the hierarchical object store. I’ll discuss each option briefly and provide some situations where the method would be appropriate.

Web.config

Now it may seem like i’m beginning to contradict myself here – I previously mentioned that manually maintaining application settings in the web.config was a BAD idea. It is. The beauty of SharePoint though is that it provides a mechanism to maintain application settings in the web.config file automatically via the SPWebConfigModification class. If you’re wanting to store them in the web.config, then a feature should be created which on activation uses the SPWebConfigModification class to modify the web.config for you. This ensures that the same values are written to the web.config files on all front-end web servers and even ensures they’re consistent amongst new servers added to the farm.

You’re likely to want to use this option if you just can’t pull yourself away from the web.config for variable configuration. At least its a safer method. There are some valid reasons however – it’s reasonably simple to incorporate this functionality and then easy to program with seeing you’re probably used to it already. It ensures values are consistent across all front-end web servers and are available and consistent across the entire web application. It’s also fairly useful for ‘set and forget’ the values – if you’re unlikely to need to change them in the future, then you won’t run into the application pool refresh issue I mentioned previously and will get the performance benefits of the cached settings.

Before running off and using this method however, be warned that the web is littered with issues and problems with using SPWebConfigModification. I’d probably want to avoid making any ‘unnecessary’ changes to the web.config especially for the purposes of setting configuration values considering there are other options available.

SharePoint lists

It almost seems too easy and obvious. SharePoint provides us with these useful things called lists. Most of us would be familiar with or have used database-driven variable configuration mechanisms before. Lists, on face value, are reasonably similar to database tables. Why don’t we use lists for variable configuration? It’s not actually that silly a proposition and is in fact one of the more reasonable options. One of the beauties of using lists is that you get all that SharePoint listy goodness. Versioning, security and an out-of-the-box UI for example. You’re likely already familiar with list-based programming, so that isn’t too much of an inconvenience.

Using SharePoint lists is definitely one of the preferred methods. It’s probably easier to outline some of the reasons why you may not want to use it; a site with lax security restrictions would probably be wise to avoid this method – you wouldn’t want any user being able to modify or delete configuration items or the list itself. If you wanted the application settings to be available to multiple site collections/web applications then you’d potentially end up duplicating the list values across these sites.

There’s another huge advantage to choosing this method. An MVP named Chris O’Brien has written a Config store framework available on Codeplex which makes the option even more attractive and erases some of the drawbacks from choosing it. I’d definitely recommend reading a bit about it in his post A better Config Store for SharePoint sites.

Property bags

This option is perhaps a little less obvious but similarly powerful. A number of SharePoint objects contain a Properties property which stores a collection of key/value pairs. These obviously lend themselves towards being used for storing application settings.

This option is possibly the best one to harness when scope is an important consideration for configuration. It lends itself to being able to maintain numerous variables with different values on a per-scope basis (per web, per web application and so forth).

Like the SharePoint list option, this also benefits from addons which improve the usability and effectiveness of the option. The SharePoint Guidance Library provides the Application Setting Manager which is an API to read and write application settings. Codeplex also has the SharePoint Property Bag Settings project which provides a GUI in Central Administration to manage the settings.

Hierarchical Object Store

This is a farm-scoped store similar to a property bag. It requires custom code to create and is far more complex than the other options, however has the benefit of being able to store more complex types if that’s neccessary. Generally for the purpose of variable configuration though, in my opinion i’d go for one of the other options.

You’d possibly choose this option if you were looking for a global storage option for values or required complex values to be stored. If the values are simple key/value pairs however a farm-scoped property bag would probably be easier to use and do the trick.

WebPart properties

I know I said before there were 4 main options, but I wanted to briefly cover this one too. In the event that your custom web parts require configuration values specific to the web part then it will often make sense to include custom properties editable in the web part itself – they are then able to be set by modifying the settings of the web part.

My initial concept for this post was to include an array of advantages, disadvantages and code samples on each option to more completely highlight where each could be used and how they’re used, however during my research for this post came across an MSDN article written by David Mann titled Managing Custom Configuration Options for a SharePoint Application – it essentially covers in reasonable detail those points and I would strongly recommend reading.

Overall I’d have to say I prefer the SharePoint list method the best. I’m somewhat surprised, I remember thinking a while ago that using lists for application settings would be a bit primitive and that surely the other options which have been provided (obviously for the purpose of variable configuration?) like SPWebConfigModification, SPPersistedObject and the Properties collections would be the best practice method to use. I guess sometimes the easy option actually is the best, and it’s sandbox-friendly to boot.

Follow

Get every new post delivered to your Inbox.