/// <summary> /// Check whether a refresh token exists. If yes, then add the credentials associated with the refresh token to the Identity Manager. If not, /// return to the app and wait for the user to click the Sign In button. /// </summary> private async void CheckUseRefreshToken() { try { string refreshToken = await LoadRefreshToken(); if (string.IsNullOrEmpty(refreshToken)) { return; } OAuthTokenCredential credential = new OAuthTokenCredential(); credential.OAuthRefreshToken = refreshToken; credential.ServiceUri = MyServerUrl; credential.GenerateTokenOptions = new GenerateTokenOptions { TokenAuthenticationType = TokenAuthenticationType.OAuthAuthorizationCode, }; await credential.RefreshTokenAsync(); IdentityManager.Current.AddCredential(credential); SignOutButton.IsEnabled = true; SignInButton.IsEnabled = false; LoadWebMapButton.IsEnabled = true; LoggedInUserName.Text = string.Format("Logged in as: {0}", credential.UserName); LoggedInUserName.Visibility = Visibility.Visible; } catch (Exception ex) { ShowDialog(ex.Message); } }
/// <summary> /// Gets the credentials /// </summary> /// <param name="info">Credentials info</param> /// <returns>Credential</returns> private async Task <Credential> CreateCredentialAsync(CredentialRequestInfo info) { // ChallengeHandler function for AuthenticationManager that will be called whenever access to a secured // resource is attempted OAuthTokenCredential credential = null; try { // Create generate token options if necessary if (info.GenerateTokenOptions == null) { info.GenerateTokenOptions = new GenerateTokenOptions(); } // Use encrypted refresh token if it exists if (string.IsNullOrEmpty(Settings.Default.OAuthRefreshToken)) { // AuthenticationManager will handle challenging the user for credentials credential = await Esri.ArcGISRuntime.Security.AuthenticationManager.Current.GenerateCredentialAsync( info.ServiceUri, info.GenerateTokenOptions) as OAuthTokenCredential; } else { var token = ProtectedData.Unprotect( Convert.FromBase64String(Settings.Default.OAuthRefreshToken), entropy, DataProtectionScope.CurrentUser); credential = new OAuthTokenCredential(); credential.ServiceUri = info.ServiceUri; credential.OAuthRefreshToken = System.Text.Encoding.Unicode.GetString(token); credential.GenerateTokenOptions = info.GenerateTokenOptions; await credential.RefreshTokenAsync(); } } catch (Exception ex) { // Exception will be reported in calling function throw ex; } // Encrypt and save refresh token if (!string.IsNullOrEmpty(credential.OAuthRefreshToken)) { var token = ProtectedData.Protect( System.Text.Encoding.Unicode.GetBytes(credential.OAuthRefreshToken), entropy, DataProtectionScope.CurrentUser); Settings.Default.OAuthRefreshToken = Convert.ToBase64String(token); Settings.Default.Save(); Settings.Default.Reload(); } return(credential); }
/// <summary> /// Methos to create a new credential given a refresh token exists /// </summary> private async Task <OAuthTokenCredential> CreateCredentialFromRefreshToken(CredentialRequestInfo info) { // set up credential using the refresh token try { var credential = new OAuthTokenCredential() { ServiceUri = info.ServiceUri, OAuthRefreshToken = GetToken(_oAuthRefreshToken), GenerateTokenOptions = info.GenerateTokenOptions }; await credential.RefreshTokenAsync(); return(credential); } catch { // if using the refresh token fails, clear the token BroadcastMessenger.Instance.RaiseBroadcastMessengerValueChanged(null, BroadcastMessageKey.OAuthRefreshToken); } return(null); }
/// <summary> /// Check whether a refresh token exists. If yes, then add the credentials associated with the refresh token to the Identity Manager. If not, /// return to the app and wait for the user to click the Sign In button. /// </summary> private async void CheckUseRefreshToken() { try { string refreshToken = await LoadRefreshToken(); if (string.IsNullOrEmpty(refreshToken)) return; OAuthTokenCredential credential = new OAuthTokenCredential(); credential.OAuthRefreshToken = refreshToken; credential.ServiceUri = MyServerUrl; credential.GenerateTokenOptions = new GenerateTokenOptions { TokenAuthenticationType = TokenAuthenticationType.OAuthAuthorizationCode, }; await credential.RefreshTokenAsync(); IdentityManager.Current.AddCredential(credential); SignOutButton.IsEnabled = true; SignInButton.IsEnabled = false; LoadWebMapButton.IsEnabled = true; LoggedInUserName.Text = string.Format("Logged in as: {0}", credential.UserName); LoggedInUserName.Visibility = Visibility.Visible; } catch (Exception ex) { ShowDialog(ex.Message); } }
/// <summary> /// ChallengeHandler function that will be called whenever access to a secured resource is attempted /// </summary> private async Task <Credential> CreateCredentialAsync(CredentialRequestInfo info) { // if credentials are already set, return set values foreach (var cred in Security.AuthenticationManager.Current.Credentials) { if (cred.ServiceUri == new Uri(_arcGISOnlineURL)) { return(cred); } } // Create generate token options if necessary if (info.GenerateTokenOptions == null) { info.GenerateTokenOptions = new GenerateTokenOptions(); } OAuthTokenCredential credential = null; // if no refresh token, call to generate credentials // otherwise if a refresh token exists, login user using the refresh token if (string.IsNullOrEmpty(_oAuthRefreshToken)) { // HACK: portal endpoints that do not contain "sharing/rest" generate ArcGISTokenCredential instead of OAuthTokenCredential // Forcing login into ArcGIS online if "sharing/rest" not in the service uri var serviceUri = info.ServiceUri.ToString().Contains("sharing/rest") ? info.ServiceUri : new Uri(_arcGISOnlineURL); // AuthenticationManager will handle challenging the user for credentials credential = await Security.AuthenticationManager.Current.GenerateCredentialAsync( serviceUri, info.GenerateTokenOptions) as OAuthTokenCredential; } else { // unprotect the refresh token var token = ProtectedData.Unprotect( Convert.FromBase64String(_oAuthRefreshToken), null, DataProtectionScope.CurrentUser); // set up credential using the refresh token credential = new OAuthTokenCredential() { ServiceUri = info.ServiceUri, OAuthRefreshToken = System.Text.Encoding.Unicode.GetString(token), GenerateTokenOptions = info.GenerateTokenOptions }; await credential.RefreshTokenAsync(); } // add credential to the authentication manager singleton instance to be used int he app Security.AuthenticationManager.Current.AddCredential(credential); try { // Create connection to Portal and provide credential var portal = await ArcGISPortal.CreateAsync(new Uri(_arcGISOnlineURL), credential); // set authenticated user local property AuthenticatedUser = portal.User; } catch (Exception ex) { UserPromptMessenger.Instance.RaiseMessageValueChanged( Resources.GetString("LoginUnsuccessful_Title"), ex.Message, true, ex.StackTrace); } // Save refresh token if it has changed. Encrypt if necessary if (credential.OAuthRefreshToken != _oAuthRefreshToken) { if (!string.IsNullOrEmpty(credential.OAuthRefreshToken)) { var token = ProtectedData.Protect( System.Text.Encoding.Unicode.GetBytes(credential.OAuthRefreshToken), null, DataProtectionScope.CurrentUser); BroadcastMessenger.Instance.RaiseBroadcastMessengerValueChanged(Convert.ToBase64String(token), BroadcastMessageKey.OAuthRefreshToken); } else { BroadcastMessenger.Instance.RaiseBroadcastMessengerValueChanged(null, BroadcastMessageKey.OAuthRefreshToken); } } return(credential); }