WebAuthenticationBroker

How to connect your Windows Phone 8 & 8.1 app to Yammer

In my recent project UniShare I also added Yammer, because some of users asked for it and we use it also at Telefónica.

This post is all about how to connect you Yammer. First, we need to prepare our app. Five steps are needed for preparation.

First, we need an uri scheme to launch our app. To add an uri scheme, right click on the WMAppManifest.xml and click on ‘Open With…’ and select ‘XML (Text) Editor with Encoding’. After the ‘Tokens’ section, add your custom uri scheme within the ‘Extensions’ tag, for example:

      <Protocol Name="yourapp-yammercallback" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />

Next step is to add a proper UriMapper:

public class UriMapper : UriMapperBase
{
    public override Uri MapUri(Uri uri)
    {
        if (uri.ToString().Contains("yourapp-yammercallback"))
        {
            string decodedUri = HttpUtility.UrlDecode(uri.ToString());

            int redirectUriIndex = decodedUri.IndexOf("yourapp-yammercallback");
            string redirectParams = new Uri(decodedUri.Substring(redirectUriIndex)).Query;
            // Map the OAuth response to the app page
            return new Uri("/MainPage.xaml" + redirectParams, UriKind.Relative);
        }

        else return uri;
    }
}

If you want to learn more about uri schemes, you can read my blog post here.

The third step is to generate your app on Yammer to get your Tokens. Open https://www.yammer.com/client_applications, click on ‘Register New App’ and fill in the form:

Screenshot (354)

After clicking on continue, click on ‘Basic Info’ and add your uri scheme in the field ‘Redirect Uri’ and click on ‘Save’.

Screenshot (356)

The fourth step starts with downloading the Yammer oAuth SDK for Windows Phone from Github. Open the solution and built all projects. After that, you can close the solution. Go back into your project, and right click on ‘References’, followed by ‘Add Reference’. Browse to the folder ‘\WPYammer-oauth-sdk-demo-master\windows-phone-oauth-sdk-demo-master\Yammer.OAuthSDK\Bin\Release’ and add the file with the name ‘Yammer.OAuthSDK.dll’.

The last step is to add your keys and the redirect uri in your app’s resource dictionary:

<model:OAuthClientInfo xmlns:model="clr-namespace:Yammer.OAuthSDK.Model;assembly=Yammer.OAuthSDK" x:Key="MyOAuthClientInfo"
    ClientId="your client id" 
    ClientSecret="your client secret" 
    RedirectUri="yourapp-yammercallback" />

Now that our app is prepared, we can finally launch the oAuth process. First, we need to read our values from our app’s resource dictionary. Add this to the constructor to do so:

YammerClientId = App.MyOAuthClientInfo.ClientId;
YammerClientSecret = App.MyOAuthClientInfo.ClientSecret;
YammerCallbackUri = App.MyOAuthClientInfo.RedirectUri;

To kick the user out to the oAuth process, which happens in the phone’s browser, just add these two lines to your starting event (for example a button click event).

OAuthUtils.LaunchSignIn(YammerClientId, YammerCallbackUri);
App.Current.Terminate();

You might notice the app gets terminated. We have to do this because only this way, the uri scheme we added earlier can do its work. If the app is not terminated, the values cannot be passed into our app. Technically, it would also be possible to use the WebAuthenticationBroker on 8.1 for this. Sadly, the Yammer authorization pages do not work well with the WAB. The best way to use it with this library, is to kick the user to the browser.

Once we are receiving the values of the authentication, we can continue the authentication process to get the final access token. Add this code to your OnNavigatedTo event:

ShowProgressIndicator("connecting to Yammer...");

