locked
Securing a WCF REST Service with ACS with ADFS As Identity Provider RRS feed

  • Question

  • Hello, I have a WCF REST based service that I'd like to authenticate users for this service via ADFS over ACS.

    Initially this code works with ACS with ACS as the identity provider meaning that I have the user names and passwords stored in Service Identies.  Next, I changed my identifiy provider to ADFS and everything stopped working.  What will happen is when I attempt to get my Token from ACS - I get a 401 unauthorized.

    I'm using tokens in SWT format, and I tested the ACS / ADFS setup by going into 'Application Integration' in my ACS portal, and then clicking login pages, and attempting to login.  So I believe my ACS / ADFS config is correct.  Does anyone know if this is possible to get working with ACS / ADFS and a WCF REST service?

    Thanks

    class Program
        {
            static string serviceNamespace = "MyServiceNamespace";
            static string acsHostUrl = "accesscontrol.windows.net";
            static string realm = "http://localhost/MyRealm";
            static string uid = "MyUserName@MyDomain";
            static string pwd = "Password";
            static string serviceUrl = "http://localhost/RESTfulWCFUsersServiceEndPoint.svc";
            static string serviceAction = @"/users";
    
            static void Main(string[] args)
            {
                string token = GetTokenFromACS(realm);
    
                WebClient client = new WebClient();
    
                string headerValue = string.Format("WRAP access_token=\"{0}\"", token);
    
                client.Headers.Add("Authorization", headerValue);
    
                Stream stream = client.OpenRead(serviceUrl + serviceAction);
    
                StreamReader reader = new StreamReader(stream);
                String response = reader.ReadToEnd();
                Console.Write(response);
                Console.ReadLine();
    
            }
    
            private static string GetTokenFromACS(string scope)
            {
                string wrapPassword = pwd;
                string wrapUsername = uid;
    
                // request a token from ACS
                WebClient client = new WebClient();
                client.BaseAddress = string.Format("https://{0}.{1}", serviceNamespace, acsHostUrl);
    
                NameValueCollection values = new NameValueCollection();
                values.Add("wrap_name", wrapUsername);
                values.Add("wrap_password", wrapPassword);
                values.Add("wrap_scope", scope);
    
                byte[] responseBytes = client.UploadValues("WRAPv0.9/", "POST", values);
    
                string response = Encoding.UTF8.GetString(responseBytes);
    
                Console.WriteLine("\nreceived token from ACS: {0}\n", response);
    
                return HttpUtility.UrlDecode(
                    response
                    .Split('&')
                    .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
                    .Split('=')[1]);
            }
    
        }

    Friday, April 26, 2013 8:09 PM

All replies

  • Have you establish a trust relationship from ACS to ADFS? 
    ADFS won’t issue tokens for use against the Access Control Service if it doesn’t trust it – we’ll need to configure a default signing certificate in ACS, generate some Federation Metadata and share that with our ADFS instance to finish off the establishment of this trust relationship. 

    You can refer to this article for more details: 
    http://blogs.msdn.com/b/willpe/archive/2010/10/25/windows-authentication-adfs-and-the-access-control-service.aspx

    <//span>

    Yang Yang
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, April 29, 2013 4:49 AM
  • Thanks Yang Yang, I think what is happening in my case is that I'm using a SWT, and I need a SAML token for the request.  I was trying to get around using WIF to get the token, because this is going to be a cross platform WCF REST service.  So since WIF isn't available on all platforms I was trying to just use SWT.  Is there no way to get a token from ADFS using SWT without WIF?

    Thanks.

    Monday, April 29, 2013 2:54 PM
  • You can refer to this blog, and download the sample.<//span>

    http://blogs.msdn.com/b/willpe/archive/2010/10/25/windows-authentication-adfs-and-the-access-control-service.aspx 

    in this sample you can find it only use the WIF libary for serialize the SAML token, I think you can use your own method serialize the token to a tokenString.


    Yang Yang
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Dino He Monday, May 6, 2013 1:46 AM
    • Unmarked as answer by Allen Chen - MSFT Thursday, May 9, 2013 5:54 AM
    Tuesday, April 30, 2013 3:04 AM
  • Thanks Yang Yang, this example is exactly what I need, however when I get down to:

    GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken;
    In the GetSamlToken function, I receive the following error:

    Secure channel cannot be opened because security negotiation with the remote endpoint has failed. This may be due to absent or incorrectly specified EndpointIdentity in the EndpointAddress used to create the channel. Please verify the EndpointIdentity specified or implied by the EndpointAddress correctly identifies the remote endpoint.

    The inner exception is:

    The request for security token has invalid or malformed elements.

    I believe I have ACS and ADFS working properly - I believe this is due to an certificate issue, however I'm not sure and have tried a lot of things to make this work.  Do you know what would cause this?

    Thanks so much for all your help.

    Monday, May 6, 2013 2:10 AM