Something on SharePoint(TM) again. Either you love it or hate it, you have to work around all the pitfalls anyway.
So we all know that in SharePoint you can allow people and assign them SharePoint roles in two ways:
- creating a “Sharepoint User” within the portal and assigning roles to the user,
- adding a domain group to users and assigning roles to a particular group.
The first case is the easy one. The second is not. Say, we add a group “MyDomainGroup” to SharePoint users and assign them a specific SharePoint role “MySharepointRole”. What happens when a user belonging to the domain group visits your SharePoint site:
- the user is allowed to open the page, because he belongs to the specific group
- the IIS thread runs under the security account of the user because this is the way IIS impersonation works
- code in webparts is executed under the security account of the user
The interesting thing is that
SPControl.GetContextWeb(context).CurrentUser returns a valid SPUser object (even though we know there is no SharePoint Web user profile for him). You can get the LoginName property of the
CurrentUser and you get the actual login name (let’s say,
So let’s try the opposite way – we know the user name, let’s find the user:
This ends up in an SPException, because there is no such a user
MyUser in this SharePoint web – he was only allowed to open this page because he is in the domain group.
OK, I think I should explain the situation a bit more. Of course, if you run all the code in the webpart itself, there is no problem – just keep using the
CurrentUser property and everything should run smoothly. However, due to some particular security considerations I need to run some code under a privileged account. This is why I’m using a COM+ component that runs under another security account.
For instance, I have a function in the COM+ component that returns an array of role names user belongs to. Within the function, you have to find the SPSite, SPWeb and SPUser to read the roles. You can do it like this:
Dim oSite as New SPSite("http://server/sites/somesite") Dim oWeb as SPWeb = oSite.AllWebs(New System.Guid("6CCED9AD-7C38-4FF3-9E69-1B2F43D2BD65"))
For a regular user, you could read his role list like this:
oUser = oWeb.Users("MyDomain\MyUser") For Each oRole As SPRole In oUser.Roles '... add to the return array Next
This does not work for a user belonging to a domain group and not being registered as a local user in the SPWeb. As mentioned above, there is no such user. However, there is a special user “MyDomain\MyDomainGroup” registered in the web. So you can do it this way:
For Each oGroup As SPUser In oWeb.Users If oGroup.IsDomainGroup() Then 'this is "True" for domain groups, "False" for regular users If IsUserMember("MyDomain\MyUser", oGroup.LoginName) Then For Each oRole As SPRole In oGroup.Roles '... add to the return array Next End If End If Next
This should work fine now. Of course, you will do it in the “Catch” block after you have tried to find the user in the regular manner.
The only thing we need is a function
IsUserMember that tells if a user ir member of a domain group. This is quite another story, covered in another article – here: Does this user belong to a domain group?