if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Code) && NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.State) && e.NavigationMode != NavigationMode.Back)
{
    OAuthUtils.HandleApprove(
        YammerClientId,
        YammerClientSecret,
        NavigationContext.QueryString[Constants.OAuthParameters.Code],
        NavigationContext.QueryString[Constants.OAuthParameters.State],
        onSuccess: () =>
        {
            GetYammerCurrentUserData();
        }, onCSRF: () =>
        {
            MessageBox.Show("Please contact us via the 'help & support' page.", "Invalid redirect", MessageBoxButton.OK);
        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK));
            HideProgressIndicator();
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() => MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK));
            HideProgressIndicator();
        }
    );
}
// "Deny"
else if (NavigationContext.QueryString.ContainsKey(Constants.OAuthParameters.Error) && e.NavigationMode != NavigationMode.Back)
{
    string error, errorDescription;
    error = NavigationContext.QueryString[Constants.OAuthParameters.Error];
    NavigationContext.QueryString.TryGetValue(Constants.OAuthParameters.ErrorDescription, out errorDescription);

    string msg = string.Format("error: {0}\nerror_description:{1}", error, errorDescription);
    MessageBox.Show(msg, "Error", MessageBoxButton.OK);

    if (NavigationContext.QueryString != null)
    {
        string[] NavigationKeys = NavigationContext.QueryString.Keys.ToArray();
        ClearNavigationContext(NavigationKeys);
    }

    OAuthUtils.DeleteStoredToken();

}

With this, you are handling all errors and events properly. If the call ends successfully, we are finally able to get our user’s data:

public void GetYammerCurrentUserData()
{
    ShowProgressIndicator("connecting to Yammer...");

    var baseUrl = new Uri("https://www.yammer.com/api/v1/users/current.json", UriKind.Absolute);

    OAuthUtils.GetJsonFromApi(baseUrl,
        onSuccess: response =>
        {
            //do something with the result (json string)

            HideProgressIndicator();

        }, onErrorResponse: errorResponse =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(errorResponse.OAuthError.ToString(), "Invalid operation", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }, onException: ex =>
        {
            Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(ex.ToString(), "Unexpected error", MessageBoxButton.OK);
                HideProgressIndicator();

            });
        }
    );
}

As you can see above, the result is a json string that contains the current user’s data. You can either create a class/model to deserialize the values or use anonymous deserialization methods.

One important point: you cannot publish your app outside your home network until it got approved as a global app by Yammer. I am waiting for nearly two weeks now for UniShare to get approved and hope it will become available for all soon.

As always, I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, windev, 1 comment

How to use the WebAuthenticationBroker in a Windows Phone 8.1 Silverlight app

oAuthDance

I already wrote how to use the WebAuthenticationBroker (WAB) in a Windows Phone Runtime app. With the need for me to switch back to Silverlight for UniShare, I needed to perform some rewriting of the WAB code.

The WAB needs some other code to work properly in a Silverlight project, and this post will got through all steps that are needed for this. I will reference to the above blog post where the methods itself are the same. I am just highlighting the changes that are needed in an 8.1 Silverlight project.

Preparing our App

First, we need to set up the proper continuation event in App.xaml.cs. We are doing this by adding this line of code in the App class:

public WebAuthenticationBrokerContinuationEventArgs WABContinuationArgs { get; set; }

This event is used when we are coming back to our app after the WAB logged the user in. The next step we need to do, is to tell our app that we have performed an authentication, and pass the values back to our main code. Unlike in the Runtime project, we are using the Application_ContractActivated event for this:

        private void Application_ContractActivated(object sender, Windows.ApplicationModel.Activation.IActivatedEventArgs e)
        {
            var _WABContinuationArgs = e as WebAuthenticationBrokerContinuationEventArgs;
            if (_WABContinuationArgs != null)
            {
                this.WABContinuationArgs = _WABContinuationArgs;
            }
        }

If you are upgrading from a WP8 project, you might have to add this event manually. Our app is now prepared to get results from the WAB.

Preparing oAuth

I am going to show you the oAuth process of Twitter to demonstrate the usage of the WAB. First, we need again the GetNonce(), GetTimeStamp () and GetSignature(string sigBaseString, string consumerSecretKey, stringoAuthTokenSecret=null) methods from my former blog post.

Performing the oAuth process

