Skip to main content

Elumenotion Blog

Go Search

 
Elumenotion > Elumenotion Blog > Posts > Anonymous Access to Add Items to Document Libraries - Solution
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!

Comments

Nice!

I'm famous ;-)

You work fast and created a very nice solution. The trick with global.asax is actuall pretty smart. :-)

Ok, no reason for me to write a blog about it then ;-) I do have a feature to insert the required membership tag in the web.config file. I'll write about that in a couple of days.

Regards
Søren
Anon at 9/18/2007 4:16 PM

FBA ONLY?

This is huge. You should share this with the IEE project folks at CodePlex. If we are to have extranet community sites with WSS3, we will need a way to have anonymous users start workflows.

http://www.codeplex.com/CKS/Wiki/View.aspx?title=Internet%2fExtranet%20Edition&referringTitle=Home

Question: Will this only work for sites set-up with FBA? Or can it work with OOTB sites using NT users?
JMW at 10/4/2007 12:29 PM

NT Users

I'll be sure to check that project out!

You might be able to work this out with NTLM auth if you could figure out a way to have the authentication happen automatically with a principal of your choice. Right off the top of my head I am not sure how you would go about it but I'll think on the problem (maybe a custom http module?)

If Microsoft could just be persuaded to actually make WSS use a real configurable identity for anonymous life would be much simpler.

On the other hand, I think and ntlm site extended to allow fba works pretty well. There are of course issues with the content editor web part, but they can be handled see Dan Attis for eexample, http://devcow.com/blogs/jdattis/archive/2007/09/27/11463.aspx.

I'll be writing a post sometime in the next couple of weeks about why I think you should pretty much always have a backing integrated site extended for FBA. If you agree after you hear me out it might not be an issue.
Doug Ware at 10/4/2007 7:13 PM

Extended for FBA

