// Create the online basemap layer (with token credentials) and add it to the map private async Task InitializeOnlineBasemap() { try { _onlineTiledLayer = new ArcGISTiledMapServiceLayer(new Uri(ONLINE_BASEMAP_URL)); _onlineTiledLayer.ID = _onlineTiledLayer.DisplayName = ONLINE_LAYER_ID; // Generate token credentials if using tiledbasemaps.arcgis.com if (!string.IsNullOrEmpty(ONLINE_BASEMAP_TOKEN_URL)) { // Set credentials and token for online basemap var options = new IdentityManager.GenerateTokenOptions() { Referer = new Uri(_onlineTiledLayer.ServiceUri) }; var cred = await IdentityManager.Current.GenerateCredentialAsync(ONLINE_BASEMAP_TOKEN_URL, USERNAME, PASSWORD); if (cred != null && !string.IsNullOrEmpty(cred.Token)) { _onlineTiledLayer.Token = cred.Token; IdentityManager.Current.AddCredential(cred); } } await _onlineTiledLayer.InitializeAsync(); mapView.Map.Layers.Add(_onlineTiledLayer); } catch (Exception ex) { MessageBox.Show(ex.Message, "Sample Error"); } }
public static Task <IdentityManager.Credential> GenerateCredentialTaskAsyncEx( this IdentityManager manager, string url, IdentityManager.GenerateTokenOptions generateTokenOptions = null) { var tcs = new TaskCompletionSource <IdentityManager.Credential>(); // Authenticate using the passed-in info manager.GenerateCredentialAsync(url, (cred, ex) => { if (ex != null) { tcs.TrySetException(ex); } else { tcs.TrySetResult(cred); } }, generateTokenOptions); return(tcs.Task); }
private void Challenge(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { LoginGrid.Visibility = System.Windows.Visibility.Visible; TitleTextBlock.Text = string.Format("Login to access: \n{0}", url); if (!challengeAttemptsPerUrl.ContainsKey(url)) { challengeAttemptsPerUrl.Add(url, 0); } RoutedEventHandler handleClick = null; handleClick = (s, e) => { IdentityManager.Current.GenerateCredentialAsync(url, UserTextBox.Text, PasswordTextBox.Text, (credential, ex) => { challengeAttemptsPerUrl[url]++; if (ex == null || challengeAttemptsPerUrl[url] == 3) { LoginLoadLayerButton.Click -= handleClick; callback(credential, ex); } }, options); }; LoginLoadLayerButton.Click += handleClick; System.Windows.Input.KeyEventHandler handleEnterKeyDown = null; handleEnterKeyDown = (s, e) => { if (e.Key == System.Windows.Input.Key.Enter) { PasswordTextBox.KeyDown -= handleEnterKeyDown; handleClick(null, null); } }; PasswordTextBox.KeyDown += handleEnterKeyDown; }
/// <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 void DoSignInInUIThreadEx(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions) { switch (credentialRequestInfos.AuthenticationType) { case IdentityManager.AuthenticationType.Token: case IdentityManager.AuthenticationType.NetworkCredential: DoSignInInUIThread(credentialRequestInfos.Url, callback, generateTokenOptions, credentialRequestInfos.AuthenticationType); break; case IdentityManager.AuthenticationType.Certificate: ChallengeCertificate(credentialRequestInfos, callback); break; } }
/// <summary> /// Static challenge method leaveraging the SignInDialog in a child window. /// This method manages all credential types. /// Note however that in case of <see cref="IdentityManager.AuthenticationType.Certificate">certificate authentication</see> the SignInDialog UI is not used. /// The standard .Net dialog box for selecting an X.509 certificate from a certificate collection is used instead. /// </summary> /// <seealso cref="DoSignIn"/> /// <param name="credentialRequestInfos">The information about the credential to get.</param> /// <param name="callback">The callback.</param> /// <param name="generateTokenOptions">The generate token options.</param> public static void DoSignInEx(IdentityManager.CredentialRequestInfos credentialRequestInfos, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions = null) { // Check if IWA authentication might be OK if (ChallengeIWA(credentialRequestInfos, callback)) { return; } // Display UI for challenging System.Windows.Threading.Dispatcher d = null; if (Application.Current != null) { d = Application.Current.Dispatcher; } if (d != null && !d.CheckAccess()) { //Ensure we are showing up the SignInDialog on the UI thread d.BeginInvoke((Action)(() => DoSignInInUIThreadEx(credentialRequestInfos, callback, generateTokenOptions))); } else { DoSignInInUIThreadEx(credentialRequestInfos, callback, generateTokenOptions); } }
#pragma warning restore 1574 private static void DoSignInInUIThread(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions #if !SILVERLIGHT , IdentityManager.AuthenticationType authenticationType = IdentityManager.AuthenticationType.Token #endif ) { // In SL and WPF : Create the ChildWindow that contains the SignInDialog #if SILVERLIGHT ChildWindow childWindow = new ChildWindow(); DependencyProperty titleProperty = ChildWindow.TitleProperty; #else var childWindow = new Window { ShowInTaskbar = false, WindowStartupLocation = WindowStartupLocation.CenterOwner, WindowStyle = WindowStyle.ToolWindow, SizeToContent = SizeToContent.WidthAndHeight, ResizeMode = ResizeMode.NoResize, WindowState = WindowState.Normal }; if (Application.Current != null && Application.Current.MainWindow != null) { try { childWindow.Owner = Application.Current.MainWindow; } catch (Exception) { // May fire an exception when used inside an excel or powerpoint addins } } DependencyProperty titleProperty = Window.TitleProperty; #endif // Create the SignInDialog with the parameters given as arguments var signInDialog = new SignInDialog { Url = url, Callback = (credential, error) => { childWindow.Close(); callback(credential, error); }, GenerateTokenOptions = generateTokenOptions, IsActive = true, Width = 300, #if !SILVERLIGHT _authenticationType = authenticationType #endif }; childWindow.Content = signInDialog; // Bind the Title so the ChildWindow Title is the SignInDialog title (taht will be initialized later) Binding binding = new Binding("Title") { Source = signInDialog }; childWindow.SetBinding(titleProperty, binding); childWindow.Closed += (s, e) => signInDialog.IsActive = false; // be sure the SignInDialog is deactivated (i.e. Callback executed once) when closing the childwindow using the X // Show the window #if SILVERLIGHT childWindow.Show(); #else childWindow.ShowDialog(); #endif }
#pragma warning disable 1574 // cref attribute 'DoSignInEx' that could not be resolved /// <summary> /// Static challenge method leaveraging the SignInDialog in a child window. /// </summary> /// <ESRIWPF><remarks>This method manages token credential only. See <see cref="DoSignInEx"/> for the extended method managing all credential types.</remarks></ESRIWPF> /// <param name="url">The URL.</param> /// <param name="callback">The callback.</param> /// <param name="generateTokenOptions">The generate token options.</param> /// <ESRIWPF><seealso cref="DoSignInEx"/></ESRIWPF> public static void DoSignIn(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions generateTokenOptions = null) { System.Windows.Threading.Dispatcher d = null; #if SILVERLIGHT // Note that RootVisual is only accessible from UI Thread so Application.Current.RootVisual.Dispatcher crashes if (Deployment.Current != null) // should always be the case { d = Deployment.Current.Dispatcher; } #else if (Application.Current != null) { d = Application.Current.Dispatcher; } #endif if (d != null && !d.CheckAccess()) { //Ensure we are showing up the SignInDialog on the UI thread d.BeginInvoke((Action) delegate { DoSignInInUIThread(url, callback, generateTokenOptions); }); } else { DoSignInInUIThread(url, callback, generateTokenOptions); } }
/// <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> /// 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; }
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); }
// Alternative login approach (used by commented out IdentityManager ChallengeMethod registration in the constructor) private void GetCredentials(string url, System.Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { // TODO get user / password from a UI displayed to user or from a secure location string user = "******"; string password = "******"; // When challenged for a token generate a set of credentials based on the specified username and password. IdentityManager.Current.GenerateCredentialAsync( url, user, password, (credential, ex) => { // Raise the Action to return to the method that triggered the challenge (GetMapAsync). callback(credential, ex); }, options); }
private void ChallengeWithTheLoginDialog(string url, System.Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { _loginDialog.ShowDialog(); // When challenged for a token generate a set of credentials based on the specified username and password. IdentityManager.Current.GenerateCredentialAsync(url, _loginDialog.UserName, _loginDialog.Password, (credential, ex) => { // Raise the Action to return to the method that triggered the challenge (GetMapAsync). callback(credential, ex); }, options); }
private void Challenge(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { // Option 1: Access to url, callback, and options passed to SignInDialog //SignInDialog.DoSignIn(url, callback, options); // Option 2: Use Popup to contain SignInDialog //var popup = new Popup //{ // HorizontalOffset = 200, // VerticalOffset = 200 //}; //SignInDialog signInDialog = new SignInDialog() //{ // Width = 300, // Url = url, // IsActive = true, // Callback = (credential, ex) => // { // callback(credential, ex); // popup.IsOpen = false; // } //}; //popup.Child = signInDialog; //popup.IsOpen = true; // Option 3: Use a template to define SignInDialog content //MainSignInDialog.Url = url; //MainSignInDialog.IsActive = true; //MainSignInDialog.Visibility = System.Windows.Visibility.Visible; // Option 4: Use the default Runtime template to define SignInDialog content if (_username != null) { MainSignInDialog.UserName = _username; } MainSignInDialog.Url = url; MainSignInDialog.IsActive = true; MainSignInDialog.Visibility = System.Windows.Visibility.Visible; MainSignInDialog.Callback = (credential, ex) => { callback(credential, ex); MainSignInDialog.Visibility = System.Windows.Visibility.Collapsed; MainSignInDialog.IsActive = false; }; }
private void Challenge(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { SignInDialog.DoSignIn(url, (credential, error) => { if (error == null) { ToolBorder.Visibility = System.Windows.Visibility.Visible; LoggedInGrid.Visibility = System.Windows.Visibility.Visible; LoggedInUserTextBlock.Text = credential.UserName; } callback(credential, error); } , options); }
/// <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); } }
// Activate IdentityManager but don't accept any challenge. // User has to use the 'SignIn' button for getting its own maps. private static void Challenge(string url, Action <IdentityManager.Credential, Exception> callback, IdentityManager.GenerateTokenOptions options) { callback(null, new NotImplementedException()); }
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; }