In the oAuth authentication flow, we need to obtain a so called Request Token, which allows our app to communicate with the API (in this case Twitter’s API).

Add the following code to your “connect to Twitter”- Button event:

                        string oAuth_Token = await GetTwitterRequestTokenAsync(TwitterCallBackUri, TwitterConsumerKey);
                        string TwitterUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oAuth_Token;

                        WebAuthenticationBroker.AuthenticateAndContinue(new Uri(TwitterUrl), new Uri(TwitterCallBackUri));

Like in a Runtime app, we are getting the request token first (code is also in my former blog post), once we obtained the request token, we are able to get the oAuth token that enables us to get the final user access tokens.

Once the user has authenticated our app, we’ll receive the above mentioned oAuth tokens. To use them, add the following code to your OnNavigatedTo event:

                var appObject = Application.Current as App;

                if (appObject.WABContinuationArgs != null)
                {
                    WebAuthenticationResult result = appObject.WABContinuationArgs.WebAuthenticationResult;

                    if (result.ResponseStatus == WebAuthenticationStatus.Success)
                    {
                        await GetTwitterUserNameAsync(result.ResponseData.ToString());
                    }
                    else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
                    {
                        MessageBox.Show(string.Format("There was an error connecting to Twitter: \n {0}", result.ResponseErrorDetail.ToString()), "Sorry", MessageBoxButton.OK);

                    }
                    else
                    {
                        MessageBox.Show(string.Format("Error returned: \n{0}", result.ResponseStatus.ToString()), "Sorry", MessageBoxButton.OK);
                        HideProgressIndicator();
                    }
                }

The WebAuthenticationResult now holds all values that we need to perform the final actions. To complete the oAuth process on Twitter, you can use the GetTwitterUserNameAsync(string webAuthResultResponseData) method from my former blog post. If you are not using other methods to control the result of the WAB, don’t forget to set appObject.WABContinuationArgs to null after you finished obtaining all tokens and data from Twitter (or other services).

As you can see, there are some structural differences in using the WAB when creating a Silverlight app, but we are also able to use a lot of code from my Runtime project. I hope this post is helpful for some of you to get the oAuth dance going.

In my next post, I will show you how to authenticate your app with Yammer (Microsoft’s enterprise social network).

Until then, happy coding!

Posted by msicc in Dev Stories, windev, 3 comments

How to use the WebAuthenticationBroker for oAuth in a Windows Phone Runtime WP8.1 app

oAuthDance

After playing around with WP8.1 for a few days (like everyone else), I decided to dig a bit into development of WP8.1.

As oAuth is the common authentication method nowadays for Apps and Websites, I was curios about the implementation of the WebAuthenticationBroker in a WINPRT app.

I used it before with Windows 8 for my TweeCoMinder app, but that’s a few month back (it didn’t make it into the Store yet (another goal, right – porting TweeCoMinder to Universal will be a lot of fun and learning for me ;-)).

Before we continue: This is a pretty huge topic. Be prepared that it may take you more than one time to read and understand what is going on.

Let’s dive into it. Unlike the Windows WebAuthenticationBroker, the Phone version does not use the AuthenticateAsync method. It uses AuthenticateAndContinue instead. This is related to the lifecycle on phone, as it is more likely that an WINPRT app is suspended than on Windows (at least that’s the official reason).

Preparing our App

But we are able to get it working, no worries. First, we need the so called ContinuationManager. This class brings the user back to the app where the fun begun.

You can download the complete class from here (it is a 1:1 copy from the official MSDN reference). The only thing you need to do is to add your app’s Namespace into it.

The next step we need to do: some modifications at the App.xaml.cs file.

1. Add an OnActivated event (it isn’t there in the Phone template) [updated: added missing continuationManager initialization]

        protected async override void OnActivated(IActivatedEventArgs e)
        {

            continuationManager = new ContinuationManager();

            CreateRootFrame();

            // Restore the saved session state only when appropriate
            if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                try
                {
                    await SuspensionManager.RestoreAsync();
                }
                catch (SuspensionManagerException)
                {
                    //Something went wrong restoring state.
                    //Assume there is no state and continue
                }
            }

            //Check if this is a continuation
            var continuationEventArgs = e as IContinuationActivatedEventArgs;
            if (continuationEventArgs != null)
            {
                continuationManager.Continue(continuationEventArgs);
            }

            Window.Current.Activate();
        }

