jump to navigation

Sharepoint SPAlert and UnAuthorizedAccessException June 2, 2005

Posted by codinglifestyle in Security, SharePoint.
Tags: , , , ,
trackback

Sharepoint Portal 2003 has a fairly decent object model to work with.  Once you overcome the various security/permission issues it is quite powerful.  In fact this is the main issue in working with Sharepoint is the rite of passage for Sharepoint developers.  You will see little help and/or pity from other developers on forums when newbies hit these obstacles because most of the information is there in the SDK to be sorted out if you take the time.  However, there comes a time when your understanding is shaken when encountering a new and interesting error.  That time was last week for me when writing a metrics program which gathered statistics portal wide.  Everything was going smoothly, heck I was almost done in 2 days, when I hit a problem with SPAlerts which threw me for 2 days. 

Starting with a SPVirtualServer I iterated through the each SPSite and thus the SPSite.AllWebs.  The first SPWebCollection is for the portal itself (the following are personal and team SPS sites).  When foreaching (and new word?  we’ll see if it catches on) the SPWebs I was attempting to access to Alerts property to gather my stats.  This is where I ran in to trouble and started catching UnAuthorizedAccessException.  Below is the example from the SDK which is really there to just baffle you further because you think if they bother to show an example and I can’t even get that to work SPAlertCollection class has an example I can’t even get to work:

SPSite siteCollection = SPControl.GetContextSite(Context);
SPWebCollection sites = siteCollection.AllWebs;

foreach (SPWeb site in sites)
{
   SPAlertCollection alerts = site.Alerts;

   foreach (SPAlert alert in alerts)
   {
      Label1.Text += SPEncode.HtmlEncode(site.Title) + " :: " + SPEncode.HtmlEncode(alert.Title) + " :: " +
          alert.User.LoginName + "
";
   }
}

The above code is so simple that to have obtained the exception I was certain that it was a simple permissions problem rather than a coding problem.  The siteCollection.CurrentUser was the COMPUTER\Administrator. That user us in the Administrators group. That user was setup as a Sharepoint administrator and as the DB admin. SiteCollection.CurrentUser.IsSiteAdmin == true.

Context.User.Identity.Name
@”VM2003S1\Administrator”
Context.User.Identity.AuthenticationType
“NTLM”
Context.User.Identity.IsAuthenticated
true
Context.User.IsInRole(@”BUILTIN\Administrators”)
true
////////
// First site (the root) from SPSite.AllWebs
////////
site.Url
http://miintranet”
site.CurrentUser.LoginName
@”VM2003S1\administrator”
site.CurrentUser.IsSiteAdmin
true
site.AuthenticationMode
Windows
site.IsRootWeb
true
site.CurrentUser.Roles.Count
1
site.CurrentUser.Roles[0].Name
“Administrator”
site.Roles[“Administrator”].Users.Count
3
site.Roles[“Administrator”].Users[2].Name
@”VM2003S1\Administrator”
site.UserIsSiteAdmin
true
site.Alerts.Count
0
/////////
// Iterate to next site in SPSite.AllWebs
/////////
site.Url
http://miintranet/C0″
site.CurrentUser.LoginName
@”VM2003S1\administrator”
site.CurrentUser.IsSiteAdmin
true
site.UserIsSiteAdmin
true
site.AuthenticationMode
Windows
site.IsRootWeb
false
site.CurrentUser.Roles.Count
>UnAuthorizedAccessException
site.Roles.Count
5
site.Roles[“Administrator”].Users.Count
>UnAuthorizedAccessException
site.Alerts.Count
>UnAuthorizedAccessException

In the end it wasn’t a permission problem at all.  It seems what I was hitting is a SharePoint Services vs Sharepoint Portal issue. I may be too new at this to make an accurate assessment, but it seems that the Portal SDK lets us down by not clearly differentiating which technology they are talking about. And furthermore Microsoft let us down by having these technologies side-by-side yet not making them interoperable. This is compounded by the fact that from the Portal context I can access a SPSite.AllWebs[x].Alerts and there seems to be nothing wrong with this on the surface. The only inkling that we’re crossing boundaries is the namespace which I will be much more paranoid of in the future. Note that my “workaround” accessed the Alert (NOT SPAlert) class from the user profile manager. This Alert class is in the Microsoft.SharePoint.Portal.Alerts.Alert namespace. While the example which confounded and frustrated me for 2 days dealt with SPAlerts in the Microsoft.SharePoint.SPAlert namespace. So coder beware the exceptions you see may have more to do with crossing the technology border from Portal->Services or vice-versa. One can only hope that in the future MS will do a better job documenting or even better, making a cohesive object model which doesn’t lead you down these nebulous dead-ends.

The workaround I eventually used was to use to the UserProfileManager.  You will note that this gets you an Alert from the Portal namespace and thus no access issues.

 

 

//Get the root URL and the PortalContext.
string url = GetRootUrl();
SPSite rootSite = SPControl.GetContextSite(Context);
rootSite.AllowUnsafeUpdates=true;
PortalContext portalContext = null;
Uri uri = new Uri(url); 

TopologyManager topologyManager = new TopologyManager();
PortalSiteCollection sites = topologyManager.PortalSites;
portalContext = PortalApplication.GetContext(sites[uri]); 

//Get all the users that have access.
SPUserCollection allUsers = rootSite.RootWeb.AllUsers;
UserProfileManager upm = new UserProfileManager(portalContext); 

foreach (SPUser user in allUsers)
{
	//Get the user profile for the SPUser (from SPUserCollection)
	UserProfile up;
	try
	{
		up = upm.GetUserProfile(user.LoginName);
	}
	catch
	{
		continue;
	}
	int n = up.Alerts.Count;
}

 

 

Advertisement

Comments»

No comments yet — be the first.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: