User authentication is an important part of application design and development. Authentication allows developers protect user privacy, store settings and access profile information such as a profile picture and other assorted details.
ArcGIS Online (or AGOL) is Esri’s cloud based solution for creating and sharing maps, apps and geographic services. AGOL supports OAuth2, an open standard for user authentication. This blog posting contains a code snippet that can help you connect to AGOL using OAuth2 authentication. Please keep in mind that this functionality will become a core capability of the next release of Esri’s ArcGIS Runtime SDK for Windows Store apps.
In this example, when the user clicks the blue start button (see screenshot above) the following dialog appears. If the user enters a valid username and password, the login dialog is dismissed and the app will navigate from the welcome page to the main application page.
Additional References:
public sealed partial class WelcomePage : LayoutAwarePage { private const string AGOL_OAUTH = "https://www.arcgis.com/sharing/oauth2/authorize"; private const string AGOL_APPID = "<your app id>"; private const string AGOL_REDIR = "http://maps.esri.com"; private const string AGOL_GETTK = "https://www.arcgis.com/sharing/oauth2/token"; // // CONSTRUCTOR // public WelcomePage() { this.InitializeComponent(); // Button events this.ButtonLogin.Click += async (s, e) => { this.ButtonLogin.IsEnabled = false; await this.LogPortal(); this.ButtonLogin.IsEnabled = true; }; } private async Task LogPortal() { // Construct AGOL login url string query = string.Empty; query += string.Format("client_id={0}", AGOL_APPID); query += string.Format("&response_type={0}", "code"); query += string.Format("&redirect_uri={0}", Uri.EscapeDataString(AGOL_REDIR)); // Build url UriBuilder b = new UriBuilder(WelcomePage.AGOL_OAUTH) { Query = query }; // Display 0Auth2 dialog WebAuthenticationResult w = await WebAuthenticationBroker.AuthenticateAsync( WebAuthenticationOptions.None, b.Uri, new Uri(AGOL_REDIR) ); switch (w.ResponseStatus) { case WebAuthenticationStatus.Success: // Response ok? if (w.ResponseData == null) { return; } // Parse return uri Uri call = null; if (!Uri.TryCreate(w.ResponseData, UriKind.RelativeOrAbsolute, out call)) { return; } // Extract code string[] parameters = call.Query.TrimStart('?').Split('&'); Dictionary<string, string> dict = new Dictionary<string, string>(); foreach (string parameter in parameters) { string[] parts = parameter.Split('='); if (parts.Length != 2) { continue; } dict.Add(parts[0], parts[1]); } var item = dict.FirstOrDefault(kvp => kvp.Key == "code"); string code = item.Value; if (string.IsNullOrWhiteSpace(code)) { return; } // Build token request query string query2 = string.Empty; query2 += string.Format("client_id={0}", AGOL_APPID); query2 += string.Format("&grant_type={0}", "authorization_code"); query2 += string.Format("&code={0}", code); query2 += string.Format("&redirect_uri={0}", Uri.EscapeDataString(AGOL_REDIR)); // Build token request url UriBuilder builder = new UriBuilder(WelcomePage.AGOL_GETTK) { Query = query2 }; // Get response HttpClient c = new HttpClient(); string text = await c.GetStringAsync(builder.Uri); if (string.IsNullOrWhiteSpace(text)) { return; } // Parse json - extract token JsonValue jv = null; if (!JsonValue.TryParse(text, out jv)) { return; } JsonObject jo = jv.GetObject(); string access = jo.GetNamedString("access_token"); double expire = jo.GetNamedNumber("expires_in"); string refresh = jo.GetNamedString("refresh_token"); string username = jo.GetNamedString("username"); // Instantiate portal ArcGISPortal portal = await ArcGISPortal.CreateAsync(null, null, access); // Store reference to portal QuizDataSource.Default.Portal = portal; // Navigate to main page this.Frame.Navigate(typeof(MainPage)); break; case WebAuthenticationStatus.ErrorHttp: string http_errorcode = w.ResponseErrorDetail.ToString(); this.GridWelcome.Visibility = Visibility.Visible; this.ErrorControl.Show(http_errorcode); break; case WebAuthenticationStatus.UserCancel: default: break; } } }