First, we check the SuspensionManager and let him restore a saved state – if there is one. If you do not have a Folder  ”Common” with the SuspensionManager, just add a new Basic page. This will generate the Common folder with the SuspenstionManager class for you.

After that, we are checking if the activation is a Continuation. We need this check there, otherwise the app will not be able to receive the Tokens after returning from the WebAuthenticationBroker. Note: declare the ContinuationManager globally in App.xaml.cs with this to avoid multiple instances (which will crash the app for sure).

public static ContinuationManager continuationManager { get; private set; }

2. Add a CreateRootFrame() method with some little changes to the default behavior

        private void CreateRootFrame()
        {
            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame != null)
                return;

            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();

            //Associate the frame with a SuspensionManager key                                
            SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

            // Set the default language
            rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];

            rootFrame.NavigationFailed += OnNavigationFailed;

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;
        }

This simply creates the RootFrame for our app. Place this one in the OnLaunched and OnActivated events. Instead of creating the RootFrame in the OnLaunched method, declare it globally in App.xaml.cs with this:

public static Frame rootFrame { get; set; }

3. Handle the HardwareButtons_BackPressed event

        private void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
        {
            Frame frame = Window.Current.Content as Frame;
            if (frame == null)
            {
                return;
            }

            if (frame.CanGoBack)
            {
                frame.GoBack();
                e.Handled = true;
            }
        }

This just handles the BackButton press globally (you can still handle it on individual pages/frames/controls).

4. Handle Navigation Errors in the OnNavigationFailed event

private void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{

    //change this code for your needs
    throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}

5. Add the Save method to the OnSuspending event

await SuspensionManager.SaveAsync();

This is just to save the current state of our app while the App gets suspended.

Preparing oAuth

Now, we have our app prepared  to be continued after the WebAuthenticationBroker has finished. Pretty much to do so far, but now we are going to start with the real fun: The oAuth process. We are going to use Twitter in this case, as it is very popular to be added as a sharing option in apps (yes, I recently saw a lot of them).

Before we are able to connect to Twitter, we need some preparing methods. The first one is to get a random character chain. Twitter demands a 32 digit chain that contains random alphanumeric values, the so called oAuth-nonce. A lot of samples use a chain that is shorter, which will be fine for the initial authentication, but not for additional request. Here is my method:

string GetNonce()
{
   StringBuilder builder = new StringBuilder();
   Random random = new Random();
   char ch;
   for (int i = 0; i < 32; i++)
   {
     ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
     builder.Append(ch);
   }

   return builder.ToString().ToLower();
 }

We also need a timestamp in Milliseconds, this one is pretty straight forward:

string GetTimeStamp()
{
  TimeSpan SinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
  return Math.Round(SinceEpoch.TotalSeconds).ToString();
}

On top, we need a signature for our Authentication request:

        string GetSignature(string sigBaseString, string consumerSecretKey, string oAuthTokenSecret=null)
        {
            IBuffer KeyMaterial = CryptographicBuffer.ConvertStringToBinary(consumerSecretKey + "&" + oAuthTokenSecret, BinaryStringEncoding.Utf8);
            MacAlgorithmProvider HmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
            CryptographicKey MacKey = HmacSha1Provider.CreateKey(KeyMaterial);
            IBuffer DataToBeSigned = CryptographicBuffer.ConvertStringToBinary(sigBaseString, BinaryStringEncoding.Utf8);
            IBuffer SignatureBuffer = CryptographicEngine.Sign(MacKey, DataToBeSigned);
            string Signature = CryptographicBuffer.EncodeToBase64String(SignatureBuffer);

            return Signature;
        }

