(2014-10-20) Configuring A New Identity Store As A Claims Provider In ADFS
Posted by Jorge on 2014-10-20
UPDATED VERSION HERE: (2018-10-11) Configuring A New Identity Store As A Local Claims Provider In ADFS
–
In ADFS v1.0 and ADFS v1.1 it was possible to use both AD and ADLDS/ADAM as an identity store. One of the very common scenarios is to use the AD identity store for internal users and use the ADLDS/ADAM identity store for external users (e.g. partners, customers, vendors, etc.). After ADFS v1.x Microsoft released ADFS v2.0 (separate download for W2K8 and W2K8R2), ADFS v2.1 in W2K12 and ADFS v3.0 in W2K12R2. All the ADFS versions starting with ADFS v2.0 and higher only supported AD as the identity store and nothing else. That could be one of the reasons why some companies remained using ADFS v1.1 and did not move one.
If you would like to support a similar scenario, where you would like to have a separate identity store for externals, you would need to:
- Configure a separate AD with its own ADFS infrastructure and configure federation between (also see: (2013-09-24) AD User Accounts For Which The ADFS STS Can Generate Security Tokens)
OR - Use Azure AD to store those identities and configure federation
–
The biggest advantage of using [2] instead of [1] is that you do not need a complete new infrastructure just to support externals. The basic Azure AD features are free, but as soon as you need something special from the Azure AD Premium list, you need to pay licensing.
–
With the release of the Windows Server vNext, currently in Technical Preview, a third option has become available as already mentioned in the blog post (2014-10-03) ADFS In vNext To Support Other Identity Stores Than AD Only. YES! YES! YES! Finally!
–
At the time of writing, for the passive federation protocols (e.g. SAML, WS-Federation and Oauth) and the active federation protocols (e.g. WS-Trust), ADFS v4.0 will support the following identity stores:
- Identity Stores As Claim Providers:
- Active Directory (Trusted AD forests)
- Identity Stores As Local Claim Providers:
- Active Directory (NON-Trusted AD forests)
- ADLDS/ADAM
- Apache DS
- IBM Tivoli DS
- Novell DS
- Open LDAP
- Open DJ
- Open DS
- Radiant Logic Virtual DS
- Sun ONE v6, v7, v11
–
The local claims providers can only be configured through PowerShell and authentication through ADFS against those local claims providers can only be done by using forms-based authentication. One last thing to note is that you can only configure local claims providers when the Farm Behavior/Level is higher than Win2012R2. Also see: (2014-10-12) Migrating Or Upgrading To A New ADFS Version.
—
I have the following ID Store:
- Type: ADLDS (LDAP)
- Server (1): IDSTORE.ADCORP.LAB
- LDAP Port (1): 5389
- LDAPS Port (1): 5636
- Account UserName: SVC_R1_IDSTORE@ADLDSCORP.LAB
- Account Password: pwd
–
# Import The ADFS PowerShell Module
Import-Module ADFS
# Define The Credentials For ADFS To Use When Connecting To The ID Store
$idStoreAccountUserName = ‘SVC_R1_IDSTORE@ADLDSCORP.LAB’
$idStoreAccountPassword = ‘pwd’ | ConvertTo-SecureString -asPlainText -Force
$idStoreAccountCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $idStoreAccountUserName,$idStoreAccountPassword
# Define All The Server Instances Hosting The Identity Store
$idStoreInstance1 = New-AdfsLdapServerConnection -HostName IDSTORE.ADCORP.LAB -Port 5636 –SslMode SSL –Credential $idStoreAccountCreds –AuthenticationMethod Basic
# Define All The Attribute-To-ClaimType Mappings For Which You Want ADFS To Automatically Retrieve From The ID Store
(These are the attributes and their values, if any, automatically retrieved from the ID store and stored in claims, whether or not these are issued later on in a security token)
$mappingGivenName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute givenName –ClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
$mappingSurname = New-AdfsLdapAttributeToClaimMapping –LdapAttribute sn –ClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
$mappingDisplayName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute displayName –ClaimType "http://temp.org/identity/claims/displayName"
$mappingEmployeeID = New-AdfsLdapAttributeToClaimMapping –LdapAttribute employeeID –ClaimType "http://temp.org/identity/claims/employeeID"
# Create The Local Claims Provider Trust (HRD Through List Of Claims Providers)
Add-AdfsLocalClaimsProviderTrust –Name "ADLDS-ID-Store" –Identifier "urn:adlds:idstore" –Type Ldap -LdapServerConnection @($idStoreInstance1) –UserObjectClass user –UserContainer "OU=Users,O=ExternalIdentityStore" –LdapAuthenticationMethod Basic –AnchorClaimLdapAttribute userPrincipalName –AnchorClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" –LdapAttributeToClaimMapping @($mappingGivenName, $mappingSurname, $mappingDisplayName, $mappingEmployeeID) –Enabled $true -AcceptanceTransformRules "@RuleName = `"Issue All Mapped Claims`"`nc:[] => issue(claim = c);"
Figure 1a: Creating A Local Claims Provider Based Upon ADLDS In ADFS v4.0 (HRD Will Be Through List Of Claims Providers)
–
REMARK: in this case the yellow error occurs because I did not specify anything for the organizational suffix for this local claims provider
–
# Create The Local Claims Provider Trust (HRD Through UPN Suffix)
Add-AdfsLocalClaimsProviderTrust –Name "ADLDS-ID-Store" –Identifier "urn:adlds:idstore" –Type Ldap -LdapServerConnection @($idStoreInstance1) –UserObjectClass user –UserContainer "OU=Users,O=ExternalIdentityStore" –LdapAuthenticationMethod Basic –AnchorClaimLdapAttribute userPrincipalName –AnchorClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" –LdapAttributeToClaimMapping @($mappingGivenName, $mappingSurname, $mappingDisplayName, $mappingEmployeeID) –Enabled $true –OrganizationalAccountSuffix "ADLDSCORP.LAB" -AcceptanceTransformRules "@RuleName = `"Issue All Mapped Claims`"`nc:[] => issue(claim = c);"
Figure 1b: Creating A Local Claims Provider Based Upon ADLDS In ADFS v4.0 (HRD Will Be Through UPN Suffix)
–
REMARK: in this case the yellow error occurs because I have not enable and also not configured device registration
–
Now let’s try this!
Figure 2: Targeting The "Show My Claims App" And Selecting ADFS v4.0 As The Proposed IdP
–
Figure 3a: Home Realm Discovery Page In ADFS v4.0 Showing All Configured/Available Identity Providers (Claims Providers)
–
Selecting/clicking "ADLDS-ID-Store", presents the Forms Based Logon Page In ADFS v4.0 (figure 4)
Figure 3b1: Home Realm Discovery Page In ADFS v4.0 NOT Showing All Configured/Available Identity Providers (Claims Providers)
–
Selecting/clicking "Other Organization", presents the Home Realm Discovery Page Based Upon UPN Suffixes of organizational accounts
Figure 3b2: Home Realm Discovery Page In ADFS v4.0 Based Upon UPN Suffix Of Organizational Accounts
–
Figure 4: Forms Based Logon Page To Enter The Credentials Of A User Account In The Configured ID Store
–
Figure 5: The List Of Issued Claims To The "Show My Claims" App Based Upon What Was Extracted From The ADLDS ID Store
–
SOME REMARKS: During my tests I also tried to the following setup:
Specifying just 3 attribute-to-claim mappings
$mappingGivenName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute givenName –ClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
$mappingSurname = New-AdfsLdapAttributeToClaimMapping –LdapAttribute sn –ClaimType "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
$mappingDisplayName = New-AdfsLdapAttributeToClaimMapping –LdapAttribute displayName –ClaimType "http://temp.org/identity/claims/displayName" $mappingEmployeeID = New-AdfsLdapAttributeToClaimMapping –LdapAttribute employeeID –ClaimType http://temp.org/identity/claims/employeeID
–
…And then use a file with the content of the Acceptance Transform Rules
File Name: D:\TEMP\ADLDS-ID-Store_AcceptanceTransformRulesFile.txt
Contents:
@RuleName = "Identity Claims – UPN"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", Issuer == "urn:adlds:idstore"]
=> issue(claim = c);
@RuleName = "Identity Claims – GivenName"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", Issuer == "urn:adlds:idstore"]
=> issue(claim = c);
@RuleName = "Identity Claims – SurName"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", Issuer == "urn:adlds:idstore"]
=> issue(claim = c);
@RuleName = "Identity Claims – DisplayName"
c:[Type == "http://temp.org/identity/claims/displayName", Issuer == "urn:adlds:idstore"]
=> issue(claim = c);
@RuleName = "Identity Claims – EmployeeID"
c:[Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn", Issuer == "urn:adlds:idstore"]
=> issue(store = "ADLDS ID Store", types = ("http://temp.org/identity/claims/employeeID"), query = ";employeeID;{0}", param = c.Value);
–
All the claims rules worked, except the last one called "Identity Claims – EmployeeID". The reason for that is that when you specify store = "ADLDS ID Store", ADFS expects to find an attribute store with that name, but for which in this case it is not an attribute but rather an identity store. It is possible to extract identity info from attribute stores when using a local claims provider trust, as long as the attribute store definition exists in ADFS and it actually works!
–
Cheers,
Jorge
———————————————————————————————
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always evaluate/test yourself before using/implementing this!
* DISCLAIMER: https://jorgequestforknowledge.wordpress.com/disclaimer/
———————————————————————————————
############### Jorge’s Quest For Knowledge #############
######### http://JorgeQuestForKnowledge.wordpress.com/ ########
———————————————————————————————
jason said
This didn’t work for me…. When I go to the IdpInitiatedSignon page and click the secondary IdP, it looks like the browser is trying to redirect me and the querystring contains something like “redirectIdp=urn:adlds:idstore”
I get this error, any ideas?
“no authentication provider could be found that supports the authentication methods specified in the claims provider trust.”
LikeLike
Jorge said
my assumption is that redirection works, but that the configured LDAP store is not working properly. can you use LDP to authenticate against it using the service account and the regular user?
LikeLike
jason said
I am getting errors running add-adfsLocalClaimsProviderTrust: an error occurred parsing the account store specific parameters…
LikeLike
Jorge said
please provide all the commands you used
LikeLike
Pen Warner said
Hi Jorge
Great article, have got everything setup however whenever I try to run the Add-AdfsLocalClaimsProviderTrust I get the Error The supplied Credential is invalid. No matter what account I use in every conceivable format it gives the same error,
“Add-AdfsLocalClaimsProviderTrust : MSIS3328: Unable to query the LDAP servers. The supplied credential is invalid.
Error code: 49
Server response message: 8009030C: LdapErr: DSID-0C0903C8, comment: AcceptSecurityContext error, data 2030, v2580”
I know the account has permissions and I can connect and bind using ldp.
Any ideas what I could be doing wrong?
Many thanks
Pen
PS: the accounts I have tried:
DOMAIN\Username
Username@domain
User DN of LDS user in the administrators group.
LikeLike
Pen Warner said
Managed to work it out using username@domain by changing the AuthType from basic to negotiate….
LikeLike
Jorge said
can you mail me all the commands you were using if not solved yet
LikeLike
Maras said
Unfortunately I have a problem also. I configured ADFS follow you article and I use application based also on your previous article. When I try to authenticate using account from AD LDS I get an error : Incorrect User ID or password. Obviously credentials are OK. I noticed some ADFS errors in event viewer. It looks like that ADFS is not able to find accounts in AD LDS. error states :
test2@test1.xx.xx.test-The object does not exist.
Error code: NoSuchObject
This error concerns service account (used during establish trust connection) and any other accounts located in AD LDS. The path in -UserContainer parameter looks correct in my opinion.
LikeLike
Jorge said
is the service account in ADLDS?
Did you assign the service account at least the Readers role in the NC where the objects are?
LikeLike
Eduardo said
I have the same problem in ADFS 4.0. In event viwer the error found is
mydomain\userinscript-MSIS8017: No user account is found for identity ‘mydomain\vendorone’.
LikeLike
Jorge said
you would need to provide more details of what you were doing
LikeLike
Kunal said
ldap_bind: Invalid credentials (49)
additional info: 8009030C: LdapErr: DSID-0C0903C8, comment: AcceptSecurityContext error, data 2030, v2580
LikeLike
Jorge said
It is nearly impossible to even say something just based on the error, without even knowing what you are trying to achieve or what command you were running
But here is a long shot: Although the AuthenticationMethod property supports Basic, Kerberos, Negotiate, in Windows Server 2016 you can ONLY use BASIC. Not even near sure if this fixes your problem or not due to not having enough information
Regards,
Jorge
LikeLike
Kunal said
Hi All,
I am facing the same issue.
ldap_bind: Invalid credentials (49)
additional info: 8009030C: LdapErr: DSID-0C0903C8, comment: AcceptSecurityContext error, data 2030, v2580
Could someone help me to fix this
LikeLike
Jorge said
It is nearly impossible to even say something just based on the error, without even knowing what you are trying to achieve or what command you were running
But here is a long shot: Although the AuthenticationMethod property supports Basic, Kerberos, Negotiate, in Windows Server 2016 you can ONLY use BASIC. Not even near sure if this fixes your problem or not due to not having enough information
Regards,
Jorge
LikeLike
Jorge said
Hi,
Have you tried to use the account in UPN format. Somebody else above had the same issue and mentioned that the UPN format did work
LikeLike
Valery said
Hello! I need to configure ADFS 4.0 + SharePoint Portal Server 2016 sites to get access with AD LDS GROUPS. Is it possible? How to make this configuration? Thank You!
LikeLike
Jorge said
Hi,
Have a look at the following blog post:
https://jorgequestforknowledge.wordpress.com/2018/10/11/configuring-a-new-identity-store-as-a-local-claims-provider-in-adfs/
regards,
jorge
LikeLike
Rajeev Chauhan said
Jorge
I am using following following configuration getting error incorrect user name or password . Native LDP works with same user name and password
two forest core.local & coreldp.local with one way trust
ldapuser = “Administrator@coreldp.local”
$ldappassword = ConvertTo-SecureString -String “**********” -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ldapuser,$ldappassword
$ldap_dir=New-AdfsLdapServerConnection -hostname coreldp.local -port 389 -sslmode None -AuthenticationMethod Negotiate -Credential $Credential
$email=New-AdfsLdapAttributeToClaimMapping -LdapAttribute email -ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/email”
$givenName = New-AdfsLdapAttributeToClaimMapping -LdapAttribute givenName -ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname”
$surname = New-AdfsLdapAttributeToClaimMapping -LdapAttribute sn -ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname”
$WindowsAccount = New-AdfsLdapAttributeToClaimMapping -LdapAttribute sAMAccountName “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname”
$upn= New-AdfsLdapAttributeToClaimMapping -LdapAttribute upn -ClaimType “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn”
Add-AdfsLocalClaimsProviderTrust -Name “CoreLdp” `
-Identifier “urn:CoreLdp” `
-type ldap `
-ldapserverconnection $ldap_dir `
-OrganizationalAccountSuffix @(“coreldp.local”)`
-UserObjectClass user `
-UserContainer “DC=coreldp,DC=local” `
-LdapAuthenticationMethod negotiate `
-AnchorClaimLdapAttribute sAMAccountName `
-AnchorClaimType “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname” `
-AcceptanceTransformRules “c:[] => issue(claim=c);”`
-Enabled $true `
-LdapAttributeToClaimMapping @($email, $givenName, $surname, $upn, $WindowsAccount) `
Thanks
LikeLike
Jorge said
As the “AuthenticationMethod” you are specifying (twice) to use “Negotiate”. Although Negotiate is a supported parameter value, in addition to BASIC and KERBEROS, ADFS in Windows Server 2016 only supports “Basic” (username and password)
Regards,
Jorge
LikeLike
Tom said
Hi Jorge,
I am receiving the following when configuring this in my test environment. I have tried to create the appropriate containers as per AD FS 2.0 reports where users encountered a similar issue. The user account I am using is in the Enterprise and Domain admin groups (to try and just to get it to return with success).
I ran Wireshark and confirmed that it is talking to Active Directory, and that Active Directory is sending responses. So I have reason to believe that it is definitely getting stuck on the container creation step, and not the AD connectivity step.
Any ideas?
“””
Add-AdfsLocalClaimsProviderTrust : PS0286: AdfsLocalClaimsProviderTrust requires a Certificate container to be
available in Active Directory for use with sharing certificates, but the container could not be created. PS0151: Could
not connect to Active Directory. Verify that you have sufficient privileges to connect to Active Directory and create
an Active Directory container.
Alternatively you can run ‘Set-AdfsCertSharingContainer’ to create a container and re-run this command.
At line:1 char:1
“””
Cheers,
Tom
LikeLike
Jorge said
The Cert Sharing container is related to ADFS using ADFS Managed Self-Signed Certificates for the token signing certificate and the token encryption certificate. When the “AutoCertificateRollover” is set to TRUE, the “CertificateSharingContainer” property MUST specify the DN of the certificate sharing container in AD. The ADFS servers and the cert sharing container must be in the same AD domain. When the “AutoCertificateRollover” is set to FALSE, the “CertificateSharingContainer” property CAN have a DN specified but in that case it is not being and can be removed if needed (but only when yo uare not going to use it in the future.
Best regards,
jorge
:
\\ I have no idea why it is related to AutoCertificateRollover : FalseCertificateSharingContainer :
LikeLike
Jorge said
Hi,
I still do not understand why there is a related between the cert sharing container and creating a local CP trust.
However, I do not how to fix it. Check out the upcoming post
cheers,
jorge
LikeLike
Jorge said
Hi,
Check this out:
https://jorgequestforknowledge.wordpress.com/2018/10/11/configuring-a-new-identity-store-as-a-local-claims-provider-in-adfs/
regards,
jorge
LikeLike
Alex said
Hi,
I tried your example and it works well when I use ldap and 389, but as soon as I Switch to SSL and 636 it fails and I get
Add-AdfsLocalClaimsProviderTrust : MSIS3328: Unable to query the LDAP servers. The LDAP server is unavailable.
The LDAP Server is a Active Directory Server which has SLDAP certificates (I tried to Access it with LDAP Browser without any issues on 636)
$ldapdir = New-AdfsLdapServerConnection –HostName Server.domain.local –Port 636 -SslMode SSL –AuthenticationMethod Basic –Credential $idStoreAccountCreds
Add-AdfsLocalClaimsProviderTrust –Name “LDAP-USERID” –Identifier “urn:ldap-userid” –Type Ldap -LdapServerConnection @($ldapdir) –UserObjectClass user –UserContainer “DC=domain,DC=local” –LdapAuthenticationMethod Basic –AnchorClaimLdapAttribute sAMAccountName –AnchorClaimType “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname” –LdapAttributeToClaimMapping @($GivenName, $Surname, $CommonName, $Email, $UPN, $WindowsAccount) -AcceptanceTransformRules “@RuleName = `”Issue All Mapped Claims`”`nc:[] => issue(claim = c);” –Enabled $true
any idea??
LikeLike
Jorge said
Have you tried to connect from the adfs server using the ldap browser or ldp. Does that succeed or fail?
Send me the exact command without any password value (use some placeholder) but with the username through the contact page of the blog
LikeLike
Alex said
Heureka – I found it – the SLDAP cert on the DC isissued by a MS CA, but the ADFS didnt have the Root CA of the SLDAP cert in its trusted root store. After adding it, it worked straight away.
Cheers
LikeLike
Jorge said
Great that it works now! 👍🏽👍🏽👍🏽
LikeLike
Alex said
@Jorge: I really like this localclaimprovidertrust – but attaching a second AD Domain, has its caveats. I just found out that PW Change is not possible. If you logon to ADFS via the localclaimprovidertrust with an account, where the password is expired, you get an error: “wrong username or Password”
;-((
Cheers
LikeLike
Jorge said
Hi,
Thanks for the info. How did you specify your user account in the username field?
regards,
jorge
LikeLike
Alex said
Hi
I tried with 3 different localclaimprovidertrust Connections to the Domain (upn, samaccountname, mail)
As soon as the user account’s pw is expired it Fails.
Thanks
LikeLike
Jorge said
Isn’t that to be expected?
LikeLike
Alex said
Probably yes, as you cant do pw reset/expiration with a simple ldap query/auth. But due to this fact, I cant use the localclaimprovidertrust in my scenario, as ADFS is the only Point where these users can authenticate and if their pw expires (due to policy every 3 month), they cant Change it. So I changed the solution to use a Claim Provider trust and one ADFS farm per AD Forest.
I think this is an important point to consider when designing localclaimprovidertrust.
Thanks
LikeLike