Anonymous Access to Add Items to Document Libraries – Solution

Yesterday I received a comment from Søren Nielsen on my earlier post on this subject:

"Hi

We have had the same problem as you – SharePoint don’t seem to be designed to have any interaction with anonymous users.

We did:
1. created an ordinary SharePoint site
2. extended the site and enabled forms authentication on the new site, using our very own custom build forms authentication, that just handles one "Guest" account
3. Gave the new Guest account proper rights to the list in question
4. Create a auto login page
5. Connected the dots, and the anonymous user is now signed in as Guest (through our own forms authentication provider) and can do whatever we grant the Guest the liberty to.

I’m not (yet) at liberty of sharing the exact solution.

Hope it helps.

soerennielsen.wordpress.com"

This is a much better solution than the one I was contemplating because it solves a wider range of issues than simply mucking about with the lists in question!

I was able to refine the approach slightly by simply using an event in global.asax instead of creating an auto login page as Søren suggests for step 4. You can now upload themes to the theme library!

Here is a brief overview of the solution. It assumes a basic understanding of membership providers and forms based authentication as it relates to SharePoint. And it assumes you have already created a site and extended it so that you have two zones, one for the public and one for authoring. If you don’t know what I mean by that, you need to do some reading before going any further. Here is an excellent article on the subject by my friend Dan Attis.

You can download the code and example configuration files here.

Step 1. Create a simple membership provider

All we want to do is create a named identity for our anonymous web friends that we can use to assign permissions. This makes the membership provider very simple. Aside from telling the site that the name is valid we need it to also return a list containing the anonymous user in a few methods so that the people picker works and so we can actually add the user to the site.

The complete code is available in the downloads section, but here are the applicable snippets.

public class AnonymousMembershipProvider : MembershipProvider

{

//If the user is named "Anon" it is valid. Otherwise something funny is going on!

public override bool ValidateUser(string username, string password)

{

if (username == "Anon")

return true;

else

return false;

}

 

//Create a MembershipUserCollection consisting of our single user.

private MembershipUserCollection GetMembers()

{

MembershipUserCollection users = new MembershipUserCollection();

users.Add(new MembershipUser("AnonymousMembershipProvider", "Anon",

"Anon", string.Empty, string.Empty, string.Empty, true, false,

DateTime.MinValue, DateTime.MinValue, DateTime.MinValue,

DateTime.MinValue, DateTime.MinValue));

return users;

}

 

//These mthods are used by SharePoint to get names for People Picker

//and to validate the name when adding it to People and Groups.

public override MembershipUserCollection FindUsersByName(string usernameToMatch,

int pageIndex, int pageSize, out int totalRecords)

{

totalRecords = 1;

return GetMembers();

}

 

public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)

{

totalRecords = 1;

return GetMembers();

}

 

public override MembershipUser GetUser(string username, bool userIsOnline)

{

return new MembershipUser("AnonymousMembershipProvider", "Anon", "Anon",

string.Empty, string.Empty, string.Empty, true, false,

DateTime.MinValue, DateTime.MinValue, DateTime.MinValue,

DateTime.MinValue, DateTime.MinValue);

}

 

public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)

{

return new MembershipUser("AnonymousMembershipProvider", "Anon", "Anon",

string.Empty, string.Empty, string.Empty, true, false,

DateTime.MinValue, DateTime.MinValue, DateTime.MinValue,

DateTime.MinValue, DateTime.MinValue);

}

Step 2. Install the AnonymousMembershipProvider to the Global Assembly Cache

 

1.

2.

3.

4.

 

Step 3. Configure the Web.Config of the FBA site

In the <SharePoint> section configure a key for the people picker:
<PeoplePickerWildcards>

<clear />

<add key="AnonymousMembershipProvider" value="%" />

</PeoplePickerWildcards>

Configure <system.web> as so:

<authentication mode="Forms">

<forms loginUrl="/_layouts/login.aspx" />

</authentication>

<identity impersonate="true" />

<authorization>

<allow users="*" />

</authorization>

<membership defaultProvider="AnonymousMembershipProvider">

<providers>

<add name="AnonymousMembershipProvider" type="AnonymousMembershipProvider, AnonymousMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=701fdd64fcd5ceb2" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />

</providers>

</membership>

If you know your web.config you may have noticed that this site is still configured for anonymous access. The next step will assign our named "Anon" user during the authentication.

Step 4. Modify Global.asax on the FBA site to Log in as Anon

<%@ Assembly Name="Microsoft.SharePoint"%>

<%@ Application Language="C#" Inherits="Microsoft.SharePoint.ApplicationRuntime.SPHttpApplication" %>

 

<script RunAt=’server’>

 

public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)

{

if (Membership.ValidateUser("Anon", ""))

{

FormsAuthentication.SetAuthCookie("Anon", true);

}

}

 

</script>

Step 5. Configure the Web.Config of the Authoring Site

In the <SharePoint> section configure a key for the people picker:
<PeoplePickerWildcards>

<clear />

<add key="AnonymousMembershipProvider" value="%" />

</PeoplePickerWildcards>

Configure <system.web> as so:

<authentication mode="Windows" />

<identity impersonate="true" />

<authorization>

<deny users="?" />

<allow users="*" />

</authorization>

<membership defaultProvider="AnonymousMembershipProvider">

<providers>

<add name="AnonymousMembershipProvider" type="AnonymousMembershipProvider, AnonymousMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=701fdd64fcd5ceb2" connectionStringName="LocalSqlServer" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="true" applicationName="/" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="1" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />

</providers>

</membership>

Even though the authoring site is configure to use Windows authentication, we still need access to the provider so that permissions can be assigned.

Step 6. Configure the Permissions

On the authoring site, do the following.

1.

2.

3.

4.

 

That’s it! If the SharePoint gods are smiling on you, you can now allow anonymous type folks to upload files, add attachments to lists, and generally have more control over your anonymous permissions!

Author: Doug Ware