Some tips on Active Federation with ADFS 2.0

Introduction

At work I have been working on helping my company adopt ADFS 2.0 for a Single Sign-On initiative. I have been working on handling a WPF application’s federation with ADFS and needed to use active federation (by definition). I had been following along with Dominick Baier’s blog post at http://www.leastprivilege.com/WIFADFS2AndWCFndashPart5ServiceClientMoreFlexibilityWithWSTrustChannelFactory.aspx. Dominick’s sample seemed simple enough but there were quite a few ADFS things I had to figure out in order to make things work.

BTW, learning how WIF relates to ADFS has been quite challenging but I have found the following article to be very helpful: http://technet.microsoft.com/en-us/library/adfs2-federation-wif-application-step-by-step-guide(WS.10).aspx.

Issues

    1. So I downloaded the code for the post and tried running the ManualClient. This uses WSTrustChannelFactory to connect to ADFS. The base sample uses the following ADFS endpoint:
      static string stsEndpoint = "https://<machine.domain>/adfs/services/trust/13/windowstransport";
      

      The windowstransport ADFS endpoints are not enabled by default so you must enable them. When I first tried to enable the WS Trust 1.3 version it would enable but it would not allow me to enable the proxy for this. I am not sure why. Eventually I was able to get the WS Trust 1.3 endpoint enabled. So at first I switched over to using the WS Trust 2005 endpoint. I also had to change the trust version to TrustVersion.WSTrustFeb2005 in the code as well. Here is the updated code at this point:

      static string stsEndpoint = "https://<machine.domain>/adfs/services/trust/2005/windowstransport";
      static string svcEndpoint = "https://<machine.domain>/soapadfs/service.svc";
      
      static void Main(string[] args)
      {
         var token = GetToken();
         CallService(token);
      }
      
      private static SecurityToken GetToken()
      {
         var factory = new WSTrustChannelFactory(
            new WindowsWSTrustBinding(SecurityMode.Transport),
            stsEndpoint);
      
         factory.TrustVersion = TrustVersion.WSTrustFeb2005;
      
         var rst = new RequestSecurityToken
         {
            RequestType = RequestTypes.Issue,
            AppliesTo = new EndpointAddress(svcEndpoint),
            KeyType = KeyTypes.Symmetric
         };
      
         var channel = factory.CreateChannel();
      
         return channel.Issue(rst);
      }
      
    2. So then I ran the code and it got all the way to the last line of the method GetToken() and it gives me the following nearly meaningless message back (wrapped in a FaultException):

      ID3082: The request scope is not valid or is unsupported.

      I was not able to find very good information on this error but I eventually found out that one of the reasons that this can occur is if you have not setup a relying party trust in ADFS for your application.

    3. Like with much of active federation, there is a lot less documentation out there for active federation than for passive federation. Here are the steps I went through to create an ADFS relying party for an application that does not have a federation metadata document:

      a. In the ADFS 2.0 MMC, click to create a Relying Party trust.
      b. On the next page of the wizard, choose to “Enter data about the relying party manually”. Click Next
      c. Enter a display name, click Next
      d. Choose ADFS 2.0, click Next
      e. For now, do not specify an encryption certificate, click Next,
      f. Do not click to enable WS-Federation passive or Web-SSO. Both of these are browser-based options that do not apply to active federation. Click Next.
      g. For the relying party trust identifier, enter the endpoint reference you are using to call over WS-Trust, so I entered: <a href=”https:///soapadfs/service.svc”>https://<machine.domain>/soapadfs/service.svc
      h. Click to allow all to access the relying party, click Next.
      i. Click Next to move on to the Claims Authorization Wizard.
      j. I just specify a Windows username pass through at this point (see the link in my introduction for how to set this up).

    4. So then I try to run the application again and I get another annoying error message:

ID3037: The specified request failed.

Unfortunately, this is a very general one. The solution I found was to go into the relying party trust and specify the encryption certificate.

  1. Then I can successfully get the GetToken method to work properly. I did also notice one other variation in the ADFS configuration that can lead to a weird error. If you disable a relying party trust and try to run the application again you get the following error:

MSIS3127: The specified request failed.

To resolve this, simply enable the relying party trust.

Conclusion

I have found that much of the work with ADFS goes by the principle, “no guts, no glory,” and I wish it were easier. There seem to be a large number of errors that you can receive without a lot of helpful information for helping you resolve them. Hopefully these error resolutions will help you and I will be sure to post any other workarounds I find as I get further down the road of implementing ADFS.

Thanks,

11 thoughts on “Some tips on Active Federation with ADFS 2.0

Add yours

  1. “While this post is not that old it was from the days of ADFS v1 (and ADFS v2 pre-release) and quite a bit has changed since then.”

    That’s not true – this is based on ADFS2 and WIF RTM versions.

  2. I just noticed an html anchor tag got inserted accidentally on this post. This is a WordPress bug. if you see it here just ignore it. Sorry

  3. Hi,

    Good post,

    I’ve made a test webapp where I try to get a token from codebehind.
    I use Windows Auth on the test site and I’ve used code from Your sample (/trust/13/windowstransport)

    The test site gets a token as long as I have the test site in the IE Intranet Zone.

    If the site is not in the IE Intranet Zone I get a logon prompt an an error on the folowing line
    return channel.Issue(rst);

    The remote server returned an error: (403) Forbidden.
    [MessageSecurityException: The HTTP request was forbidden with client authentication scheme ‘Negotiate’.]

    Any idea what the problem could be?

    Regards Magnus

  4. Magnus,
    I believe that you need the site to belong to the Local Intranet zone, as the ADFS process extracts the details from your kerberos credentials embedded within the HTTP session (for an SSO) experience. If the site is not within the local intranet zone no kerberos credentials.
    Am sure Ben can confirm.

  5. Ben,

    You said this in the post…

    “When I first tried to enable the WS Trust 1.3 version it would enable but it would not allow me to enable the proxy for this. I am not sure why.”

    Did you ever figure out why that was. I ask because I’m was trying route a kerberos credential through ACS to my AD FS proxy and I can’t seem to enable /adfs/services/trust/13/windowstransport either at least not on the proxy.

    Any ideas?

  6. I have an issue with IFD CRM. Am trying to connect to crm with network credentials. but it throwing as “The NetworkCredentials provided were unable to create a Kerberos credential, see inner exception for details.” and am able to connect to crm with username and password.

    Please help me….

  7. Can you explain for me how I can authenticate without user interaction (active authentication) to a CRM 2016 APP that is protected with ADFS server?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: