<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Mark Arend : Security</title><link>http://blogs.msdn.com/markarend/archive/tags/Security/default.aspx</link><description>Tags: Security</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Modifying MySite Owner Security</title><link>http://blogs.msdn.com/markarend/archive/2008/04/10/modifying-mysite-owner-security.aspx</link><pubDate>Thu, 10 Apr 2008 07:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8374056</guid><dc:creator>markarend</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/markarend/comments/8374056.aspx</comments><wfw:commentRss>http://blogs.msdn.com/markarend/commentrss.aspx?PostID=8374056</wfw:commentRss><description>&lt;P&gt;When someone creates a MySite, they are automatically given full control of that site.&amp;nbsp; More accurately: a MySite is a site collection; the creator becomes the first &amp;amp; only Site Collection Administrator; the creator is made a member of the Owners group.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Some people feel that this is too much control, and they'd like to limit it in some way.&amp;nbsp; My first piece of advice in this situation is: don't.&amp;nbsp; MySites are built with dependencies on the permissions and identity of the owner, the person who created the site.&amp;nbsp; Changing this can introduce undesirable or confusing behavior.&amp;nbsp; Then, if requirements later change, after hundreds or thousands of people have created their MySite, more code must be written to effect those changes.&amp;nbsp; But if you insist on going down this path, I found a way to meet this seemingly simple request.&amp;nbsp; The answer is most certainly not simple.&lt;/P&gt;
&lt;P&gt;Basically, you have to follow Steve Peschka’s approach described in the blog entry &lt;A href="http://blogs.msdn.com/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites-within-the-enterprise.aspx" mce_href="http://blogs.msdn.com/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites-within-the-enterprise.aspx"&gt;customizing My Sites&lt;/A&gt; as the framework for doing this.&amp;nbsp; Then, add code to that scheme that knows how to change the security.&amp;nbsp; There are a few added challenges:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You must do two things: 1) change the creator’s group membership and 2) remove them as a Site Collection Administrator. &lt;/LI&gt;
&lt;LI&gt;To give the creator of the MySite specific privileges, you typically want to create a custom privilege level and add the user into that group.&amp;nbsp; The benefit is that you can tweak this to allow/prevent actions at a fairly granular level, such as being able to block the ability to add subsites. &lt;/LI&gt;
&lt;LI&gt;The creator of the MySite is the &lt;EM&gt;only &lt;/EM&gt;Site Collection Administrator, so you can’t remove this person from this role until you first put someone else in there.&amp;nbsp; For best governance, this should be a user account that’s not really associated with an individual, but shared among trusted admins.&amp;nbsp; Unfortunately it must be a user account, not a group. &lt;/LI&gt;
&lt;LI&gt;There seems to be a timer job that fixes up the title of the MySite to match the name of the site administrator… so you need some code that resets this back every time the user opens the site. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Why can’t we just change the MySite site definition (template)?&amp;nbsp; Two reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Modifying the MySite site definition is “unsupported” by Microsoft.&amp;nbsp; If you did it, then wanted help with problems related to it, the support engineer would make a best effort, but could not guarantee a fix.&amp;nbsp; Steve’s article talks more about this. &lt;/LI&gt;
&lt;LI&gt;Moot point!&amp;nbsp; User security is not stored in the site definition, so even if it were supported to modify it, there would be nothing to do. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Below are code samples that address the challenges listed above.&amp;nbsp; Your job would be to integrate them with Steve Peschka’s &lt;A href="http://www.codeplex.com/CKS/Release/ProjectReleases.aspx?ReleaseId=2824" mce_href="http://www.codeplex.com/CKS/Release/ProjectReleases.aspx?ReleaseId=2824"&gt;code&lt;/A&gt;.&amp;nbsp; Sorry I can’t give a more complete solution.&amp;nbsp; This is one task that is very difficult to accomplish in SharePoint, and the methods described are the only way we know of doing it in a supported way.&lt;/P&gt;
&lt;P&gt;(BTW, I use lots of try...catch blocks here to get the most granular logging.&amp;nbsp; You can implement Utility.LogMessage any way you like; I use MSDN's &lt;A href="http://msdn2.microsoft.com/en-us/library/aa979522.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa979522.aspx"&gt;Trace Log Example&lt;/A&gt; to write to the ULS logs, and CodePlex's &lt;A href="http://www.codeplex.com/features/Release/ProjectReleases.aspx?ReleaseId=2502" mce_href="http://www.codeplex.com/features/Release/ProjectReleases.aspx?ReleaseId=2502"&gt;Log Viewer Feature&lt;/A&gt; to read them.)&lt;/P&gt;
&lt;STYLE type=text/css&gt;








