I was exceedingly excited to think about using Sharepoint 2007 (MOSS to some) as our Internet facing site. I had written the code for our previous site in Cold Fusion over the a few years and was looking forward to laying down that burden...
MOSS seemed to have almost everything we did, plus a whole lot more. Imagine my surprise when I discovered that as an Internet-facing site it leaves a lot to be desired (and that at $40k). Now imagine me staying up until 2am for a few nights running trying to find solutions. Now imagine me blowing milk out my nostrils... maybe not...
For a variety of reasons (which I will not go into here) I selected a "Publishing Site with Workflow". Those of you who have worked with MOSS know that this automates LOCKDOWN on all Lists so that Anon users can not view them. What they don't tell you is that no matter what you do, even if you give them permissions to VIEW the list, they can not ADD to the list.
Now this is a problem because one of the reasons (among many) that I chose Sharepoint was their integration with Infopath to easily create and publish forms. Now I was discovering that anonymous users could pull up the form, they just could not submit it. Unless, of course, we allowed them access to all the forms. The reason seems to be tie back into Sharepoint's rather complex permission schemes. There are actually three areas that need to be checked for permissions, sort of like three distinct committees. Each has a stranglehold on one area and one type of connection. Since Sharepoint does not recognize that there can be a variety of Anonymous users, and it can not distinguish them, it becomes all or nothing.
I have tried a number of solutions - note these rather creative solutions -
So, I am desperately asking, WHAT DO I DO????
Basically you must
- setup a separate IIS Web App running a Webservice (it does not need to be exposed externally)
- Write a webservice to handle this (it will use identity impersonation and the app pool account to convince the List that you really ARE someone).
- Muck with InfoPath forms to pass the necc data to the webservice when submitting to it.
I must admit I probably would never have thought of this - so big thanks to Nezih Tinas! I love techies on the web!!!
So here (as an example) is my very simple webservice code
<%@ WebService Language="C#" Class="AnonFormSubmission" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Security.Principal;
using System.IO;
using System.Text;
using Microsoft.SharePoint;
[WebService(Namespace = "
http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AnonFormSubmission : System.Web.Services.WebService {
[WebMethod]
public void SubmitToFormLibrary(string siteName, string webName, string formLibraryName, string formXml)
{
WindowsImpersonationContext wic =
WindowsIdentity.GetCurrent().Impersonate();
string formName = Guid.NewGuid().ToString();
using (SPSite site = new SPSite(siteName + "/"))
{
site.AllowUnsafeUpdates = true;
using (SPWeb web = site.OpenWeb(webName))
{
SPFolder folder = web.GetFolder(formLibraryName);
foreach (SPFile file in folder.Files)
{
if (file.Name.Replace(".xml", "") == formName)
throw new Exception("File name exists.");
}
folder.Files.Add(formName + ".xml", UnicodeEncoding.UTF8.GetBytes(formXml));
web.Dispose();
}
site.Dispose();
}
wic.Undo();
}
}
Note 1 - If you are tweaking this, remember to either use
Dispose your Web and Site objects or do the using container (which Disposes of them for you). Otherwise you will start hemorraghing memory. I am paranoid and do both. Incidently Disposing will automatically Close.
Note 2 - I use a random GUID to create the Form name because it must be unique, but as long as you make sure it is unique you should be good to go.
Note 3 - You will need to tweak your web.config (at least I did) to include a username/password that has permissions. This does not need to submit to the web app extension that is Internet facing (I submit it to the root app which using NTLM since it all goes into the same list and then use an NTLM account that I know has access). Ex:
<compilation debug="false">
<assemblies>
<add assembly="Microsoft.SharePoint,
Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71E9BCE111E9429C"/>
</assemblies>
</compilation>
<authorization>
<allow users="?" />
</authorization>
<identity impersonate="true"
userName="myDom\myUser"
password="mypassword" />
<authentication mode="Windows"/>
This should enable you to submit to that list as myDom\myUser. You can encrypt the web.config to be paranoid. Remember, paranoia is not a problem in IT, it is a job requirement.
You can follow Nezih's directons for creating the infopath form. I should note that this will have to be an administratively approved form.
WAIT!!! You're not done!!!
What you then need to do is go into the form library that you want to submit it to and set this up as the default form. Then you can use all these nifty fields in whatever view you want!!! Plus you have to modify the form library itself to not launch it as Infopath. Then you will want to grab the URL. O, and DON'T FORGET TO CHANGE THE TIMEOUT SETTINGS FOR INFOPATH!!!