Folders (SPFolder objects) in Sharepoint lists and document libraries can be used to restrict access to its content. I.e. you can assign different permissions to folders so users which have access to one folder will not have access to another. This is quite convenient solution. When you change folder permission settings you have to break role inheritance for this folder so it will not anymore inherit permissions from parent list:
Unfortunately there is an upsetting side effect - Sharepoint doesn’t allow anonymous users to access content inside folders with unique permissions (see http://yvonneharryman.wordpress.com/2007/11/23/follow-up-on-anonymous-access-and-item-level-permissions-from-sharepoint-connections-07). So what should we do if we have requirement that anonymous access has to be allowed to these folders?
In order to avoid this limitation of Sharepoint I made the following workaround: add special account into AD (lets call it email@example.com). Then I force Sharepoint to use this account when non-authenticated request goes inside the folder with unique permissions. The main points of solution are the following:
- Add predefined account firstname.lastname@example.org into AD
- All folders with unique permissions which should be available for anonymous are configured so email@example.com account has Reader permission set on them
- Implement custom HttpModule which analyzes the target URL of http request. If request goes to the folder with unique permissions HttpModule temporary authenticates request with firstname.lastname@example.org. As folders are accessible for this account (see step 2) Sharepoint successfully authorizes this “fake” anonymous request
- At the end of request we “rollback” temporary authentication – so other surface of the site is not touched and works by standard way
The simplified code of HttpModule is the following:
It analyzes request URL (method shouldAnonymousBeAuthenticated()) and based on it authenticates request or leaves it untouched.
Notice that described technique works only for http get verbs. I.e. it wont be work if postbacks should be supported. For last case instead of simple Response.Redirect() you can try to construct HttpWebRequest inside http module and reexecute it with authentication cookies.