locked
Windows 8 push notification problem: invalid_request & invalid_token

    Question

  • Hi,

    I am trying to send a toast notification to a w8 application, but sadly, the final GetResponseStream call fails with the following error:

    WWW-Authenticate: Bearer error="invalid_request",error_description="Invalid token"

    I followed these(http://msdn.microsoft.com/en-us/library/windows/apps/hh465407.aspx) steps to get the SID and the client secret and I am able to get an access token from the wpn. Please help, because I am out of ideas:(

    Thx,

    Szabolcs

    My code is as follows:(code block didnt work out well, so I put it in in text first and in a code block once again at the end of the post...)

    public void SendNotifications()
            {
                var token = GetAccessToken();
                foreach (var uri in _pushNotificationClients)
                {
                    Push(uri, token, GetToastMessage());
                }
            }

            private string GetAccessToken()
            {

                string url = "https://login.live.com/accesstoken.srf";
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";

                string sid = HttpUtility.UrlEncode("ms-app://s-1-......");
                string secret = HttpUtility.UrlEncode("xzKGLiBKav6z9dV1.....");
                string content = "grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com";

                string data = string.Format(content, sid, secret);

                byte[] notificationMessage = Encoding.Default.GetBytes(data);
                request.ContentLength = notificationMessage.Length;

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                }

                var response = (HttpWebResponse)request.GetResponse();

                string result;
                using (Stream responseStream = response.GetResponseStream())
                {
                    var streamReader = new StreamReader(responseStream);
                    result = streamReader.ReadToEnd();
                }

                return result;
            }

            private HttpStatusCode Push(string pushUri, string accessToken, string text)
            {
                var subscriptionUri = new Uri(pushUri);

                var request = (HttpWebRequest)WebRequest.Create(subscriptionUri);
                request.Method = "POST";
                request.ContentType = "text/xml";
                request.Headers = new WebHeaderCollection();
                request.Headers.Add("X-WNS-Type", "wns/toast");
                request.Headers.Add("Authorization", "Bearer " + accessToken);

                string data = "<?xml version='1.0' encoding='utf-8'?>" + text;

                byte[] notificationMessage = Encoding.Default.GetBytes(data);
                request.ContentLength = notificationMessage.Length;

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                }

                var response = (HttpWebResponse)request.GetResponse();

                return response.StatusCode;
            }

            private string GetToastMessage()
            {
                return @"<toast>
                            <visual lang=""en-US"">
                                <binding template=""ToastText01"">
                                    <text id=""1"">New test arrived!</text>
                                </binding> 
                            </visual>
                        </toast>";
            }

    public void SendNotifications()
            {
                var token = GetAccessToken();
                foreach (var uri in _pushNotificationClients)
                {
                    Push(uri, token, GetToastMessage());
                }
            }
    
            private string GetAccessToken()
            {
    
                string url = "https://login.live.com/accesstoken.srf";
                var request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
    
                string sid = HttpUtility.UrlEncode("ms-app://s-1-......");
                string secret = HttpUtility.UrlEncode("xzKGLiBKav6z9dV1.....");
                string content = "grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com";
    
                string data = string.Format(content, sid, secret);
    
                byte[] notificationMessage = Encoding.Default.GetBytes(data);
                request.ContentLength = notificationMessage.Length;
    
                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                }
    
                var response = (HttpWebResponse)request.GetResponse();
    
                string result;
                using (Stream responseStream = response.GetResponseStream())
                {
                    var streamReader = new StreamReader(responseStream);
                    result = streamReader.ReadToEnd();
                }
    
                return result;
            }
    
            private HttpStatusCode Push(string pushUri, string accessToken, string text)
            {
                var subscriptionUri = new Uri(pushUri);
    
                var request = (HttpWebRequest)WebRequest.Create(subscriptionUri);
                request.Method = "POST";
                request.ContentType = "text/xml";
                request.Headers = new WebHeaderCollection();
                request.Headers.Add("X-WNS-Type", "wns/toast");
                request.Headers.Add("Authorization", "Bearer " + accessToken);
    
                string data = "<?xml version='1.0' encoding='utf-8'?>" + text;
    
                byte[] notificationMessage = Encoding.Default.GetBytes(data);
                request.ContentLength = notificationMessage.Length;
    
                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(notificationMessage, 0, notificationMessage.Length);
                }
    
                var response = (HttpWebResponse)request.GetResponse();
    
                return response.StatusCode;
            }
    
            private string GetToastMessage()
            {
                return @"<toast>
                            <visual lang=""en-US"">
                                <binding template=""ToastText01"">
                                    <text id=""1"">New test arrived!</text>
                                </binding>  
                            </visual>
                        </toast>";
            }




    Wednesday, May 09, 2012 9:03 PM

