ADFS 2016 - Bypass Login Page using Local Claims Provider

Cedric D 131 Reputation points
2020-04-21T16:15:56.28+00:00

Hello,

I am on ADFS 2016 and I would like to bypass ADFS login page and use RESTful API to authenticate users stored in an LDAP Directory (Declared as Local Claims Provider).

With ROPC, I can obtain an Access and an ID Token using AD Account Store.
But I can't use my Local Claims Provider to authenticate users.

Do you know if there is a specific configuration or parameter to do this?

My configuration :

  • ADFS 2016
  • LDAP Local Claims Provider
  • OpenID Connect with ROPC flow
  • Note : With an authorization Code flow, I'm redirected to ADFS Login page where I can choose my Local Claims Provider and the authentication is OK.

Thanks by advance for your help.

Active Directory Federation Services
Active Directory Federation Services
An Active Directory technology that provides single-sign-on functionality by securely sharing digital identity and entitlement rights across security and enterprise boundaries.
1,189 questions
0 comments No comments
{count} votes

Accepted answer
  1. Cedric D 131 Reputation points
    2020-06-15T07:49:47.56+00:00

    Finally, I succeed to bypass ADFS login page and mix it with OBO flow.

    Here the solution :

    1. Get JWT token for App A. I send a SOAP request to the endpoint /adfs/services/trust/2005/usernamemixed with<trust:TokenType>urn:ietf:params:oauth:token-type:jwt</trust:TokenType> (Same request as my first response).
    2. Base 64 decode the wsse:BinarySecurityToken
    3. Send the JWT to the endpoint /adfs/oauth2/token. Here the parameters : client_id, client_secret, scope (openid user_impersonation), assertion (the base64 decoded JWT), resource (the App B url), requested_token_use (on_behalf_of).
    4. You will get the access_token, id_token and refresh_token for App B.

    You can't get the ADFS cookies but you have your OIDC tokens.

    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. rbrayb 21 Reputation points MVP
    2020-04-22T20:38:16.843+00:00

    In SAML, you can do this with the SAML bearer assertion flow.

    But note that this requires federation.

    As per this:

    "All passive authorization protocols that are supported by AD FS, including SAML, WS-Federation, and OAuth are also supported for identities that are stored in LDAP directories.

    The WS-Trust active authorization protocol is also supported for identities that are stored in LDAP directories."

    So if you want to use an API, you need to do this via WS-Trust.

    1 person found this answer helpful.
    0 comments No comments

  2. Cedric D 131 Reputation points
    2020-04-27T08:47:13.977+00:00

    Thanks for your answer, @rbrayb .

    I tried the SAML bearer assertion flow, but it seems that the endpoint /adfs/services/trust/2005/usernamemixed works only with Azure AD.
    So I tried this endpoint /adfs/services/trust/13/UsernameMixed with this request :

    <?xml version="1.0" encoding="utf-8"?>  
    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">  
        <s:Header>  
            <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>  
            <a:To s:mustUnderstand="1">https://adfs.test.local/adfs/services/trust/13/UsernameMixed</a:To>  
            <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" >  
                <o:UsernameToken u:Id="uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1">  
                    <o:Username>**USERNAME**</o:Username>  
                    <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">**PASSWORD**</o:Password>  
                </o:UsernameToken>  
            </o:Security>  
        </s:Header>  
        <s:Body>  
            <trust:RequestSecurityToken xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">  
                <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">  
                    <a:EndpointReference>  
                        <a:Address>**https://mysite.identifier**</a:Address>  
                    </a:EndpointReference>  
                </wsp:AppliesTo>  
                <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>  
                <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>  
                <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>  
            </trust:RequestSecurityToken>  
        </s:Body>  
    </s:Envelope>  
    
    • With an USERNAME/PASSWORD from the Active Directory, It works and I get my SAML Response.
    • But with the USERNAME/PASSWORD from my Local LDAP Directory, I have the following error : ID3242: The security token could not be authenticated or authorized.

    When I check the ADFS logs :

    Token Type:
    http://schemas.microsoft.com/ws/2006/05/identitymodel/tokens/UserName
    %Error message:
    USERNAME-The user name or password is incorrect

    I tried with the DN of the account but same error, even if I have set only my Local LDAP Directory as unique claimsProvider for the application with this command :

    Set-AdfsRelyingPartyTrust -TargetName "myClaimAPP" -ClaimsProviderName @("MY LDAP DIRECTORY")  
    

    With the classic SP-initiated flow it works well (I have only my LDAP Directory form).

    I suppose that it must have a special parameter to had in the SOAP Request ou maybe a configuration in SAML to use the LDAP Local Claims Provider instead of the Active Directory but I can't find anything.
    Do you have any idea, please?

    0 comments No comments

  3. rbrayb 21 Reputation points MVP
    2020-04-29T20:22:18.573+00:00

    Have a look at this.

    There are some parameters you may not have?

    I'm not aware of any SAML specific parameters for LDAP.

    0 comments No comments

  4. Cedric D 131 Reputation points
    2020-05-06T13:38:38.98+00:00

    Hello @rbrayb

    Finally, I succeeded the first step! Now, I can get the SAML Assertion based from the LDAP Local Claims Provider.

    Here the steps to get a SAML Assertion with the endpoint /adfs/services/trust/2005/usernamemixed :

    1- Setup an Organisational Account Suffix for the Local Claims Provider

    Set-AdfsLocalClaimsProviderTrust -TargetName "MY LDAP DIRECTORY" -OrganizationalAccountSuffix @("test.com")  
    

    Note : The username must contain the Organisational Account Suffix. Use the email adresse as AnchorClaimLdapAttribute for instance.

    2- In the SOAP Request, set the username wich contains the Organisational Account Suffix

    <o:UsernameToken u:Id="uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1">  
    <o:Username>**me@test.com**</o:Username>  
    <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">**PASSWORD**</o:Password>  
    </o:UsernameToken>  
    

    3- The ADFS use the LDAP Local Claims Provider to authenticate the user and returns a SAML Assertion

    But I always have some issues with the next step:

    I try your link to get the access token but it works only with Azure. The grant types urn:ietf:params:oauth:grant-type:saml1_1-bearer and urn:ietf:params:oauth:grant-type:saml2-bearer are not supported in ADFS 4.0/2016 (as explain in this link : https://social.technet.microsoft.com/Forums/en-US/47dc854e-eabf-44ee-b012-df71fa2c1da4/implement-rfc-7522-saml-bearer-for-oauth-on-our-adfs-v3?forum=ADFS )

    Maybe I can try to obtain the access token with the grant type urn:ietf:params:oauth:grant-type:jwt-bearer and use the OBO flow for the next step: https://learn.microsoft.com/fr-fr/windows-server/identity/ad-fs/overview/ad-fs-openid-connect-oauth-flows-scenarios#on-behalf-of-flow

    First I have to obtain an access token from the SAML assertion.

    0 comments No comments