Extending wab in a store app to talk to an asp.net “consent” site – that wraps the ACS grant management API.


image

image

image

image

 

We changed the facebook provider of the WAB sample so it all points to our authz and token endpoints (that wrap ACS):

 

//********************************************************* // // Copyright (c) Microsoft. All rights reserved. // //********************************************************* using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; using SDKTemplate; using System; using System.Linq; using System.Collections.Generic; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.Graphics.Display; using Windows.UI.ViewManagement; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.Security.Authentication.Web; using Windows.Security.Cryptography.Core; using Windows.Security.Cryptography; using Windows.Storage.Streams; using System.Text; using System.IO; using System.Threading.Tasks; using Windows.Data.Json; using Windows.Web.Http; using Windows.ApplicationModel.Activation; using Newtonsoft.Json.Linq; namespace WebAuthentication { /// <summary> /// An empty page that can be used on its own or navigated to within a Frame. /// </summary> #if WINDOWS_PHONE_APP public sealed partial class Scenario1 : Page, IWebAuthenticationContinuable #else public sealed partial class Scenario1 : Page #endif { // A pointer back to the main page. This is needed if you want to call methods in MainPage such // as NotifyUser() MainPage rootPage = MainPage.Current; public Scenario1() { this.InitializeComponent(); } /// <summary> /// Invoked when this page is about to be displayed in a Frame. /// </summary> /// <param name="e">Event data that describes how this page was reached. The Parameter /// property is typically used to configure the page.</param> protected override void OnNavigatedTo(NavigationEventArgs e) { } private void DebugPrint(String Trace) { FacebookDebugArea.Text += Trace + "\r\n"; } private void OutputToken(String TokenUri) { FacebookReturnedToken.Text = TokenUri; } #if WINDOWS_PHONE_APP private void Launch_Click(object sender, RoutedEventArgs e) #else private async void Launch_Click(object sender, RoutedEventArgs e) #endif { string Authority = "https://ssoportal.rapmlsqa.com/as/authorization.oauth2.aspx/BARI/32"; string Resource = "https://outlook.office365.com/"; // h?client_id=ac_client_sa&client_secret=ac_client_sa_password&response_type=code&scope=urn:smarteragent.com:scope:pullrets&state=BAREIS string authURL = string.Format( "{0}?response_type=code&resource={1}&client_id={2}&redirect_uri={3}&client_secret=ac_client_sa_password&scope=urn:smarteragent.com:scope:pullrets", Authority, Resource, Uri.EscapeDataString(FacebookClientID.Text), Uri.EscapeDataString(FacebookCallbackUrl.Text)); if (FacebookClientID.Text == "") { rootPage.NotifyUser("Please enter an Client ID.", NotifyType.StatusMessage); } else if (FacebookCallbackUrl.Text == "") { rootPage.NotifyUser("Please enter an Callback URL.", NotifyType.StatusMessage); } try { String RAPMLSQAURL = authURL; System.Uri StartUri = new Uri(RAPMLSQAURL); // When using the desktop flow, the success code is displayed in the html title of this end uri System.Uri EndUri = new Uri(FacebookCallbackUrl.Text); DebugPrint("Navigating to: " + RAPMLSQAURL); #if WINDOWS_PHONE_APP WebAuthenticationBroker.AuthenticateAndContinue(StartUri, EndUri, null, WebAuthenticationOptions.None); #else WebAuthenticationResult WebAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync( WebAuthenticationOptions.None, StartUri, EndUri); if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success) { OutputToken(WebAuthenticationResult.ResponseData.ToString()); await GetSSOPORTALUserNameAsync(WebAuthenticationResult.ResponseData.ToString()); } else if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.ErrorHttp) { OutputToken("HTTP Error returned by AuthenticateAsync() : " + WebAuthenticationResult.ResponseErrorDetail.ToString()); } else { OutputToken("Error returned by AuthenticateAsync() : " + WebAuthenticationResult.ResponseStatus.ToString()); } #endif } catch (Exception Error) { // // Bad Parameter, SSL/TLS Errors and Network Unavailable errors are to be handled here. // DebugPrint(Error.ToString()); } } #if WINDOWS_PHONE_APP public async void ContinueWebAuthentication(WebAuthenticationBrokerContinuationEventArgs args) { WebAuthenticationResult result = args.WebAuthenticationResult; if (result.ResponseStatus == WebAuthenticationStatus.Success) { OutputToken(result.ResponseData.ToString()); await GetFacebookUserNameAsync(result.ResponseData.ToString()); } else if (result.ResponseStatus == WebAuthenticationStatus.ErrorHttp) { OutputToken("HTTP Error returned by AuthenticateAsync() : " + result.ResponseErrorDetail.ToString()); } else { OutputToken("Error returned by AuthenticateAsync() : " + result.ResponseStatus.ToString()); } } #endif private string ParseCode(string result) { int codeIndex = result.IndexOf("code=", 0) + 5; int endCodeIndex = result.IndexOf("&", codeIndex); // Return the access code as a string return result.Substring(codeIndex, endCodeIndex - codeIndex); } /// <summary> /// This function extracts access_token from the response returned from web authentication broker /// and uses that token to get user information using facebook graph api. /// </summary> /// <param name="webAuthResultResponseData">responseData returned from AuthenticateAsync result.</param> private async Task GetSSOPORTALUserNameAsync(string webAuthResultResponseData) { string Authority = "https://ssoportal.rapmlsqa.com/as/token.oauth2.aspx/BARI/32"; // string Resource = "https://outlook.office365.com/"; string ClientID = "ac_client_sa"; string RedirectUri = "http://apptest.smarteragent.com/rest/OAuthCallback.jsp"; //Get Access Token first string responseData = webAuthResultResponseData.Substring(webAuthResultResponseData.IndexOf("code")); String[] keyValPairs = responseData.Split('&'); string access_token = null; string id_token = null; string code = null; for (int i = 0; i < keyValPairs.Length; i++) { String[] splits = keyValPairs[i].Split('='); switch (splits[0]) { case "code": code = splits[1]; { System.Net.Http.HttpClient client = new System.Net.Http.HttpClient(); System.Net.Http.HttpRequestMessage request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Post, string.Format("{0}", Authority)); string tokenreq = string.Format( "grant_type=authorization_code&code={0}&client_id={1}&client_secret=ac_client_sa_password&redirect_uri={2}&scope=urn:smarteragent.com:scope:pullrets", code, ClientID, Uri.EscapeDataString(RedirectUri)); request.Content = new System.Net.Http.StringContent(tokenreq, Encoding.UTF8, "application/x-www-form-urlencoded"); System.Net.Http.HttpResponseMessage response1 = await client.SendAsync(request); string responseString = await response1.Content.ReadAsStringAsync(); var jResult = JObject.Parse(responseString); access_token = (string)jResult["access_token"]; id_token = access_token; } break; } } DebugPrint("access_token = " + access_token); DebugPrint("id_token = " + id_token); id_token = id_token.Replace('-', '+'); // 62nd char of encoding id_token = id_token.Replace('_', '/'); // 63rd char of encoding String[] splitsperiod = id_token.Split('.'); id_token = splitsperiod[1]; switch (splitsperiod[1].Length % 4) // Pad with trailing '='s { case 0: break; // No pad chars in this case case 2: id_token += "=="; break; // Two pad chars case 3: id_token += "="; break; // One pad char default: throw new System.Exception( "Illegal base64url string!"); } byte[] id_token_clear = Convert.FromBase64String(id_token); // Standard base64 decoder var idt = Encoding.UTF8.GetString(id_token_clear, 0, id_token_clear.Length); var jResult2 = JObject.Parse(idt); var rapmlsqaUserName = (string)jResult2["nameid"]; rootPage.NotifyUser(rapmlsqaUserName + " is connected!!", NotifyType.StatusMessage); } /// <summary> /// This function extracts access_token from the response returned from web authentication broker /// and uses that token to get user information using facebook graph api. /// </summary> /// <param name="webAuthResultResponseData">responseData returned from AuthenticateAsync result.</param> private async Task GetFacebookUserNameAsync(string webAuthResultResponseData) { //Get Access Token first string responseData = webAuthResultResponseData.Substring(webAuthResultResponseData.IndexOf("access_token")); String[] keyValPairs = responseData.Split('&'); string access_token = null; string expires_in = null; for (int i = 0; i < keyValPairs.Length; i++) { String[] splits = keyValPairs[i].Split('='); switch (splits[0]) { case "access_token": access_token = splits[1]; //you may want to store access_token for further use. Look at Scenario5 (Account Management). break; case "expires_in": expires_in = splits[1]; break; } } DebugPrint("access_token = " + access_token); //Request User info. HttpClient httpClient = new HttpClient(); string response = await httpClient.GetStringAsync(new Uri("https://graph.facebook.com/me?access_token=" + access_token)); JsonObject value = JsonValue.Parse(response).GetObject(); string facebookUserName = value.GetNamedString("name"); rootPage.NotifyUser(facebookUserName + " is connected!!", NotifyType.StatusMessage); } } }

Advertisements

About home_pw@msn.com

Computer Programmer who often does network administration with focus on security servers. Very strong in Microsoft Azure cloud!
This entry was posted in AAD. Bookmark the permalink.