1

I have a WebApi2 endpoint where supportCredentials flag is set to true. On the IIS the Anonymous Authentication on false and the Windows Authentication on true.

What I'm trying to do is to load the right ShatePoint user based on the Identity loaded in RequestContext.Principal.Identity.

Current code:

string userLogin = RequestContext.Principal.Identity.Name;
using (ClientContext ctx = new ClientContext(WebConfig.Portal))
{
    List list = ctx.Site.RootWeb.SiteUserInfoList;

    var caml = new CamlQuery
    {
        ViewXml = $"<View><Query><Where><Contains><FieldRef Name='Name'/><Value Type='Text'>{userLogin}</Value></Contains></Where></Query></View>"
    };

    var users = list.GetItems(caml);
    ctx.Load(users);
    ctx.ExecuteQuery();

    IEnumerable<ListItem> user = from u in users.Cast<ListItem>()
                orderby u.Id descending
                select u;

    return Convert.ToString(user.First()["EMail"]);
}

It works, but I don't really like it. My first approach was:

string userLogin = RequestContext.Principal.Identity.Name;
using (ClientContext ctx = new ClientContext(WebConfig.Portal))
{
    UserCollection list = ctx.Site.RootWeb.SiteUsers;
    User user = list.GetByLoginName(userLogin);
    ctx.Load(user);
    ctx.ExecuteQuery();
    return user.Email;
}

The latter does not always work, since the Identity.Name is like "DOMAIN\USERNAME" but some SharePoint users have e.g the prefix i:0#.w| which is not present in the Identity.Name. The idea was to add i:0#.w| + userLogin, but as far I've read, this prefix may change.

Is there a clean and working way to load the correct SharePoint user with this Identity information?

1

Assuming the login name is in casual domain format DOMAIN\USERNAME, you can convert it to valid SharePoint claims format and getting user using

using SP = Microsoft.SharePoint.Client;
//...

// resolve user principal using regular login name or e-mail:
var userPrincipal = SP.Utilities.Utility.ResolvePrincipal(
  context, 
  context.Web, 
  "DOMAIN\\user", // normal login name
  SP.Utilities.PrincipalType.User,
  SP.Utilities.PrincipalSource.All,
  context.Web.SiteUsers,
  false);

context.ExecuteQuery();

// ensure that the user principal was resolved:
if (userPrincipal.Value == null)
  throw new Exception("The specified user principal could not be resolved");

// get a User instance based on the encoded login name from userPrincipal
var user = context.Web.SiteUsers.GetByLoginName(userPrincipal.LoginName);
context.Load(user);

context.ExecuteQuery();

On the other hand, simply doing this might work for DOMAIN\USERNAME as well, so it's worth a try.

var ctx = new ClientContext(site);
var rootWeb = ctx.Site.RootWeb;
var usr = rootWeb.EnsureUser("DOMAIN\\USERNAME");
ctx.Load(usr);
ctx.ExecuteQuery();
  • The first one works as I need. The second one doesn't IF there there is one user i:0#.w|DOMAIN\USERNAME and a second one DOMAIN\USERNAME. I know that such a state is wrong, but it could be. – Emaborsa Sep 21 '18 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.