// Updates the display name based on the state of the credentials being monitored by the control private void updateUserDisplayName() { if (PortalUser != null && !string.IsNullOrEmpty(PortalUser.FullName)) { // If there is a portal/AGOL user, its name takes precedence because it is typically // the most user-friendly UserDisplayName = PortalUser.FullName; } else if (Credentials != null && Credentials.Count > 0) { // If there are any credentials, use the username from the first one that has a token IdentityManager.Credential cred = null; Func <IdentityManager.Credential, bool> condition = c => !string.IsNullOrEmpty(c.Token); if (Credentials.Any(condition)) { cred = Credentials.First(condition); } UserDisplayName = cred != null ? cred.UserName : null; } else { // No users, so set the label to prompt users to sign in UserDisplayName = Strings.SignIn; } }
// Test Windows Authentication private static bool ChallengeIWA(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback) { if (credentialRequestInfos.AuthenticationType == IdentityManager.AuthenticationType.NetworkCredential && credentialRequestInfos.ResponseHeaders != null && CredentialCache.DefaultCredentials != null) { // test that we didn't already try the IWA authentication if (TryDone(credentialRequestInfos.Url)) { return(false); } // get the WWW-Authenticate header string header = credentialRequestInfos.ResponseHeaders.Get("WWW-Authenticate"); // if the header contains NTLM the server is using Integrated Windows // Authentication (IWA), so try the current user's credentials if (!string.IsNullOrEmpty(header) && header.Contains("NTLM")) // IWA { var credential = new IdentityManager.Credential { Url = credentialRequestInfos.Url, Credentials = CredentialCache.DefaultCredentials }; AddTry(credentialRequestInfos.Url); callback(credential, null); return(true); } } return(false); }
private void TokenGenerated(IdentityManager.Credential credential, Exception exc, long requestID) { if (requestID != _requestID) { return; // No more the current request } IsBusy = false; string error = null; if (exc != null) { error = exc.Message; if (string.IsNullOrEmpty(error) && exc.InnerException != null) { error = exc.InnerException.Message; } } ErrorMessage = error; if (exc == null) // else the user can try again { _callbackHasBeenCalled = true; // Avoid that IsActive = false calls the callback with Cancel exception IsActive = false; if (Callback != null) { Callback(credential, exc); } } }
/// <summary> /// Fires the <see cref="SignedIn"/> event /// </summary> protected virtual void OnSignedIn(IdentityManager.Credential cred) { if (SignedIn != null) { SignedIn(this, new SignedInEventArgs(cred)); } }
private void initBrowserAuthenticatedUser(string portalUrl, string userName) { if (!CredentialManagement.Current.Credentials.Any(c => c.Url != null && c.Url.Equals(portalUrl, StringComparison.OrdinalIgnoreCase) && c.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase))) { IdentityManager.Credential cred = new IdentityManager.Credential() { Url = portalUrl, UserName = userName }; CredentialManagement.Current.Credentials.Add(cred); } m_ignoreSignInOut = true; User.InitializeTaskAsync(userName, null).ContinueWith(t => { m_ignoreSignInOut = false; if (t.IsFaulted) { var exception = t.Exception; } else { // Do nothing } }); }
private static IdentityManager.Credential FromDictionary(IDictionary <string, string> dictionary) { var credential = new IdentityManager.Credential(); if (dictionary.ContainsKey("access_token")) { // Token returned --> no error credential.Token = dictionary["access_token"]; } if (dictionary.ContainsKey("expires_in")) { long expiresIn; Int64.TryParse(dictionary["expires_in"], out expiresIn); credential.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expiresIn); } if (dictionary.ContainsKey("refresh_token")) { credential.OAuthRefreshToken = dictionary["refresh_token"]; } if (dictionary.ContainsKey("username")) { credential.UserName = dictionary["username"]; } return(credential); }
private void FeatureLayer_Initialized(object sender, EventArgs e) { FeatureLayer fl = sender as FeatureLayer; IdentityManager.Credential credential = IdentityManager.Current.FindCredential(fl.Url); if (credential != null || fl.InitializationFailure != null) { LoginGrid.Visibility = System.Windows.Visibility.Collapsed; ShadowGrid.Visibility = System.Windows.Visibility.Collapsed; LoggedInGrid.Visibility = System.Windows.Visibility.Visible; #region populate the FeatureTypeListBox with the possible templates FeatureTypeListBox.Items.Clear(); IDictionary <object, FeatureType> featureTypes = fl.LayerInfo.FeatureTypes; if (fl.Renderer != null) { Symbol defaultSymbol = fl.Renderer.GetSymbol(null); if (featureTypes != null && featureTypes.Count > 0) { foreach (KeyValuePair <object, FeatureType> featureTypePairs in featureTypes) { if (featureTypePairs.Value != null && featureTypePairs.Value.Templates != null && featureTypePairs.Value.Templates.Count > 0) { foreach (KeyValuePair <string, FeatureTemplate> featureTemplate in featureTypePairs.Value.Templates) { string name = featureTypePairs.Value.Name; if (featureTypePairs.Value.Templates.Count > 1) { name = string.Format("{0}-{1}", featureTypePairs.Value.Name, featureTemplate.Value.Name); } Symbol symbol = featureTemplate.Value.GetSymbol(fl.Renderer) ?? defaultSymbol; FeatureTypeListBox.Items.Add(new TemplateItem(name, symbol, Convert.ToInt32(featureTypePairs.Value.Id))); } } } } } #endregion if (credential != null) { LoggedInUserTextBlock.Text = credential.UserName; fl.EditUserName = credential.UserName; } //enable the app bar and context menu items for (int i = 0; i < ApplicationBar.Buttons.Count; ++i) { (ApplicationBar.Buttons[i] as IApplicationBarIconButton).IsEnabled = true; } } }
private void GenerateNetworkCredential() { if (IsReady) { var credential = new IdentityManager.Credential { Credentials = new NetworkCredential(UserName, Password) }; Debug.Assert(Tcs != null); // due to test on IsReady Tcs.TrySetResult(credential); Tcs = null; ErrorMessage = null; } }
private static void ChallengeCertificate(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback) { var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); X509Certificate2Collection certificates; try { const string clientAuthOid = "1.3.6.1.5.5.7.3.2"; // Client Authentication OID store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); // Find Client Authentication certificate certificates = store.Certificates.Find(X509FindType.FindByApplicationPolicy, clientAuthOid, true); // todo true); } catch (Exception) { certificates = null; } finally { store.Close(); } if (certificates != null && certificates.Count >= 1) { // Let the user select/validate the certificate string url = credentialRequestInfos.Url; string resourceName = GetResourceName(url); IdentityManager.ServerInfo serverInfo = IdentityManager.Current.FindServerInfo(url); string server = serverInfo == null?Regex.Match(url, "http.?//[^/]*").ToString() : serverInfo.ServerUrl; string message = string.Format(Properties.Resources.SignInDialog_CertificateRequired, resourceName, server); // certicate required to access {0} on {1} certificates = X509Certificate2UI.SelectFromCollection(certificates, null, message, X509SelectionFlag.SingleSelection); } IdentityManager.Credential credential = null; Exception error = null; if (certificates != null && certificates.Count > 0) { credential = new IdentityManager.Credential { ClientCertificate = certificates[0] }; } else { // Note : Error type is not that important since the error returned to the user is the initial HTTP error (Authorization Error) error = new System.Security.Authentication.AuthenticationException(); } callback(credential, error); }
/// <summary> /// Signs into the application environment's current ArcGIS Online/Portal instance using the /// specified credential /// </summary> public static async Task SignInToPortal(IdentityManager.Credential cred, ESRI.ArcGIS.Mapping.Controls.ArcGISOnline.ArcGISOnline agol = null) { ESRI.ArcGIS.Mapping.Controls.ArcGISOnline.ArcGISOnline portal = agol ?? ArcGISOnlineEnvironment.ArcGISOnline; if (portal.User.Current != null && !string.IsNullOrEmpty(portal.User.Current.FullName)) { return; // User is already signed in } await portal.User.InitializeTaskAsync(cred.UserName, cred.Token); if (MapApplication.Current != null && MapApplication.Current.Portal != null) { MapApplication.Current.Portal.Token = cred.Token; await MapApplication.Current.Portal.InitializeTaskAsync(); } }
private void GenerateNetworkCredential() { if (!IsReady) { return; } _callbackHasBeenCalled = true; // Avoid that IsActive = false calls the callback with Cancel exception IsActive = false; var credential = new IdentityManager.Credential { Credentials = new NetworkCredential(UserName, Password) }; if (Callback != null) { Callback(credential, null); } }
private async void GenerateToken() { if (!IsReady) { return; } IsBusy = true; ErrorMessage = null; long requestID = ++_requestID; Exception error = null; IdentityManager.Credential credential = null; try { credential = await IdentityManager.Current.GenerateCredentialAsync(_credentialRequestInfo.ServiceUri, UserName, Password, _credentialRequestInfo.GenerateTokenOptions); } catch (Exception e) { error = e; } if (requestID != _requestID || Tcs == null) { return; // No more the current request } IsBusy = false; if (error == null) { Tcs.TrySetResult(credential); Tcs = null; } else { // Display the error message and let the user try again string message = error.Message; if (string.IsNullOrEmpty(message) && error.InnerException != null) { message = error.InnerException.Message; } ErrorMessage = message; } }
/// <summary> /// Static challenge method leaveraging the SignInDialog in a child window. /// </summary> public static Task <IdentityManager.Credential> DoSignIn(IdentityManager.CredentialRequestInfo credentialRequestInfo) { Dispatcher d = Application.Current == null ? null : Application.Current.Dispatcher; Task <IdentityManager.Credential> doSignInTask; if (d != null && !d.CheckAccess()) { //Ensure we are showing up the SignInDialog on the UI thread var tcs = new TaskCompletionSource <IdentityManager.Credential>(); d.BeginInvoke((Action)(async() => { try { IdentityManager.Credential crd = await DoSignInInUIThread(credentialRequestInfo); tcs.TrySetResult(crd); } catch (Exception error) { tcs.TrySetException(error); } })); doSignInTask = tcs.Task; } else { doSignInTask = DoSignInInUIThread(credentialRequestInfo); } return(doSignInTask.ContinueWith(t => { // Flatten the exceptions if (t.Exception != null) { throw t.Exception.Flatten().InnerException; } return t.Result; })); }
/// <summary> /// Initiates sign-in based on the username and token stored in user settings. /// </summary> public void SignInFromLocalStorage(EventHandler<RequestEventArgs> callback) { string username = null; string token = null; // see if the browser cookie is present // string cookie = WebUtil.GetCookie("esri_auth"); if (cookie != null) { cookie = HttpUtility.UrlDecode(cookie); CachedSignIn signIn = WebUtil.ReadObject<CachedSignIn>(new MemoryStream(Encoding.UTF8.GetBytes(cookie))); username = signIn.Email; token = signIn.Token; } if (username != null && token != null) { string url = _agol.Url + "community/users/" + username + "?token=" + token + "&f=json"; WebUtil.OpenReadAsync(url, null, (sender, e) => { if (e.Error != null) // bail on error { if (callback != null) callback(null, new RequestEventArgs() { Error = e.Error }); return; } User cachedUser = WebUtil.ReadObject<User>(e.Result); if (cachedUser != null && !string.IsNullOrEmpty(cachedUser.Username)) { // Add credential to IdentityManager if (!string.IsNullOrEmpty(token) && !string.IsNullOrEmpty(username) && IdentityManager.Current != null && IdentityManager.Current.FindCredential(_agol.Url, username) == null) { IdentityManager.Credential cred = new IdentityManager.Credential() { UserName = username, Url = _agol.Url, Token = token }; IdentityManager.Current.AddCredential(cred); } Current = cachedUser; Token = token; } else { Current = null; Token = null; } if (callback != null) // notify caller of success callback(null, new RequestEventArgs()); if (SignedInOut != null) SignedInOut(null, EventArgs.Empty); }); } else if(callback != null) callback(null, new RequestEventArgs()); // call the client back in any case }
private void GenerateNetworkCredential() { if (!IsReady) return; _callbackHasBeenCalled = true; // Avoid that IsActive = false calls the callback with Cancel exception IsActive = false; var credential = new IdentityManager.Credential {Credentials = new NetworkCredential(UserName, Password)}; if (Callback != null) Callback(credential, null); }
private IdentityManager.Credential cachedCredential; // Credential that was just retrieved from sign-in // Raised when an authentication challenge occurs in the application private async void OnChallenge(string url, Action<IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options = null) { if (signedOut) // Sign-out occurred within the last two seconds. Do not prompt for login. { callback(null, null); return; } var uri = new Uri(url); var tree = uri.AbsolutePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (tree[tree.Length - 2].ToLower() == "services" && tree[tree.Length - 3].ToLower() == "rest") { // Challenge is coming from a secure folder. Do not prompt. callback(null, null); return; } // In some cases, multiple challenges are raised for resources at the same endpoint (e.g. tiles from // hosted tile services in ArcGIS Online). To keep the user from being prompted to login multiple times // in succession, each new credential is cached for a half-second. If another challenge is raised // within a half second, and the domain of the current challenge matches that of the cached credential, // then the cached credential is used. // Initialize timer for clearing cached credential if (credentialCacheTimer == null) { credentialCacheTimer = new ThrottleTimer(2000, () => cachedCredential = null); } // If there is a credential cached, then sign-in has just occurred. Check to see if the saved // should also be used for this challenge if (cachedCredential != null) { try { // check whether the domain of the currently requested URL matches that of the cached credential if ((new Uri(url)).Domain().ToLower() == (new Uri(cachedCredential.Url).Domain().ToLower())) { // Domains match, so use the cached credential callback(cachedCredential, null); return; } } catch { } } // Sometimes challenges are raised after sign-in is cancelled. To avoid prompting the user after // cancellation, this timer will suppress challenges for two seconds. // Initialize timer for resetting sign-in cancellation tracking if (signInCancelledTimer == null) { signInCancelledTimer = new ThrottleTimer(2000, () => { // Two seconds has expired since sign-in was cancelled. Reset tracking variables. signInCancelled = false; signInCancelUrl = null; }); } // Check whether sign-in has been cancelled within two seconds if (signInCancelled && !string.IsNullOrEmpty(signInCancelUrl)) { try { // Check whether the domain of the requested URL matches that for the cancelled sign-in Uri requestUri = new Uri(url); Uri cancelUri = new Uri(signInCancelUrl); if (requestUri.Domain().Equals(cancelUri.Domain(), StringComparison.OrdinalIgnoreCase) && requestUri.AbsolutePath.Equals(cancelUri.AbsolutePath, StringComparison.OrdinalIgnoreCase)) { // Domains match - do not prompt user callback(null, null); return; } } catch { } } var proxyUrl = options != null ? options.ProxyUrl : null; // Sign in suppression checks passed. Try to authenticate using existing credentials // Try existing credentials IdentityManager.Credential cred = await ApplicationHelper.TryExistingCredentials(url, proxyUrl); if (cred != null) { // The existing credentials were sufficient for authentication. // If the request was for a URL in the current ArcGIS Portal, sign into Portal if (await url.IsFederatedWithPortal()) await ApplicationHelper.SignInToPortal(cred); // If there is not already a credential in the app's credentials collection that has the // same URL, add this one to the collection if (!UserManagement.Current.Credentials.Any(c => c.Url != null && c.Url.Equals(cred.Url, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(c.Token))) UserManagement.Current.Credentials.Add(cred); // Pass the credential to the callback callback(cred, null); return; } // Try just getting a credential for the URL without specifying login info. This can work if // the browser has authenticated the user (e.g. using PKI or IWA auth) try { cred = await IdentityManager.Current.GenerateCredentialTaskAsyncEx(url, options); } catch { } // Swallow authorization exception if (cred != null) { callback(cred, null); return; } // Existing credentials were insufficient. Prompt user to sign in. SignInCommand signInCommand = null; if (await url.IsFederatedWithPortal()) // Sign into ArcGIS portal signInCommand = new SignInToAGSOLCommand() { ProxyUrl = proxyUrl }; else // Sign into ArcGIS Server signInCommand = new SignInToServerCommand() { Url = url, ProxyUrl = proxyUrl }; signInCommand.SignedIn += (o, e) => { // Temporarily store the credential and start the timer. This allows this credential // to be re-used if there is another challenge with the same domain within a couple // seconds of sign-in. cachedCredential = e.Credential; credentialCacheTimer.Invoke(); // Pass the retrieved credential to the callback callback(e.Credential, null); }; signInCommand.Cancelled += (o, e) => { // Set the flags indicating that sign-in was cancelled and start the timer. If another // challenge for the same resouce is raised within the next couple seconds, it is assumed // that the user should not be prompted because cancellation of sign-in has just occurred. signInCancelled = true; signInCancelUrl = url; signInCancelledTimer.Invoke(); // Pass the retrieved credential to the callback callback(null, null); }; // Promt user to sign-in signInCommand.Execute(null); }
/// <summary> /// Attempts to authenticate with the credentials and against the server specified by the command /// </summary> protected async override void onSignIn(object parameter) { if (viewModel == null) { return; } // Set state to busy viewModel.SigningIn = true; try { string credentialUrl = Url; if (viewModel.Url != null) { // Get the token URL for the ArcGIS Server credentialUrl = await ArcGISServerDataSource.GetServicesDirectoryURL(viewModel.Url, null); if (credentialUrl == null) { onSignInFailed(new Exception(Strings.InvalidUrlUserPassword)); } } if (IdentityManager.Current != null) { var options = new IdentityManager.GenerateTokenOptions() { ProxyUrl = ProxyUrl }; // Authenticate against the server to retrieve user token IdentityManager.Credential cred = await IdentityManager.Current.GenerateCredentialTaskAsync( credentialUrl, viewModel.Username, viewModel.Password, options); if (cred != null) { // Save the credential info so it can be used to try to access other services if (!UserManagement.Current.Credentials.Any(c => c.Url != null && c.Url.Equals(cred.Url, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(c.Token))) { UserManagement.Current.Credentials.Add(cred); } try { // Complete sign-in viewModel.SigningIn = false; viewModel.SignInError = null; closeWindow(); OnSignedIn(cred); } catch (Exception ex) { onSignInFailed(ex); } } else { onSignInFailed(new Exception(agolStrings.Get("SignInFailed"))); } } } catch (Exception ex) { onSignInFailed(ex); } }
private static IdentityManager.Credential FromDictionary(IDictionary<string, string> dictionary) { var credential = new IdentityManager.Credential(); if (dictionary.ContainsKey("access_token")) { // Token returned --> no error credential.Token = dictionary["access_token"]; } if (dictionary.ContainsKey("expires_in")) { long expiresIn; Int64.TryParse(dictionary["expires_in"], out expiresIn); credential.ExpirationDate = DateTime.UtcNow + TimeSpan.FromSeconds(expiresIn); } if (dictionary.ContainsKey("refresh_token")) credential.OAuthRefreshToken = dictionary["refresh_token"]; if (dictionary.ContainsKey("username")) credential.UserName = dictionary["username"]; return credential; }
public SignedInEventArgs(IdentityManager.Credential cred) { Credential = cred; }
public async Task <bool> SignInUsingIdentityManager(string username, string password) { IsSigningIn = true; // if oauth2 required params are set, register the server for oauth2 authentication. if (App.IsOrgOAuth2) { IdentityManager.ServerInfo si = new IdentityManager.ServerInfo(); si.ServerUri = App.PortalUri.Uri.ToString(); si.TokenAuthenticationType = IdentityManager.TokenAuthenticationType.OAuthAuthorizationCode; si.OAuthClientInfo = new IdentityManager.OAuthClientInfo() { ClientId = App.AppServerId, RedirectUri = App.AppRedirectUri }; IdentityManager.Current.RegisterServer(si); //IdentityManager.Current.TokenValidity = 30; ////ToDo: revisist persisting and retreiving the token for OAuth2 //IdentityManager.Credential cr = await RetrieveCredentialAsync(); //if (cr != null) //{ // IdentityManager.Current.AddCredential(cr); // _credential = cr; // IsSigningIn = false; // return true; //} } // if username and password were retrieved try getting the credentials without challenging the user else if (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) { try { var credential = await IdentityManager.Current.GenerateCredentialAsync(App.PortalUri.Uri.ToString(), username, password); if (credential != null && !string.IsNullOrEmpty(credential.Token)) { //set the credential _credential = credential; IsSigningIn = false; return(true); } } catch (Exception ex) { IsSigningIn = false; var _ = App.ShowExceptionDialog(ex); return(false); } } // Since credential could not be retrieved, try getting it by challenging the user var credentialRequestInfo = new IdentityManager.CredentialRequestInfo { ServiceUri = App.PortalUri.Uri.ToString(), AuthenticationType = IdentityManager.AuthenticationType.Token, }; try { IdentityManager.Credential credential = await IdentityManager.Current.GetCredentialAsync(credentialRequestInfo, true); if (credential != null && !string.IsNullOrEmpty(credential.Token)) // && credential.Token != Token) { //set the credential _credential = credential; //store credentials using PasswordVault if (!App.IsOrgOAuth2) // && IdentityManager.Current.ChallengeMethodCredentialResults.CredentialSaveOption == Windows.Security.Credentials.UI.CredentialSaveOption.Selected) { new PasswordVault().Add(new PasswordCredential(App.OrganizationUrl, credential.UserName, credential.Password)); } //else // new PasswordVault().Add(new PasswordCredential(App.OrganizationUrl, credential.UserName, credential.Token)); // for OAuth2 store the token instead of the password. IsSigningIn = false; return(true); } //if (credential.Credentials != null) // && credential.Credentials != credentials) //{ // System.Net.ICredentials credentials = credential.Credentials; // hasChanged = true; //} } catch (Exception) { IsSigningIn = false; } IsSigningIn = false; return(false); }
/// <summary> /// Attempt to use application environment credentials to authenticate against the specified URL /// </summary> public static async Task <IdentityManager.Credential> TryExistingCredentials(string requestUrl, string proxyUrl = null) { if (string.IsNullOrEmpty(requestUrl) || UserManagement.Current.Credentials.Count == 0) { return(null); } bool isPortalUrl = await requestUrl.IsFederatedWithPortal(); string credentialUrl = requestUrl; // Get the token auth endpoint if the requested URL is not an ArcGIS Online/Portal URL if (!isPortalUrl) { credentialUrl = await ArcGISServerDataSource.GetServicesDirectoryURL(requestUrl, proxyUrl); } // Check whether there's already a credential for the url foreach (IdentityManager.Credential cred in UserManagement.Current.Credentials) { IdentityManager.Credential newCred = null; if (isPortalUrl && !string.IsNullOrEmpty(cred.Url) && await cred.Url.IsFederatedWithPortal()) { try { // If a portal credential already exists, try simply getting a new credential for the same portal newCred = await IdentityManager.Current.GetCredentialTaskAsync(requestUrl, false); } catch { } } else if (!string.IsNullOrEmpty(cred.Url) && cred.Url.Equals(credentialUrl, StringComparison.OrdinalIgnoreCase)) { newCred = cred; // If a credential that matches the requested URL exists, try it } else if (!string.IsNullOrEmpty(cred.UserName) && !string.IsNullOrEmpty(cred.Password)) { try { var options = new IdentityManager.GenerateTokenOptions() { ProxyUrl = proxyUrl }; // Try authenticating with the user name and password newCred = await IdentityManager.Current.GenerateCredentialTaskAsync(credentialUrl, cred.UserName, cred.Password, options); } catch { } // Intentionally trying credentials that may not work, so swallow exceptions } if (newCred != null) { // Try the original request URL with the new credential's token string testUrl = requestUrl; // Construct the URL with the token if (testUrl.Contains("?")) { testUrl += string.Format("&token={0}&f=json", newCred.Token); } else { testUrl += string.Format("?token={0}&f=json", newCred.Token); } var wc = new ArcGISWebClient() { ProxyUrl = proxyUrl }; string result = null; try { // Issue the request result = await wc.DownloadStringTaskAsync(new Uri(testUrl)); } catch { continue; } if (result != null) { try { // Check whether the response contains a JSON error JsonObject o = (JsonObject)JsonObject.Parse(result); if (o.ContainsKey("error")) { o = (JsonObject)o["error"]; // Check the error code if (o.ContainsKey("code")) { int statusCode = o["code"]; // Server should return 401 Unauthorized, 403 Forbidden, 498 Invalid Token, or 499 // Token Required if the token was insufficient authorization. Other errors should // mean that the resource was accessible with the token, but was just not used // properly. if (statusCode == 401 || statusCode == 403 || statusCode == 498 || statusCode == 499) { continue; } } } } catch { // could not parse response, so it's probably HTML or an image. Assume the // credential is valid since these types of responses are generally not returned // by Portal/Server if there is an error. return(newCred); } return(newCred); } } } return(null); }
/// <summary> /// Initiates sign-in based on the username and token stored in user settings. /// </summary> public void SignInFromLocalStorage(EventHandler <RequestEventArgs> callback) { string username = null; string token = null; // see if the browser cookie is present // string cookie = WebUtil.GetCookie("esri_auth"); if (cookie != null) { cookie = HttpUtility.UrlDecode(cookie); CachedSignIn signIn = WebUtil.ReadObject <CachedSignIn>(new MemoryStream(Encoding.UTF8.GetBytes(cookie))); username = signIn.Email; token = signIn.Token; } if (username != null && token != null) { string url = _agol.Url + "community/users/" + username + "?token=" + token + "&f=json"; WebUtil.OpenReadAsync(url, null, (sender, e) => { if (e.Error != null) // bail on error { if (callback != null) { callback(null, new RequestEventArgs() { Error = e.Error }); } return; } User cachedUser = WebUtil.ReadObject <User>(e.Result); if (cachedUser != null && !string.IsNullOrEmpty(cachedUser.Username)) { // Add credential to IdentityManager if (!string.IsNullOrEmpty(token) && !string.IsNullOrEmpty(username) && IdentityManager.Current != null && IdentityManager.Current.FindCredential(_agol.Url, username) == null) { IdentityManager.Credential cred = new IdentityManager.Credential() { UserName = username, Url = _agol.Url, Token = token }; IdentityManager.Current.AddCredential(cred); } Current = cachedUser; Token = token; } else { Current = null; Token = null; } if (callback != null) // notify caller of success { callback(null, new RequestEventArgs()); } if (SignedInOut != null) { SignedInOut(null, EventArgs.Empty); } }); } else if (callback != null) { callback(null, new RequestEventArgs()); // call the client back in any case } }
private void StartAnalysis() { var userName = App.Current.Resources["AccountUserName"] as string; var password = App.Current.Resources["AccountPassword"] as string; IdentityManager.Current.GenerateCredentialAsync(ANALYSIS_URL, userName, password, (cred, ex) => { _credential = cred; }, new IdentityManager.GenerateTokenOptions() { Referer = "f" }); }
private async Task <IdentityManager.Credential> generateCredential(string portalAppID) { // Get the ArcGIS Online or Portal URL to try to authenticate against string portalUrl = null; var appPortal = MapApplication.Current != null ? MapApplication.Current.Portal : null; if (appPortal != null && !string.IsNullOrEmpty(appPortal.Url)) { portalUrl = MapApplication.Current.Portal.Url; } else if (ArcGISOnline != null) { portalUrl = ArcGISOnline.Url; } else if (ArcGISOnlineEnvironment.ArcGISOnline != null) { portalUrl = ArcGISOnlineEnvironment.ArcGISOnline.Url; } IdentityManager.Credential cred = null; if (IdentityManager.Current != null && !string.IsNullOrEmpty(portalUrl)) { portalUrl = portalUrl.TrimEnd('/'); var options = new IdentityManager.GenerateTokenOptions() { ProxyUrl = ProxyUrl, TokenAuthenticationType = !string.IsNullOrEmpty(portalAppID) ? IdentityManager.TokenAuthenticationType.OAuthImplicit : IdentityManager.TokenAuthenticationType.ArcGISToken }; if (!string.IsNullOrEmpty(portalAppID)) { var oauthAuthorize = new OAuthAuthorize() { UsePopup = true }; options.OAuthAuthorize = oauthAuthorize; var oauthClientInfo = new IdentityManager.OAuthClientInfo() { ClientId = portalAppID, OAuthAuthorize = oauthAuthorize, RedirectUri = HtmlPage.Document.DocumentUri.ToString() }; var serverInfoRegistered = IdentityManager.Current.ServerInfos.Any(info => info.ServerUrl == portalUrl); var serverInfo = serverInfoRegistered ? IdentityManager.Current.ServerInfos.First(info => info.ServerUrl == portalUrl) : new IdentityManager.ServerInfo(); serverInfo.ServerUrl = portalUrl; serverInfo.OAuthClientInfo = oauthClientInfo; serverInfo.TokenAuthenticationType = IdentityManager.TokenAuthenticationType.OAuthImplicit; if (!serverInfoRegistered) { IdentityManager.Current.RegisterServers(new IdentityManager.ServerInfo[] { serverInfo }); } cred = await IdentityManager.Current.GenerateCredentialTaskAsync(portalUrl, options); } else { // Authenticate against ArcGIS Online/Portal to retrieve user token cred = await IdentityManager.Current.GenerateCredentialTaskAsync( portalUrl, viewModel.Username, viewModel.Password, options); } } return(cred); }
private static void ChallengeCertificate(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action<IdentityManager.Credential, Exception> callback) { var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); X509Certificate2Collection certificates; try { const string clientAuthOid = "1.3.6.1.5.5.7.3.2"; // Client Authentication OID store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); // Find Client Authentication certificate certificates = store.Certificates.Find(X509FindType.FindByApplicationPolicy, clientAuthOid, true); // todo true); } catch (Exception) { certificates = null; } finally { store.Close(); } if (certificates != null && certificates.Count >= 1) { // Let the user select/validate the certificate string url = credentialRequestInfos.Url; string resourceName = GetResourceName(url); IdentityManager.ServerInfo serverInfo = IdentityManager.Current.FindServerInfo(url); string server = serverInfo == null ? Regex.Match(url, "http.?//[^/]*").ToString() : serverInfo.ServerUrl; string message = string.Format(Properties.Resources.SignInDialog_CertificateRequired, resourceName, server); // certicate required to access {0} on {1} certificates = X509Certificate2UI.SelectFromCollection(certificates, null, message, X509SelectionFlag.SingleSelection); } IdentityManager.Credential credential = null; Exception error = null; if (certificates != null && certificates.Count > 0) { credential = new IdentityManager.Credential {ClientCertificate = certificates[0]}; } else { // Note : Error type is not that important since the error returned to the user is the initial HTTP error (Authorization Error) error = new System.Security.Authentication.AuthenticationException(); } callback(credential, error); }
// Test Windows Authentication private static bool ChallengeIWA(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action<IdentityManager.Credential, Exception> callback) { if (credentialRequestInfos.AuthenticationType == IdentityManager.AuthenticationType.NetworkCredential && credentialRequestInfos.ResponseHeaders != null && CredentialCache.DefaultCredentials != null) { // test that we didn't already try the IWA authentication if (TryDone(credentialRequestInfos.Url)) return false; // get the WWW-Authenticate header string header = credentialRequestInfos.ResponseHeaders.Get("WWW-Authenticate"); // if the header contains NTLM the server is using Integrated Windows // Authentication (IWA), so try the current user's credentials if (!string.IsNullOrEmpty(header) && header.Contains("NTLM")) // IWA { var credential = new IdentityManager.Credential { Url = credentialRequestInfos.Url, Credentials = CredentialCache.DefaultCredentials }; AddTry(credentialRequestInfos.Url); callback(credential, null); return true; } } return false; }