.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}

.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;
&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; RestrictMySiteOwner()
{
    SPUserInfo originalOwnerInfo = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SPUserInfo();
    SPUserInfo newOwnerInfo = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SPUserInfo();&lt;BR&gt;
    &lt;SPAN class=rem&gt;// Store the original owner in site properties so we can restore it later if necessary&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        StoreValueInSiteProperty(_curWeb, &lt;SPAN class=str&gt;"OriginalOwner"&lt;/SPAN&gt;, MakeUserInfoString(originalOwnerInfo));
        Utility.LogMessage(&lt;SPAN class=str&gt;"Stored original administrator in site property."&lt;/SPAN&gt;);
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't store original administrator in site property.  "&lt;/SPAN&gt; + ex.Message);
    }&lt;BR&gt;
    &lt;SPAN class=rem&gt;// Switch out the primary site administrator with a pre-defined one.&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        newOwnerInfo.LoginName = &lt;SPAN class=str&gt;"DOMAIN\MySitesAdmin"&lt;/SPAN&gt;;
        newOwnerInfo.Email = &lt;SPAN class=str&gt;"mysitesadmin@customer.com"&lt;/SPAN&gt;;
        newOwnerInfo.Name = &lt;SPAN class=str&gt;"MySites domain manager"&lt;/SPAN&gt;;
        newOwnerInfo.Notes = &lt;SPAN class=str&gt;"Owner of all MySites"&lt;/SPAN&gt;;
        originalOwnerInfo = ReplacePrimarySiteAdministrator(_curWeb, newOwnerInfo);
        Utility.LogMessage(&lt;SPAN class=str&gt;"Switched primary administrator."&lt;/SPAN&gt;);
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't replace primary administrator.  "&lt;/SPAN&gt; + ex.Message);
    }&lt;BR&gt;
    &lt;SPAN class=rem&gt;// Add the My Site creator to a group with limited permissions to control what is permissible on the site&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        ChangeCurrentUserPermission(_curWeb, &lt;SPAN class=str&gt;"Restricted Owner"&lt;/SPAN&gt;);
        Utility.LogMessage(&lt;SPAN class=str&gt;"Changed current user permissions."&lt;/SPAN&gt;);
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't change current user permissions.  "&lt;/SPAN&gt; + ex.Message);
    }&lt;BR&gt;
    &lt;SPAN class=rem&gt;// Reset the name of the site back to original owner (was changed by switching primary site admin)&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        SetSiteTitle(_curWeb, originalOwnerInfo.Name);
        Utility.LogMessage(&lt;SPAN class=str&gt;"Reset site title."&lt;/SPAN&gt;);
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't reset site title.  "&lt;/SPAN&gt; + ex.Message);
    }
}


&lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; SPUserInfo ReplacePrimarySiteAdministrator(SPWeb site, &lt;SPAN class=kwrd&gt;SPUserInfo&lt;/SPAN&gt; newAdminInfo)
{
    SPUser originalOwner = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
    SPUserInfo originalOwnerInfo = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SPUserInfo();
 
    SPSecurity.RunWithElevatedPrivileges(&lt;SPAN class=kwrd&gt;delegate&lt;/SPAN&gt;()
    {
        &lt;SPAN class=rem&gt;// Get the parent site collection&lt;/SPAN&gt;
        SPSite sitecollection = site.Site;&lt;BR&gt;
        originalOwner = sitecollection.Owner;
        originalOwnerInfo = Utility.GetUserInfo(originalOwner);

        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (newAdminInfo.LoginName != originalOwnerInfo.LoginName)
        {
            &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
            {
                &lt;SPAN class=rem&gt;// Add new admin to Full Control group&lt;/SPAN&gt;
                SPRoleDefinition admins = site.RoleDefinitions[&lt;SPAN class=str&gt;"Full Control"&lt;/SPAN&gt;];
                &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (admins != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
                {
                    SPRoleAssignment roleAssignment = &lt;BR&gt;&lt;SPAN class=kwrd&gt;                        new&lt;/SPAN&gt; SPRoleAssignment(newAdminInfo.LoginName, newAdminInfo.Email, &lt;BR&gt;                        newAdminInfo.Name, newAdminInfo.Notes);
                   SPRoleDefinitionBindingCollection roleDefBindings = &lt;BR&gt;                        roleAssignment.RoleDefinitionBindings;
                    roleDefBindings.Add(admins);
                    site.RoleAssignments.Add(roleAssignment);
                    &lt;SPAN class=rem&gt;//site.Update(); // Don't need to do this&lt;/SPAN&gt;
                }

                &lt;SPAN class=rem&gt;// Reset owner of site collection to new admin&lt;/SPAN&gt;
                sitecollection.Owner = site.Users[newAdminInfo.LoginName];
                sitecollection.Owner.Update();

                &lt;SPAN class=rem&gt;//change the userprofile guid of the site&lt;/SPAN&gt;
                sitecollection.Properties["urn:schemas-microsoft-com:sharepoint:portal:profile:userprofile_guid"] = toProfile.ID.ToString().Replace("{", string.Empty).Replace("}", string.Empty); 
                sitecollection.Properties.Update(); 

            }
            &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (SPException ex)
            {
                &lt;SPAN class=rem&gt;// We may get here if the user running this thread is the same as the &lt;BR&gt;                // aministrator we're trying to remove.&lt;/SPAN&gt;
                Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't replace primary administrator.  "&lt;/SPAN&gt; + ex.Message);
            }
        }
    });

    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; originalOwnerInfo;
}


&lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; ChangeCurrentUserPermission(SPWeb site, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; roleDefinitionName)
{
    SPUser curUser = site.CurrentUser;
    &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; curUserName = curUser.LoginName;

    SPRoleDefinition roleDefFull = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;         &lt;SPAN class=rem&gt;// Full control privilege level&lt;/SPAN&gt;
    SPRoleDefinition roleDefContributor = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;  &lt;SPAN class=rem&gt;// Contributor privilege level&lt;/SPAN&gt;
    SPRoleDefinition roleDefLimitedOwner = &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;; &lt;SPAN class=rem&gt;// Our new privilege level&lt;/SPAN&gt;
            
    &lt;SPAN class=rem&gt;// Create new role definition&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        &lt;SPAN class=rem&gt;// Get existing role definitions&lt;/SPAN&gt;
        roleDefFull = site.RoleDefinitions[&lt;SPAN class=str&gt;"Full Control"&lt;/SPAN&gt;];
        roleDefContributor = site.RoleDefinitions[&lt;SPAN class=str&gt;"Contribute"&lt;/SPAN&gt;];

        &lt;SPAN class=rem&gt;// Create custom role definition&lt;/SPAN&gt;
        roleDefLimitedOwner = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SPRoleDefinition();
        roleDefLimitedOwner.Name = roleDefinitionName;
        roleDefLimitedOwner.Description = &lt;SPAN class=str&gt;"Permission settings for the owner of this MySite."&lt;/SPAN&gt;;
        site.FirstUniqueRoleDefinitionWeb.RoleDefinitions.Add(roleDefLimitedOwner);
        site.FirstUniqueRoleDefinitionWeb.Update();

        &lt;SPAN class=rem&gt;// Get the new role definition again... makes sure the Update took all the way or something.&lt;/SPAN&gt;
        roleDefLimitedOwner = site.FirstUniqueRoleDefinitionWeb.RoleDefinitions[roleDefinitionName];

        &lt;SPAN class=rem&gt;// Set permissions of new role... start from Contributor as base.&lt;/SPAN&gt;
        roleDefLimitedOwner.BasePermissions = roleDefContributor.BasePermissions;
        &lt;SPAN class=rem&gt;// To ADD a permission, use Bitwise-Or assignment:       permissions |= permission&lt;/SPAN&gt;
        &lt;SPAN class=rem&gt;// To REMOVE, use Bitwise-And assignment to Complement:  permissions &amp;amp;= ~permission&lt;/SPAN&gt;
        roleDefLimitedOwner.BasePermissions |= SPBasePermissions.CancelCheckout;
        roleDefLimitedOwner.BasePermissions &amp;amp;= ~SPBasePermissions.AddDelPrivateWebParts;
        roleDefLimitedOwner.BasePermissions &amp;amp;= ~SPBasePermissions.UpdatePersonalWebParts;
        roleDefLimitedOwner.Update();
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't create new permission group \""&lt;/SPAN&gt; &lt;BR&gt;            + roleDefinitionName + &lt;SPAN class=str&gt;"\". "&lt;/SPAN&gt; + ex.Message);
    }
            
    &lt;SPAN class=rem&gt;// Add owner to new role definition&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        SPRoleAssignment assignment = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; SPRoleAssignment(curUser);
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (roleDefLimitedOwner != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            assignment.RoleDefinitionBindings.Add(roleDefLimitedOwner);
        }
        &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt;
        {
            &lt;SPAN class=rem&gt;//Workaround: for now we just make owner a contributor&lt;/SPAN&gt;
            assignment.RoleDefinitionBindings.Add(roleDefContributor);
        }
        site.RoleAssignments.Add(assignment);
&lt;SPAN class=rem&gt;        //site.Update();&lt;/SPAN&gt; // Don't need to do this&lt;BR&gt;    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't add user \""&lt;/SPAN&gt; + curUserName &lt;BR&gt;            + &lt;SPAN class=str&gt;"\" to new permission group \"" &lt;/SPAN&gt;+ roleDefinitionName + &lt;SPAN class=str&gt;"\".  "&lt;/SPAN&gt; + ex.Message);
    }

    &lt;SPAN class=rem&gt;// Remove owner from Full Control&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        SPRoleAssignment userRoleAssignment = UserRoleAssignment(site, curUser, roleDefFull);
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (userRoleAssignment != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        {
            userRoleAssignment.RoleDefinitionBindings.Remove(roleDefFull);
            userRoleAssignment.Update();
        }
        &lt;SPAN class=rem&gt;//site.Update(); // Don't need to do this&lt;/SPAN&gt;
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't remove user \""&lt;/SPAN&gt; + curUserName &lt;BR&gt;            + &lt;SPAN class=str&gt;"\" from default permission groups.  "&lt;/SPAN&gt; + ex.Message);
    }
}&lt;BR&gt; &lt;BR&gt; &lt;BR&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; SPRoleAssignment UserRoleAssignment(SPWeb site, SPUser curUser, SPRoleDefinition curRoleDef)
{
    &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (SPRoleAssignment roleAssignment &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; site.RoleAssignments)
    {
        &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (roleAssignment.Member.ID == curUser.ID)
        {
            &lt;SPAN class=kwrd&gt;foreach&lt;/SPAN&gt; (SPRoleDefinition roleDefinition &lt;SPAN class=kwrd&gt;in&lt;/SPAN&gt; roleAssignment.RoleDefinitionBindings)
            {
                &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (roleDefinition.Id == curRoleDef.Id)
                {
                    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; roleAssignment;
                }
            }
        }
    }
    &lt;SPAN class=kwrd&gt;return&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;;
}


&lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; StoreValueInSiteProperty(SPWeb site, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; propertyName, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; propertyValue)
{
    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (site.Properties.ContainsKey(propertyName))
        site.Properties[propertyName] = propertyValue;
    &lt;SPAN class=kwrd&gt;else&lt;/SPAN&gt;
        site.Properties.Add(propertyName, propertyValue);
    site.Properties.Update();
}


&lt;SPAN class=kwrd&gt;protected&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; SetSiteTitle(SPWeb site, &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; title)
{
    &lt;SPAN class=kwrd&gt;try&lt;/SPAN&gt;
    {
        site.Title = title;
        &lt;SPAN class=rem&gt;//site.Update(); // Don't need to do this&lt;/SPAN&gt;
    }
    &lt;SPAN class=kwrd&gt;catch&lt;/SPAN&gt; (Exception ex)
    {
        Utility.LogMessage(&lt;SPAN class=str&gt;"Error: can't set site title to \""&lt;/SPAN&gt; + title + &lt;SPAN class=str&gt;"\".  "&lt;/SPAN&gt; + ex.Message);
    }
}
 &lt;/PRE&gt;
&lt;DIV class=wlWriterSmartContent id=scid:0767317B-992E-4b12-91E0-4F059A8CECA8:ee094114-a2a2-48b8-893a-c059149ed214 style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;Technorati Tags: &lt;A href="http://technorati.com/tags/MySite" rel=tag mce_href="http://technorati.com/tags/MySite"&gt;MySite&lt;/A&gt;,&lt;A href="http://technorati.com/tags/SharePoint%20Security" rel=tag mce_href="http://technorati.com/tags/SharePoint%20Security"&gt;SharePoint Security&lt;/A&gt;,&lt;A href="http://technorati.com/tags/SharePoint%20Development" rel=tag mce_href="http://technorati.com/tags/SharePoint%20Development"&gt;SharePoint Development&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8374056" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/markarend/archive/tags/MySites/default.aspx">MySites</category><category domain="http://blogs.msdn.com/markarend/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/markarend/archive/tags/Security/default.aspx">Security</category></item><item><title>Test With Correct Privileges</title><link>http://blogs.msdn.com/markarend/archive/2008/03/06/test-with-correct-privileges.aspx</link><pubDate>Fri, 07 Mar 2008 00:12:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8078784</guid><dc:creator>markarend</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/markarend/comments/8078784.aspx</comments><wfw:commentRss>http://blogs.msdn.com/markarend/commentrss.aspx?PostID=8078784</wfw:commentRss><description>&lt;p&gt;When developing web parts and other components with code, it's important to remember that operations performed by code may require certain privileges.&amp;#160; During development, the code runs in the security context of the developer, who is usually a server administrator.&amp;#160; This means all operations are permitted, so access problems don't arise.&amp;#160; During testing and production, however, the security context of the code may be different because it's being invoked by testers and end-users.&lt;/p&gt;  &lt;p&gt;Therefore, all components should be tested with several end-user accounts: one would be the developer&amp;#8217;s account which is usually a server admin; that&amp;#8217;s how most people do their unit testing. But tests should also be made with an account of minimal privilege, say Visitor.&amp;#160; Some components might be doing things with the object model that will only work when an administrator invokes it. If this turns out to be the case, a technique called &amp;#8220;elevation of privilege&amp;#8221; can be used to overcome it.&amp;#160; See MSDN article &lt;a title="Article by Ted Pattison Group" href="http://msdn2.microsoft.com/en-us/library/bb466220.aspx" target="_blank"&gt;Running Commands with Elevated Privileges in Windows SharePoint Services 3.0&lt;/a&gt; for an explanation of doing this.&lt;/p&gt;  &lt;p&gt;What code needs to be tested using different privileges? &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1. Code that's invoked as the result of an end-user action. An example is a custom web part that is displayed on a page. The end-user opens the page and this is what invokes the web part code under the user's security context. A counter-example is timer job code that is invoked by SharePoint.&lt;/p&gt;    &lt;p&gt;2. Code that uses the SharePoint API. This is typically where security errors arise. If a component does not use the SharePoint API, then chances are it will not need to elevate its privilege. To be entirely sure, it should be tested at minimum privilege, but this criterion can be used to prioritize testing of other components higher.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;How can a developer test with different accounts?&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The simplest approach is to create three accounts &amp;quot;Test Visitor,&amp;quot; &amp;quot;Test Member,&amp;quot; and &amp;quot;Test Owner&amp;quot; in Active Directory and then to add these accounts to matching groups on the test sites.&lt;/p&gt;    &lt;p&gt;First, the developer must decide in what security contexts the component is supposed to work. For example, most end-user web parts should work for users signed on as Test Visitor. On the other hand, an stsadm extension is only invoked by a server admin and should not be tested with a minimum privilege account.&lt;/p&gt;    &lt;p&gt;&amp;quot;Sign on as different user&amp;quot; can be used to choose one of the test accounts as appropriate; however, in some cases, this approach does not seem to &amp;#8220;stick&amp;#8221; based on browser state or browsing behavior (e.g. browsing to My Site when browser is configured for automatic logon). The best way to ensure that the desired account is used is to configure the browser to always prompt for credentials, then to open a new browser window to begin testing. Then, re-run all unit tests that exercise the component directly (not, say, the deployment of the component).&lt;/p&gt; &lt;/blockquote&gt;  &lt;div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:9087756e-a110-4edd-baa3-5f9e1bf807da" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/Minimum%20privilege" rel="tag"&gt;Minimum privilege&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Web%20part%20security" rel="tag"&gt;Web part security&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Code%20Access%20Security" rel="tag"&gt;Code Access Security&lt;/a&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8078784" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/markarend/archive/tags/SharePoint/default.aspx">SharePoint</category><category domain="http://blogs.msdn.com/markarend/archive/tags/Development/default.aspx">Development</category><category domain="http://blogs.msdn.com/markarend/archive/tags/Security/default.aspx">Security</category></item><item><title>SharePoint 2007 Permissions Matrix</title><link>http://blogs.msdn.com/markarend/archive/2008/02/14/sharepoint-2007-permissions-matrix.aspx</link><pubDate>Thu, 14 Feb 2008 21:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7697309</guid><dc:creator>markarend</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/markarend/comments/7697309.aspx</comments><wfw:commentRss>http://blogs.msdn.com/markarend/commentrss.aspx?PostID=7697309</wfw:commentRss><description>&lt;P&gt;Many times it helps to see an overall comparison of SharePoint 2007 permissions.&amp;nbsp; I assembled a matrix that shows lots of useful information that helps you understand how permission levels are related, and how they affect security trimming of Site Actions and Site Settings.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Screenshot (click to download the spreadsheet)&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=ReferenceTopics&amp;amp;DownloadId=490" target=_blank mce_href="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=ReferenceTopics&amp;amp;DownloadId=490"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=369 alt="Permissions Screenshot" src="http://blogs.msdn.com/blogfiles/markarend/WindowsLiveWriter/SharePoint2007PermissionsMatrix_A9E6/Permissions%20Screenshot_3.jpg" width=475 border=0 mce_src="http://blogs.msdn.com/blogfiles/markarend/WindowsLiveWriter/SharePoint2007PermissionsMatrix_A9E6/Permissions%20Screenshot_3.jpg"&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7697309" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/markarend/archive/tags/Configuration/default.aspx">Configuration</category><category domain="http://blogs.msdn.com/markarend/archive/tags/Security/default.aspx">Security</category></item></channel></rss>