ADFS Authentication Needs

To understand what is required to authenticate, you can access the ADFS server and identify, based on your preferred authentication approach, the policy can be reviewed. ADFS metadata is published from the ADFS server, for example, at https://auth.demo.local/adfs/services/trust/mex.

Let's say you want to use a username and password to authenticate, you can find the specific binding endpoint by looking at the list included in the XML from the above metadata:

<wsdl:port binding="tns:UserNameWSTrustBinding_IWSTrust13Async" name="UserNameWSTrustBinding_IWSTrust13Async">
      <soap12:address location="https://crm.demo.local/adfs/services/trust/13/usernamemixed"/>
      <wsa10:EndpointReference>
        <wsa10:Address>https://crm.demo.local/adfs/services/trust/13/usernamemixed</wsa10:Address>
      </wsa10:EndpointReference>
</wsdl:port>

The specification says to access the policy reference UsernameWSTrustBinding_IWSTrust13Async_policy which is included in the same document. That snippet looks like:

<wsp:Policy wsu:Id="UserNameWSTrustBinding_IWSTrust13Async_policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <sp:TransportBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:TransportToken>
              <wsp:Policy>
                <sp:HttpsToken/>
              </wsp:Policy>
            </sp:TransportToken>
            <sp:AlgorithmSuite>
              <wsp:Policy>
                <sp:Basic256/>
              </wsp:Policy>
            </sp:AlgorithmSuite>
            <sp:Layout>
              <wsp:Policy>
                <sp:Strict/>
              </wsp:Policy>
            </sp:Layout>
            <sp:IncludeTimestamp/>
          </wsp:Policy>
        </sp:TransportBinding>
        <sp:SignedEncryptedSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:UsernameToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
              <wsp:Policy>
                <sp:WssUsernameToken10/>
              </wsp:Policy>
            </sp:UsernameToken>
          </wsp:Policy>
        </sp:SignedEncryptedSupportingTokens>
        <sp:EndorsingSupportingTokens xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:KeyValueToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never" wsp:Optional="true"/>
            <sp:SignedParts>
              <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
            </sp:SignedParts>
          </wsp:Policy>
        </sp:EndorsingSupportingTokens>
        <sp:Wss11 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy/>
        </sp:Wss11>
        <sp:Trust13 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
          <wsp:Policy>
            <sp:MustSupportIssuedTokens/>
            <sp:RequireClientEntropy/>
            <sp:RequireServerEntropy/>
          </wsp:Policy>
        </sp:Trust13>
        <wsaw:UsingAddressing/>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>

It is this policy that is transmitted to user agents that wish to authenticate. The policy section contains policy assertions which are at a top level specified in WS-SecurityPolicy. This particular assertion indicates that:

  • TransportBinding: Indicates that message protection is provided by means other than techniques described in WS-SecurityPolicy, for example, by HTTPS. The assertion above indicates this by TransportToken policy HttpsToken which says that HTTPS is supported, the header must be laid out strictly (vs lax) and that the algorithm suite for performing cryptographic operations is Basic256. Basic256 indicates that SHA1 should be used for digest calculation.

    sp:IncludeTimestamp: A policy assertion that indicates that the security header should include a Timestamp element. Since Transport security is used, the Timestamp must be part of a signature calculation—which is called a supporting token.

  • wsaw:UsingAddressing: A policy that indicates that the endpoint conforms to the * WS-Addressing specification. There are three separate WS Services Addressing specification documents: core, WSDL and SOAP. wsaw refers to the WS Services Addressing - WSDL. With this assertion, ReplyTo, Action and and To should be included in the headers. The use of the "mustUnderstand" attribute is also described in this specification.

  • SupportingTokens: Additional tokens may also be included to enhance message security. This is referred to as "augmenting the claims." Since Transport security is used, the supporting token (a signature) must include a Timestamp element and included in the Security header. Additional elements can be signed as part of creating a supporting token as well and these additional elements would be specified in SignedParts. The policy above suggests two additional supporting tokens:

    • SignedEncryptedSupportingTokens: This policy indicates that an additional token, a UsernameToken, should be included in the RST. The contents of a UsernameToken are specified in a WS specification: http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf. This specific policy element does not indicate whether the password is allowed to be clear text or encrypted in some way. We can use clear text password content fortunately, as HTTPS requires the entire message to be encrypted.

    • EndorsingSupportedTokens: This policy indicates that the Signature element is signed. It may seem duplicative but the approach is quite common, that is, you sign a signature. The policy here says to sign the To field that is present from WS-Addressing. However, the KeyValueToken:Optional=true indicates that this is optional and hence you can ignore the EndorsingSupportedTokens policy if you wish to.

  • Trust13: This assertion indicates which WS-Trust (version) 1.3 options are supported. This is a straightforward list that can be lookup in the WS-Trust specification.

Based on interpreting the policy assertions above, what's needed when requesting authentication?

  • A Timestamp token (element) in the Security header.

  • A UsernameToken. This means that a username and some form of password must be provided.

For example, when authenticated to an on-premise IFD deployment, the authentication request can look like:

<s:Envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
    <a:MessageID>urn:uuid:f2d2bda8-b82a-4e0f-b8f2-2b15205822d7</a:MessageID>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <Security s:mustUnderstand="1" 
    xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
    xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <u:Timestamp u:Id="4a425ec0-7a08-4be5-95be-9eec5755d53b">
        <u:Created>2016-12-14T18:09:37.0000113Z</u:Created>
        <u:Expires>2016-12-14T19:09:37.0000113Z</u:Expires>
      </u:Timestamp>
      <UsernameToken u:Id="d071dbfb3-6b68-431d-b9a7-78288fe6eb27">
        <Username>crmuser@demo.local</Username>
        <Password 
        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">crmuser</Password>
      </UsernameToken>
    </Security>
    <a:To s:mustUnderstand="1">https://crm.demo.local/adfs/services/trust/13/usernamemixed</a:To>
  </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://crmdemo.demo.local:444/XRMServices/2011/Organization.svc</a:Address>
        </a:EndpointReference>
      </wsp:AppliesTo>
      <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
    </trust:RequestSecurityToken>
  </s:Body>
</s:Envelope>

The Security header elements includes these two parts in the RST. The request itself is in the Body.

Last updated