You will find a lot of samples that don’t use the oAuthTokenSecret in the basic method. We will need this for additional requests, so I am using a nullable string overload. This way,  I need only one method after all.

Performing the Authentication process

To start the Authentication process, we are using this code in our Button_Click event:

        private async void connectToTwitterButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string oAuth_Token = await GetTwitterRequestTokenAsync(TwitterCallBackUri, TwitterConsumerKey);
                string TwitterUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oAuth_Token;

                WebAuthenticationBroker.AuthenticateAndContinue(new Uri(TwitterUrl), new Uri(TwitterCallBackUri), null, WebAuthenticationOptions.None);
            }
            catch
            { 
                //error handling here
            }
        }

First, we need a RequestToken that authenticates our request for the oAuthToken, that’s why we are awaiting the GetTwitterRequestTokenAsync(TwitterCallBackUri, TwitterConsumerKey) Task. The Task itself is this one:

        private async Task<string> GetTwitterRequestTokenAsync(string twitterCallbackUrl, string consumerKey)
        {
            //
            // Acquiring a request token
            //
            string TwitterUrl = "https://api.twitter.com/oauth/request_token";

            string nonce = GetNonce();
            string timeStamp = GetTimeStamp();
            string SigBaseStringParams = "oauth_callback=" + Uri.EscapeDataString(twitterCallbackUrl);
            SigBaseStringParams += "&" + "oauth_consumer_key=" + consumerKey;
            SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
            SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
            SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
            SigBaseStringParams += "&" + "oauth_version=1.0";
            string SigBaseString = "GET&";
            SigBaseString += Uri.EscapeDataString(TwitterUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);
            string Signature = GetSignature(SigBaseString, TwitterConsumerSecret);

            TwitterUrl += "?" + SigBaseStringParams + "&oauth_signature=" + Uri.EscapeDataString(Signature);
            HttpClient httpClient = new HttpClient();
            string GetResponse = await httpClient.GetStringAsync(new Uri(TwitterUrl));

            string request_token = null;
            string oauth_token_secret = null;
            string[] keyValPairs = GetResponse.Split('&');

            for (int i = 0; i < keyValPairs.Length; i++)
            {
                string[] splits = keyValPairs[i].Split('=');
                switch (splits[0])
                {
                    case "oauth_token":
                        request_token = splits[1];
                        break;
                    case "oauth_token_secret":
                        oauth_token_secret = splits[1];
                        break;
                }
            }

            return request_token;
        }

After receiving the RequestToken, we are able to call the the AuthenticateAndContinue(Uri, Uri, ValueSet, WebAuthenticationOptions) method. The WebAuthenticationBroker opens and the user needs to login. After finishing, the user will get redirected back into our app.

If you think that’s all of our code, I need to disappoint you. The fun goes on. We prepared our app to be recognized as continued app. To effectifely continue our app, we need to use the ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args) event from our ContinuationManager class:

 

        public async void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args)
        {
            WebAuthenticationResult result = args.WebAuthenticationResult;

            if (result.ResponseStatus == WebAuthenticationStatus.Success)
            {
                await GetTwitterUserNameAsync(result.ResponseData.ToString());
            }
            else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp)
            {
                MessageDialog HttpErrMsg = new MessageDialog(string.Format("There was an error connecting to Twitter: \n {0}", result.ResponseErrorDetail.ToString()), "Sorry");
                await HttpErrMsg.ShowAsync();
            }
            else
            {
                MessageDialog ErrMsg = new MessageDialog(string.Format("Error returned: \n{0}", result.ResponseStatus.ToString()), "Sorry");
                await ErrMsg.ShowAsync();
            }
        }

The WebAuthenticationResult holds our accessToken and accessTokenSecret, that we are going to exchange for our final oAuthToken and oAuthTokenSecret (we need them for all further requests).