Answers

  • I updated the POST and validated it works with the Consumer Preview.  Check it out!

    http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Friday, May 11, 2012 6:40 PM
    Moderator

All replies

  • Currently the developer page is not available so you cannot get a token to use.  Where did you get your token from?

    -Jeff


    Jeff Sanders (MSFT)

    Thursday, May 10, 2012 7:41 PM
    Moderator
  • I followed the "Remarks" part of this instruction page: http://msdn.microsoft.com/en-us/library/windows/apps/hh465407.aspx

    ... which led me to the Windows Push Notifications & Live Connect page:

    https://manage.dev.live.com/build?wa=wsignin1.0

    Then I used the client secret and SID values provided by the abovementioned page in my GetAccessToken() - code can be found above -, which exchanged these for an access token at https://login.live.com/accesstoken.srf

    In the tutorials I found,these steps were enough:(

    Thanks!

    Friday, May 11, 2012 6:22 AM
  • That is the correct way.  I have an old Post I put together for //build/  I will take time to update it it today for the current build and see if I run into any problems! http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx

    I will post back here when it is updated.


    Jeff Sanders (MSFT)

    Friday, May 11, 2012 12:31 PM
    Moderator
  • I updated the POST and validated it works with the Consumer Preview.  Check it out!

    http://blogs.msdn.com/b/jpsanders/archive/2011/12/02/walkthrough-creating-an-iis-server-to-use-with-wns-push-notifications-metro.aspx

    -Jeff


    Jeff Sanders (MSFT)

    Friday, May 11, 2012 6:40 PM
    Moderator
  • Hi Jeff,

    I have gone through your ABOVE given blog  and in fact  was following your procedure. But it returns 400 Bad Request when request for a access token.

    protected void getAccessToken() 
        { 
            var urlEncodedSid = HttpUtility.UrlEncode(String.Format("{0}", this.sid)); 
            var urlEncodedSecret = HttpUtility.UrlEncode(this.secret);

            var body =  String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);

            var client = new WebClient(); 
            client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

            string response = client.UploadString(login_server_url, body);  // Error occurs at this line (i.e. 400 Bad request)

            var oAuthToken = GetOAuthTokenFromJson(response); 
            this.accessToken = oAuthToken.AccessToken; 
        }

    Thanx in advanced :)
    Monday, March 25, 2013 5:48 AM
  • Hi Kasun!

    Check out this page:

    http://msdn.microsoft.com/en-us/library/windows/apps/hh465407.aspx

    You should be able to use a tool like fiddler to send the post manually and see what is going on (it discusses the format of the string).  I believe that you are probably not providing the correct client id and secret for your app.

    -Jeff


    Jeff Sanders (MSFT)

    • Proposed as answer by Kasun SW Friday, March 29, 2013 10:40 AM
    Monday, March 25, 2013 12:21 PM
    Moderator
  • Hi Jeff,

    I found the reason for the error response. In fact it is the wrong PACKAGE_SECURITY_IDENTIFIER and CLIENT_SECRET.

    DO NOT type the values. Because associated ASCII values differ. Therefore it is always better to copy and paste directly.

    You will probably will get the access token with the simple code snippet.

    Thanx :)

    • Proposed as answer by Kasun SW Friday, March 29, 2013 10:40 AM
    Friday, March 29, 2013 10:40 AM