SPUser? SPException!

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, MyDomain\MyUser).
So let’s try the opposite way – we know the user name, let’s find the user:

SPControl.GetContextWeb(context).Users("MyDomain\MyUser")

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?

15 thoughts on “SPUser? SPException!”

  1. Its really helpful. This is the only site which i got desired information. But I need to know where can i get the IsUserMember() function. Can you help me???

  2. Hi i saw that link. But I felt very hard to understand that. Finally I understood. You specified that it will work only with LDAP:// provider. I dont know about my provider. Just i am retrieving the information from Active Directory(AD) group and mapped to SPS site. Is it possible to use your code for this AD groups??? If so, help me for this.. Thanks.. I searched so many websites. But none of the website is giving about this issue. You are the one who gave some suggession.

  3. Sankar! As you know, if you have ActiveDirectory, you can register domain users and domain groups in the directory. Usernames registered in the AD look like “domainname\username”. However, the “old style” local groups and users that are registered “per computer” are still working. For instance, every computer has a built-in local group “Administrators”. These names are written like “computername\username”, i.e. instead of the domain you have the computer name in the “security authority” part of username. The problem is that groups like “yourcomp\Administrators” are NOT registered in ActiveDirectory, they “live” only in your computer and can be accessed, using the WinNT ADSI provider. This means, you cannot use the LDAP ADSI provider to query for local groups and users.

    If you say you’re using groups from active directory, the code posted in the other article should work.

    Actually I’m writing another article with updated code that will work both with local and domain groups.

  4. Hi I tried. But its not working. I will explain what i did. I am accessing SPS site through SPS server. I created the AD group called “primary” in the SPS server and i mapped to SPS site. The domain is “SPS” and group name is “primary”. So my group is appearing as “SPS\primary”. The members in that group are SPS\sankar, SPS\thiru, etc.. I have used your code in the web part to check whether the user is available inside the group or not. Can you check the code in this link http://sankar83.8k.com/share.htm

    Thanks

    Regards

    SANKAR

  5. One thing, I think this line is wrong then:

    If IsUserMember(“SPS\primary”, “SPS\sankar”) Then

    should be

    If IsUserMember(“SPS\sankar”, “SPS\primary”) Then

    ’cause user name is the first argument, group name – the second one.

  6. Hi, This is Thiru, doing project in Sharepoint site, in that i need to send “Events List” as “Mail” to others. i added events by the help of default “Calendar Control” in SPS site, but i cant send events to multiple mail-id’s. I tried “Alert Me” option but in that i can send event as single mail-id only. so, i need look and feel could be sending mail to different groups and multiple mail-id’s. plz….anyone give me suggestion about this problem. Thank you,

    Cheers, Thiru

  7. Hi Kriss Rauhvargers….

    Thank you very much. Its working fine. Thanks allot..

    I may ask some doubts regarding sharepoint. Plz help me in the future.

    Byeeee

    Regards

    J.SANKAR

  8. Thiru! This does not seem to be a case where you could easily use built-in Sharepoint capabilities. Looks like you have to use same custom code. I suggest you look for custom event handlers on the particular “Events list”.

    br, Kriss

  9. Hello Kriss, Thank you very much, your information was precise, the articles are very clear and – just what I needed. :-)

    Thank you, Eva

  10. Hello Kriss, Further to my comment above I’ve found that using spWeb.AllUsers (rather than spWeb.Users) I always see my user (even ones that were added to SharePoint only through a domain group) and your AD lookup code above (which by the way works superbly) is never entered. I thought it worth noting for the next person out there.

    Thank you, Eva

  11. Thanks, Eva! This is exactly what my colleague told me today (no, really, today) – that all the users that have entered the site (once, twice, doesn’t matter), can be found in that collection. Which leads us to thinking that this is a wonderful workaround for a problem that doesn’t exist ;-)

  12. What Eva says is right, you can get the user with SPWeb.AllUsers but you cannot get any of the roles associated to the group where the user belongs to via SPUser.Roles. I at least get an empty list and my AD Group is granted an specific role.

  13. Hi all,

    Can we retrieve Sharepoint Site user’s properties (e.g, First, Middle, Last names) from active directory, from within Sharepoint’s aspx page, in the run time.

    Regards Sharad

Comments are closed.