If all goes well, we are now able to call the final Authentication Task GetTwitterUserNameAsync(string webAuthResultResponseData):

        private async Task GetTwitterUserNameAsync(string webAuthResultResponseData)
        {

            string responseData = webAuthResultResponseData.Substring(webAuthResultResponseData.IndexOf("oauth_token"));
            string request_token = null;
            string oauth_verifier = null;
            String[] keyValPairs = responseData.Split('&');

            for (int i = 0; i < keyValPairs.Length; i++)
            {
                String[] splits = keyValPairs[i].Split('=');
                switch (splits[0])
                {
                    case "oauth_token":
                        request_token = splits[1];
                        break;
                    case "oauth_verifier":
                        oauth_verifier = splits[1];
                        break;
                }
            }

            String TwitterUrl = "https://api.twitter.com/oauth/access_token";

            string timeStamp = GetTimeStamp();
            string nonce = GetNonce();

            String SigBaseStringParams = "oauth_consumer_key=" + TwitterConsumerKey;
            SigBaseStringParams += "&" + "oauth_nonce=" + nonce;
            SigBaseStringParams += "&" + "oauth_signature_method=HMAC-SHA1";
            SigBaseStringParams += "&" + "oauth_timestamp=" + timeStamp;
            SigBaseStringParams += "&" + "oauth_token=" + request_token;
            SigBaseStringParams += "&" + "oauth_version=1.0";
            String SigBaseString = "POST&";
            SigBaseString += Uri.EscapeDataString(TwitterUrl) + "&" + Uri.EscapeDataString(SigBaseStringParams);

            String Signature = GetSignature(SigBaseString, TwitterConsumerSecret);

            HttpStringContent httpContent = new HttpStringContent("oauth_verifier=" + oauth_verifier, Windows.Storage.Streams.UnicodeEncoding.Utf8);
            httpContent.Headers.ContentType = HttpMediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
            string authorizationHeaderParams = "oauth_consumer_key=\"" + TwitterConsumerKey + "\", oauth_nonce=\"" + nonce + "\", oauth_signature_method=\"HMAC-SHA1\", oauth_signature=\"" + Uri.EscapeDataString(Signature) + "\", oauth_timestamp=\"" + timeStamp + "\", oauth_token=\"" + Uri.EscapeDataString(request_token) + "\", oauth_version=\"1.0\"";

            HttpClient httpClient = new HttpClient();

            httpClient.DefaultRequestHeaders.Authorization = new HttpCredentialsHeaderValue("OAuth", authorizationHeaderParams);
            var httpResponseMessage = await httpClient.PostAsync(new Uri(TwitterUrl), httpContent);
            string response = await httpResponseMessage.Content.ReadAsStringAsync();

            String[] Tokens = response.Split('&');
            string oauth_token_secret = null;
            string oauth_token = null;
            string screen_name = null;

            for (int i = 0; i < Tokens.Length; i++)
            {
                String[] splits = Tokens[i].Split('=');
                switch (splits[0])
                {
                    case "screen_name":
                        screen_name = splits[1];
                        break;
                    case "oauth_token":
                        oauth_token = splits[1];
                        break;
                    case "oauth_token_secret":
                        oauth_token_secret = splits[1];
                        break;
                }
            }

            if (oauth_token != null)
            {
                App.SettingsStore.TwitteroAuthToken = oauth_token;
            }

            if (oauth_token_secret != null)
            {
                App.SettingsStore.TwitteroAuthTokenSecret = oauth_token_secret;
            }
            if (screen_name != null)
            {
                App.SettingsStore.TwitterName = screen_name;
            }
        }

At the end of this Task, we will have all Tokens and the ScreenName of our user and can save them for further usage.

The whole oAuth process is a pretty huge thing as you can see. I hope this blog post helps you all to understand how to use the WebAuthenticationBroker and get the required Tokens for all further requests.

Here are some useful links to the MSDN, if you want to dive deeper:

As always, this covers my experience. If anyone has tips or tricks to make this all easier (except of using already existing libraries), feel free to add a comment below.

Until the next post,  happy coding!

Posted by msicc in Dev Stories, windev, 27 comments