Archive for August 2008
Enabling Anonymous Access on an Internet-Facing MOSS Portal
If you are using the publishing features of SharePoint on an internet-facing portal, you probably need to enable anonymous access.
It’s a quick two-step process:
A. Edit Authentication Providers
- Go to Central Administration and then Application Management.
- Under SharePoint Web Application Management click Web application list.
- Select the web application on which you want to enable anonymous access.
- Under Application Security select Authentication providers.
- Click the zone you want edit (probably Default).
- Check the box Enable anonymous access and click Save:

B. Enable Anonymous Access at Site Collection Level
- Go back to your site and go to Site Settings – at site collection level.
- Under Users and Permissions click Advanced permissions.
- In the Settings drop-down menu select Anonymous Access.
- Click Entire Web site (or whatever applies to your setup) and click OK:
Remember, hardening your internet-facing MOSS installation is essential to shield your portal against intruders.
ViewFormPagesLockDown Does not Kick In
Hardening your internet-facing MOSS installation is essential to avoid attacks. Check out Microsoft’s excellent guide which takes you through most of the steps required to shield your portal against intruders.
However, if your portal wasn’t born as a publishing portal, all anonymous users will have access to AllItems.aspx, DispForm.aspx and other pages that you probably don’t want outside users to see. For instance, you may have created a newsletter signup web part which posts data to a list (using elevation). In time, the list fills up with more or less sensitive information about your newsletter subscribers and you probably don’t want this information to end up in the wrong hands.
Unfortunately, it is quite easy for someone with just a litte SharePoint experience to guess the path to e.g. the AllItems.aspx page of a SharePoint list:
And if your portal is not locked down, all list items will be there for the taking.
ViewFormPagesLockDown
Stsadm comes to the rescue yet again. To activate the lockdown, simply run this stsadm command:
stsadm -o activatefeature -url <site collection url> -filename ViewFormPagesLockDown\feature.xml
If you get the “Operation completed successfully”-message, you’re in business.
Well, almost…
The final step
You’ll probably find that the new feature still hasn’t kicked in. Fear not, you simply need to deactivate and reactivate anonymous access on the portal.
Elevation: Run Code as an Administrator
Sometimes you may need your web part to perform tasks for which the current user doesn’t have priviliges. For instance, we needed a sign up form for our WCM web site where the user could enter contact information that should be stored in a list.
Naturally, our web site runs with anonymous access and the the anonymous users do not have access to the underlying lists, including the list where the contact information goes.
Thus, submitting to the list is not just a matter of doing an Items.Add() because this causes a login dialogue to pop up and ultimately a 401 Unauthorized error.
Normally you’d create an element in the list with code similar to this:
However, if the logged-in user doesn’t have sufficient credentials to write to the list, a login dialogue will pop up.
Run with Elevation
To get around this problem you can use SPSecurity.RunWithElevatedPriviliges() like this:
For this to work, you need to instantiate the SPSite and SPWeb objects inside delegate():

Now the list will be updated with a new element, created by the system account.
UserProfileService Web Service Returns Multiple Instances of User Profiles with Identical Names
The lack of a built-in overview of all users in SharePoint makes it difficult to create a simple phone book of your company’s employees. The object UserProfileManager would be the obvious starting point if you were to create your own phone book for SharePoint – and many have tried this. Google this object and you’ll find that the only real way to query all users effectively is using the built-in web services of MOSS.
Specifically, UserProfileService (http://server/_vti_bin/userprofileservice.asmx) is ideal for querying user profiles from e.g. within a web part.
In Visual Studio, when you’ve set up the web service, you connect to the web services like so:

Then, you can query the number of profiles in the user profile database by calling the method GetUserProfileCount:

Knowing the number of user profiles, you can iterate through them and pull the user data:

Some names show up several times
You will find, however, that GetUserProfileByIndex only holds information about users whom have active MySites. Strangely enough, even if the total number of users exceed the number of users with MySites, you can still iterate through all the user profiles you found with GetUserProfileCount.
Say, you have the following people in your User Profile database:
1 – Ted Pattison
2 – Liam Cleary
3 – Amanda Murphy
4 – Yvonne Harryman
5 – Steve Pietrek
Let’s assume that Amanda and Yvonne don’t have MySites. Then the output of the above loop would look like this:
1 – Ted Pattison
2 – Liam Cleary
3 – Liam Cleary
4 – Liam Cleary
5 – Steve Pietrek
GetUserProfileByIndex will not fail when you loop through 5 profiles because that is the number of profiles present in the database. On the other hand, querying a profile that doesn’t have a MySite, e.g. GetUserProfileByIndex(3) and GetUserProfileByIndex(4), will return the latest user with a MySite, in this case Liam Cleary (index no. 2).
Solution
In order to avoid this situation the value stored in NextValue can be used. NextValue contains the index of the next user with a valid MySite user profile. Looking at the first table again, the NextValue values are shown in parentheses:
1 – Ted Pattison (2)
2 – Liam Cleary (5)
3 – Amanda Murphy (5)
4 – Yvonne Harryman (5)
5 – Steve Pietrek ()
The following line can then be added to the loop to ensure that the next profile to be shown contains usable information:

Now you just need to output all the information in an SPGridView and the phone book is ready to be implemented.
Custom Properties in a SharePoint web part
It’s simple, really. Whenever you install a web part, it probably needs a few settings to work properly.
Maybe the web part needs to know the name of a specific list to be able to gather information and display it to the user. Or perhaps it requires the email address of the person who should receive status updates from the web part.
In any case you want the web part to be able to store simple textual and persistant information to be used in your code. You may of course decide to store this information in, say, a SQL Server table but – unless you need to store vast amounts of information – this is overkill and makes installation of the web part unecessarily difficult.
Custom web part properties to the rescue
You can add your own properties to the tool pane which appears when you access the settings of a web part in the browser. You can even make your properties appear in its own section, like this:
To achieve this, first add the following namespaces to your web part code:
Then, for each property you need, insert a code block similar to this:
Note that Category, WebDisplayName and WebDescription are optional but they do make your custom property much more readable for the end user.
In the above example, propEmail contains the default value of the property.