Error 401 Sending the Token to a Web Service

Unanswered Error 401 Sending the Token to a Web Service

  • Tuesday, May 17, 2011 6:17 PM
     
     

    Hello everybody,

    I have a solution using service bus who works fine. The client side (by a browser for example) makes a request about a file, and the service side gives the file to the client. This works putting in a browser : 'http://XXX.servicebus.windows.net/Image/GetFile/file.pdf' and you obtain the file.

    Now, I want to add authentication and authorization using Acces Control, so I change the App.config at the service, adding the next:

    <security relayClientAuthenticationType="RelayAccessToken"/> in the <webHttpRelayBinding> tag, so now, when you try to get a file, the browser shows you the next message:

    <Code>401</Code><Detail>The request contains no authorization header.</Detail>

    That's ok.

    My problem is next. I added code lines at the client side to obtain a Token using a pair Name/Password, unwrapp the token, and send the token in the header. The code is basically the next:

      string returnToken = tf.GetACSToken(name, password, "https://XXX.servicebus.windows.net/Image"); // this URL is the wrap_scope of the authentication
                   
      WebClient client = new WebCllient();

      client.Headers[HttpRequestHeader.Authorization] = string.Format("WRAP access_token=\"{0}\"", returnToken);

      byte[] response = client.DownloadData("https://XXX.servicebus.windows.net/Image/GetFile/hola.pdf");

    The code works fine, get the valid token, unwrap the token, insert the header, etc, but when the code execute 'client.DownloadData' an exception ocurrs. With a web debbuger I obtain the next error:

    <Error><Code>401</Code><Detail>Invalid token audience: https://XXX.servicebus.windows.net/Image/, expected: http://XXX.servicebus.windows.net/Image/GetFile/hola.pdf.</Detail></Error>

    My Access Control Settings are Relying Party Applications with 'https://XXX.servicebus.windows.net/Image' at Realm and Return Url, Token Format as SAML2.0, and a Default Rule Group with a Rule with 'Pass Through'.

    I know the error maybe is in use https instead http in the settings, but I tried many changes and I don't find the solution.

    Thank you.

All Replies

  • Tuesday, May 17, 2011 8:06 PM
     
      Has Code

    Have you tried modifying the token request to:

    string returnToken = tf.GetACSToken(name, password, "https://XXX.servicebus.windows.net/Image/GetFile/hola.pdf"); 
    
     The error message is pretty clear about what it wants. :)

    Developer Security MVP | http://www.steveonsecurity.com
  • Wednesday, May 18, 2011 8:28 AM
     
     

    Sorry, but I doesn't work. The error is the same : 401

    Now the error message I obtain from the web debugger is next:

    <Error><Code>401</Code><Detail>Invalid token audience: https://XXX.servicebus.windows.net/Image/GetFile/hola.pdf, expected: http://XX.servicebus.windows.net/Image/GetFile/hola.pdf.</Detail></Error>

    I need to use https urls, because I'm using service bus, and I think the problem maybe is between http and https, but I don't know hot to resolve it.

  • Wednesday, May 18, 2011 10:55 AM
     
      Has Code

    Finally I find the problem. When you use service bus, you have to use 'http' in the scope for the token request instead 'https', so I have to call the GetACSToken method by this way:

    string returnToken = tf.GetACSToken(name, password, "http://XXX.servicebus.windows.net/Image/GetFile/hola.pdf"); 

    Bu now, I have another problem in the same place: the service call. When I try to execute this:

    byte[] response = client.DownloadData("https://XXX.servicebus.windows.net/Image/GetFile/hola.pdf");

    Another 401 error exception appears. Now, the error message is : Error 401 : Invalid token signature.

    I'm making the token request against a Service Identity.

    I have read in other posts (older posts) that service bus removes the authorization token. Is this true? Or is it a older feature?

  • Thursday, May 19, 2011 6:26 AM
    Moderator
     
     

    Hi Alberto,

    Which TokenFactory class you were using?

    I refer to Calling a Service Bus HTTP Endpoint with Authentication using WebClient and successfully call my service through service bus. The code I used is:

        static void Main(string[] args)
        {
            string serviceNamespace = "my namespace";
            string issuerName = "my issuer name";
            string issuerKey = "my key";
            string serviceAddress = "https://[my namespace].servicebus.windows.net/[my file path]";

            string baseAddress = string.Format("http://{0}.servicebus.windows.net/", serviceNamespace);

            TokenFactory tf = new TokenFactory(string.Format("{0}-sb", serviceNamespace), issuerName, issuerKey);
            string requestToken = tf.CreateRequestToken();
            string returnToken = tf.GetACSToken(requestToken, baseAddress);

            WebClient client = new WebClient();
            client.Headers[HttpRequestHeader.Authorization] = string.Format("WRAP access_token=\"{0}\"", returnToken);
            string response = client.DownloadString(serviceAddress);

            Console.WriteLine(response);
            Console.ReadLine();
        }

    The TokenFactory class is from Requesting a Token from Access Control Service in C#. If it still does not work for you, can you show more code so that I can paste it in my side and reproduce the issue?

    Thanks,


    Wengchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
  • Thursday, May 19, 2011 12:00 PM
     
     

    Hello again,

    I`m using the same TokenFactory, the same sample, but the XXX-sb.accesscontrol.windows.net doesn't work for me. It returns an 'Error 401 Unathorized' when I try to send it the token request. So I use XXX.accesscontrol.windows.net to get te token, and this address works well.

    The only difference is that I`m working with Username/Password so I don't use the 'CreateRequestToken' method, I just use the next code below:

                NameValueCollection values = new NameValueCollection();
                values.Add("wrap_name", issuerName);
                values.Add("wrap_password", signingKey);
                values.Add("wrap_assertion_format", "SWT");
                values.Add("wrap_scope", scope);

                string response = null;

                byte[] responseBytes = client.UploadValues("WRAPv0.9/", values);
                response = Encoding.UTF8.GetString(responseBytes);

                return HttpUtility.UrlDecode(response
                    .Split('&')
                    .Single(value => value.StartsWith("wrap_access_token=", StringComparison.OrdinalIgnoreCase))
                    .Split('=')[1]);

    And this code returns us a correct token. When I try to send a client request to my service (with the token in the authorization header) via Service Bus (the client.DownloadData) is when I receive an Error 401 Invalid Token Signature, so I think It's something wrong in the token, but I don't know what.

    I try with Simetric Key instead Password, and get the same error, with SAML instead SWT, and nothing. I don't know how to get a solution.

     

     

  • Monday, May 23, 2011 3:09 AM
    Moderator
     
     

    Hi Alberto,

    Sorry for the late response.

    > the XXX-sb.accesscontrol.windows.net doesn't work for me. It returns an 'Error 401 Unathorized'.

    By using the code provided in my post, may I ask you to double check if issuerName, issuerKey, serviceAddress are correct? If it still does not work, may I ask for a sample code you use? This will be very helpful in case if there is a typo in your code or something.

    Thanks,


    Wengchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
  • Thursday, October 06, 2011 6:37 PM
     
     

    You must have figured out the solution by now. Which access control service are you using? For this solution to work, you have to use service bus access control service. The page which appears after selecting the "Service Bus" option in left pane, selecting the namespace and then clicking the "Access Control Service" button. The one which is opened after selecting the "Access Control" option is different than this one. It gave me hard time to figure this out. So thought of posting it.