I have setup a web app in SP2010 with ADFS and NTLM authentication enabled. We have code that runs SPUser.EnsureUser() that fails looking up a user account that exists in the hidden user list (/_catalogs/users/simple.aspx) and can/has logged into the site collection. I have found some interesting behavior with this scenario and I am confused/unsure why this happening. Following is what I have found:

  • If I give the user account an email address in the hidden user list EnsureUser works (user does not have one in AD).
  • User accounts that have logged in using ADFS work.
  • User accounts that have logged in using NTLM do not work unless they have an email address.
  • User accounts that do have an email address in AD and/or SharePoint work just fine.
  • If a web application is setup for Claims but has not had a membership provider configured (so just using AD auth) EnsureUser works.
  • If I setup ADFS to use the email address as the identifier rather than SamAccountName EnsureUser works.
  • I have tried user, domain\user, and [email protected] with no effect.
  • The claim ID of the NTLM users look correct (i:0#.w|domain\user) (as far as I can tell).

The ADFS instance that isn't working is sending claims for WindowsAccountName, email, and Name (mapped to SamAccountName, email, and DisplayName, respectively)(I followed these steps to setup ADFS. Only difference is I added the other two claim mappings). The ADFS instance that is working is mapping email and display name only with email being the unique identifier in SharePoint.

From what I have read online it seems like the membership providers are stepping on each other. However, if that is the case then I understand why the one ADFS instance that is working is working (different identifiers), but why would having an email address or not matter to the site collection that isn't? Or is EnsureUser actually complaining because it is finding two user accounts (AD and ADFS) and throwing the wrong error?

1 Answer 1


I'm going to break this down how I looked at your issue, and hopefully answer some questions on the way:

EnsureUser basically iterates through SPUserCollection and compares the passed parameter to SPUserCollection.UserFields.LoginName

SPUser.Email is ClientCallableConstraintType.NotNull so maybe it's that...

ADFS login usually requires emails, or generates an email for you (ie on 365 you get [email protected]) this isn't held in AD it is in the proxy. So I kept digging.

The ID format is i:0#.authtype|membership_if_forms|username So your id is correct yes.

The SPException will be thrown on this line in EnsureUser:

SPPrincipalInfo sPPrincipalInfo = SPUtility.ResolvePrincipalInternal(this, null, null, logonName, SPPrincipalType.User | SPPrincipalType.SecurityGroup, SPPrincipalSource.All, null, false, true)

Meaning it cannot resolve the user.

So yes, you are right they are stepping on each other.

Then it hit me, the email is also a unique value, the ResolvePrincipalInternal is matching on email if it is included, otherwise on the login name which in your case isn't unique because if the cross over.

It only works if the match is unique, so you need to add email addresses. Now I went and had a quick chat with my sys admin and he confirmed what I was thinking as when he sets this up he says he has to make a field with a email address.

and to quote "You need to add the emails and set up a UPN for the same domain as the email ie [email protected] set up a UPN for mysite.com (name change it) that will allow it to sync, tell the guy to add email addresses"

Emails addresses are the unique field for resolving the users.

  • 1
    Thanks for the follow up. I barely remember this project now and I am pretty sure I came to the same conclusion as you. I wonder if we get a prize for the longest time between responses? Jul 15, 2014 at 13:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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