As an end-user (niskypto dot org), I want to avoid excessive backend modifications to config files and such. I am relying on folks like you and CodePlex to make wsp files or other executables that automate set-ups. Right now, it's a clunky process: (1) Use SharePoint solution's PowerShell extensions to provision an extended FBA site, (2) Follow your recipe to get the Anon thingy running (I'm almost sure I''ll botch this part), (3) Install the FBA parts from IEE at CodePlex or similar... 
JMW at 10/5/2007 10:25 AM

What site is the Authoring Site?

What site is the "Configure the Web.Config of the Authoring Site" are you refering to the Central Administration site?
Anon at 10/10/2007 12:00 PM

DLL?

Doug,

I do not see the AnonymousMembershipProvider.dll in the zip download.

Also, can you tell me where the simple membership provider code goes for Step 1.

I'm basically lost here - not being a programmer.

john at jotsbox dot com
JMW at 10/11/2007 2:58 PM

Updated Download

Thanks for reminding me about that. I updated the zip file to include the download.

The dll is the code for step 1.

Also, in response to the question about the Authoring Site, see above:
"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."

Create a web application for the default zone that will use integrated authentication. Extend it to the other named zone of your choice and set ip to use forms based authentication.

What I called the authoring site is the default using NTLM. This is the site you will use to administer permissions for Anon.

Hope that helps!



Doug Ware at 10/11/2007 3:15 PM

Step 2 --> Step 1

OK, I see. You've done the heavy lifting for Step 1 for us ala DLL file. So Step 2 becomes Step 1 :)

OK, I'm going to try this on a test site!

JMW at 10/11/2007 4:10 PM

CODEPLEX

Hi Doug,

Not had a chance to try this yet. But this seems to be a logical fit to the IEE-FBA work at CodePlex, I added this as a feature request:

http://www.codeplex.com/CKS/WorkItem/View.aspx?WorkItemId=4005
JMW at 10/15/2007 8:51 AM

2 Questions

Is this hardwired for "anon" or can I use "guest" or some other term?

I have my site working with FBA, and already have a number of FBA user accounts. If I implement the "anon change", will it mess-up my other users? Will the have to log-out anon and log back in?

ptowebmaster at niskypto dot org
JMW at 10/25/2007 8:39 PM

2 Questions

Is this hardwired for "anon" or can I use "guest" or some other term?

I have my site working with FBA, and already have a number of FBA user accounts. If I implement the "anon change", will it mess-up my other users? Will the have to log-out anon and log back in?

ptowebmaster at niskypto dot org
JMW at 10/25/2007 8:57 PM

More questions

Do I need to add "anon" to my aspnetdb?

Add this to config?
<SafeControl Assembly="AnonymousMembershipProvider, Version=1.0.0.0, Culture=neutral, PublicKeyToken=701fdd64fcd5ceb2" Namespace="AnonymousMembershipProvider" TypeName="*" Safe="True" />

Any other bits?
JMW at 10/26/2007 6:13 PM

..and more

I feel my thoughts are being sent intro a black hole...no matter, since I already have FBA on my site, I'm wondering if you can just add some bit of code to the global.asax to auto-authenticate one of my FBA users?
JMW at 10/26/2007 9:59 PM

JMW

Sorry JMW, I'm covered up with customers and getting ready for a couple of upcoming classes.

It'll be a few days at the earliest before I'll have time to help you.
Doug Ware at 10/27/2007 7:43 AM

I have a new solution

Doug,

I have a new way to do this that is better! No dll's required.

I have a windows auth site as the default on the server - only I can access this. I extended this two two FBA enabled sites on the Internet, one at the internet zone (mysite.com) and the other at the custom zone (edit.mysite.com). Each one needed a unique FBA Membership Provider, and corresponding aspnetdb. The edit.mysite.com is what my team uses to login via FBA and edit content. They are validated against the first aspnetdb. The other FBA site, mysite.com, is what anonyous users visit. To get these anonyous users auto-logged in, I had to add this bit of code to the global.aspx file "<script RunAt='server'>public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args){FormsAuthentication.SetAuthCookie("Guest", true);}</script>". "Guest" is the only FBA account in my second aspnetdb. On the edit.mysite.com, I had to add the connection strings and memebrship providers for both aspnetdb's so I can add "Guest" to the lists I want him to access.

Hope that's clear?

I'm not a programmer by any means, so there may be a better way. For example, the "guest" at mysite.com cannot ever be logged out at present (due to the global.aspx event at page-load). This is why I had to make the edit.mysite.com site. Maybe there's another trick you can add the the global.aspx code to allow this, and avodi habe to extend the site twice.

But this works!
JMW at 10/27/2007 1:35 PM

Update

I modified the global.aspx file with this new code. Now I do not have to have edit.mysite.com extended. This code (which I found and modified after much googling) allows logoff of the default guest cookie and replaces it with one of my FBA people's cookies. There may be a more robust way to code this, but I'm prertty sure this is close to optimal.

<script RunAt='server'>

protected void Application_Start(Object sender, EventArgs e) {Application["Title"] = "FBA";}

protected void Session_Start(Object sender, EventArgs e) {Session["startValue"] = 0;}

protected void Application_AuthenticateRequest(Object sender, EventArgs e) {string cookieName = FormsAuthentication.FormsCookieName; HttpCookie authCookie = Context.Request.Cookies[cookieName]; if (null == authCookie) {FormsAuthentication.SetAuthCookie("guest", false);}}
       
</script>
JMW at 10/29/2007 9:07 AM

Now at Codeplex

Sorry to fill your blog with my ramblings. I've started a CodePlex project now: http://www.codeplex.com/wssguestaccount
JMW at 10/29/2007 10:33 AM

Same issues and trying your approach

hey there - great post, i thought i was alone with this anonymous user problem..

I have your global.asax working on my environment and everything works as expected but i've been experiencing issues with user permissions that is plain odd and wrong.

I have a membership provider logged in as 'guest' and i've assigned specific permissions to the guest account for subsites and lists in the same site collection all the way down to specific list items / pages etc.

The root level site is administrative and the child sites are where the 'guest' should go. The child sites therefore have broken inheritance to the root to prevent mr. guest from going up to other areas at the root.

Even though I assign my guest user with Visitor access, or specifically assign "Read" permission set levels I have problems.. The user can see pages and even "view all site content" but when accessing form pages (like list views such as AllItems.aspx etc) I get an access denied page.

In some cases I break inheritance on a list and give the 'guest' account full control of that list - still get access denied.

To make matters more interesting, if I log on to the site as the forms based administrator account, then I access those pages, and log out - when i log back in with mr 'guest' everything works as expected...

now when i do an IISRESET and log on back with mr guest, everything's broken again until I sign in with the administrator user...

Have you had an easy intuitive configuration on permissions? what do you think could be wrong here?... I verified that the lockdown feature is not active (which is what i want) but mr. guest just doesnt want to see lists ...
Alex Talarico at 11/13/2007 12:24 PM

Security Risks

Will there be any security risks anyone can think of when using this approach?
Anon at 1/22/2009 12:42 AM

RE: Security Risks

The risk is that people will upload malicious content. You should run anti-virus and also use the content approval features to vet anonymous content.
Doug Ware at 1/26/2009 10:22 AM

Public URL

Hi,

The solution works perfectly. We only have the following problem. We seem to be unable to connect a public URL to the extended site. If we connect the public URL to the authering site, the solution doesnt seem to work.

Are people using ISA server to tackle this? Or can this be solved within Sharepoint or IIS6?

Regards,
Jacob Iedema
Jacob Iedema at 9/4/2009 6:33 AM

Anonymous access to add items in document library

1. goto document library settings > Permissions for this document library > settings > edit settings > should get a prompt that your changing settings > say yes you want to do this > settings > anonymous access > notice the url at the end is 2CDOCLIB.
2. change the end of the url to 2clist and hit enter
3. now you have the settings.

kundan Ghimire at 11/11/2009 12:22 PM

RE: Anonymous access to add items in document library

That will show the option to the screen and select it, but you still won't be able to upload as an anonymouse user.
Doug at 11/12/2009 7:40 AM

Anonymous Access to add items i document library

Thank you very much for the solution. It work's great...
Anon at 2/11/2010 4:02 PM

Very close to working

I have performed the steps suggested.  It seems as though all pieces are in place.  I am still not able to submit to my Library from my Auth Site.  I am not sure what I need to do to debug or determine where it's breaking.  My Auth site is using Windows Authentication.  I extended the Web App and created and FBA site.  I have modified the webconfigs and global.asax accordingly.  I installed the dll into my GAC as well.  The "Anon" user does come up when I assign him to the library, so it seems okay.  But still getting the permissions error message when I attempt to submit a form. 

How can I test to make sure the auto login page is working and the app is being authenticated with the "Anon" user behind the scenes?

Thanks so much for any help that can be provided.
Oscar at 2/21/2010 4:32 PM

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Your Name *


Attachments
Follow me on twitter!
  Archive
  Archive (Calendar)
  Skinner Created Themes
  New Skinner Download
  New Skinner Tutorial

©  2009 Elumenotion, LLC  |   SharePoint Training, SharePoint Consulting and SharePoint Staffing
8075 Cavendish Place | Suwanee, Georgia 30024 | + 1 (888) 653-5021