protected override void ProcessRecord() { source = new CancellationTokenSource(); var messageWriter = new CmdletMessageWriter(this); CancellationToken cancellationToken = source.Token; var endPoint = string.Empty; using (var authManager = new AuthenticationManager()) { endPoint = authManager.GetAzureADLoginEndPoint(AzureEnvironment); } Task.Factory.StartNew(() => { var deviceCodeApplication = PublicClientApplicationBuilder.Create(PnPConnection.PnPManagementShellClientId).WithAuthority($"{endPoint}/organizations/").WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient").Build(); deviceCodeApplication.AcquireTokenWithDeviceCode(new[] { "https://graph.microsoft.com/.default" }, codeResult => { if (Utilities.OperatingSystem.IsWindows()) { ClipboardService.SetText(codeResult.UserCode); messageWriter.WriteMessage($"Provide consent for the PnP Management Shell application to access SharePoint.\n\nWe opened a browser and navigated to {codeResult.VerificationUrl}\n\nEnter code: {codeResult.UserCode} (we copied this code to your clipboard)"); BrowserHelper.GetWebBrowserPopup(codeResult.VerificationUrl, "Provide consent for the PnP Management Shell application"); } else { messageWriter.WriteMessage($"Please provide consent for the PnP Management Shell application by navigating to\n\n{codeResult.VerificationUrl}\n\nEnter code: {codeResult.UserCode}."); } return(Task.FromResult(0)); }).ExecuteAsync(cancellationToken).GetAwaiter().GetResult(); messageWriter.Finished = true; }, cancellationToken); messageWriter.Start(); }
private void StartConsentFlow(string loginEndPoint, AzureADApp azureApp, string redirectUri, string token, HttpClient httpClient, PSObject record, CmdletMessageWriter messageWriter, List <PermissionScope> scopes) { Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"Starting consent flow."); var resource = scopes.FirstOrDefault(s => s.resourceAppId == PermissionScopes.ResourceAppId_Graph) != null ? $"https://{AzureAuthHelper.GetGraphEndPoint(AzureEnvironment)}/.default" : "https://microsoft.sharepoint-df.com/.default"; var consentUrl = $"{loginEndPoint}/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope={resource}&redirect_uri={redirectUri}"; if (OperatingSystem.IsWindows() && !NoPopup) { var waitTime = 60; // CmdletMessageWriter.WriteFormattedWarning(this, $"Waiting {waitTime} seconds to launch the consent flow in a popup window.\n\nThis wait is required to make sure that Azure AD is able to initialize all required artifacts. You can always navigate to the consent page manually:\n\n{consentUrl}"); var progressRecord = new ProgressRecord(1, "Please wait...", $"Waiting {waitTime} seconds to launch the consent flow in a popup window. This wait is required to make sure that Azure AD is able to initialize all required artifacts."); for (var i = 0; i < waitTime; i++) { progressRecord.PercentComplete = Convert.ToInt32((Convert.ToDouble(i) / Convert.ToDouble(waitTime)) * 100); WriteProgress(progressRecord); // if (Convert.ToDouble(i) % Convert.ToDouble(10) > 0) // { // Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "-"); // } // else // { // Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{i}]"); // } System.Threading.Thread.Sleep(1000); // Check if CTRL+C has been pressed and if so, abort the wait if (Stopping) { Host.UI.WriteLine("Wait cancelled. You can provide consent manually by navigating to"); Host.UI.WriteLine(consentUrl); break; } } progressRecord.RecordType = ProgressRecordType.Completed; WriteProgress(progressRecord); if (!Stopping) { // Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{waitTime}]"); // Host.UI.WriteLine(); if (ParameterSpecified(nameof(Interactive))) { using (var authManager = AuthenticationManager.CreateWithInteractiveLogin(azureApp.AppId, (url, port) => { BrowserHelper.OpenBrowserForInteractiveLogin(url, port, true, cancellationTokenSource); }, Tenant, "You successfully provided consent", "You failed to provide consent.", AzureEnvironment)) { authManager.GetAccessToken(resource, Microsoft.Identity.Client.Prompt.Consent); } } else { BrowserHelper.GetWebBrowserPopup(consentUrl, "Please provide consent", new[] { ("https://pnp.github.io/powershell/consent.html", BrowserHelper.UrlMatchType.StartsWith) }, cancellationTokenSource: cancellationTokenSource, cancelOnClose: false);
internal static PnPConnection InstantiateDeviceLoginConnection(string url, bool launchBrowser, CmdletMessageWriter messageWriter, AzureEnvironment azureEnvironment, CancellationToken cancellationToken) { var connectionUri = new Uri(url); var scopes = new[] { $"{connectionUri.Scheme}://{connectionUri.Authority}//.default" }; // the second double slash is not a typo. PnP.Framework.AuthenticationManager authManager = null; if (PnPConnection.CachedAuthenticationManager != null) { authManager = PnPConnection.CachedAuthenticationManager; PnPConnection.CachedAuthenticationManager = null; } else { Func <DeviceCodeResult, Task> deviceCodeCallback = (deviceCodeResult) => { if (launchBrowser) { if (Utilities.OperatingSystem.IsWindows()) { ClipboardService.SetText(deviceCodeResult.UserCode); messageWriter.WriteMessage($"\n\nCode {deviceCodeResult.UserCode} has been copied to your clipboard\n\n"); BrowserHelper.GetWebBrowserPopup(deviceCodeResult.VerificationUrl, "Please log in"); } else { messageWriter.WriteMessage($"\n\n{deviceCodeResult.Message}\n\n"); } } else { messageWriter.WriteMessage($"\n\n{deviceCodeResult.Message}\n\n"); } return(Task.FromResult(0)); }; authManager = new PnP.Framework.AuthenticationManager(PnPConnection.PnPManagementShellClientId, deviceCodeCallback, azureEnvironment); } using (authManager) { var clientContext = authManager.GetContext(url.ToString(), cancellationToken); var context = PnPClientContext.ConvertFrom(clientContext); var connectionType = ConnectionType.O365; var spoConnection = new PnPConnection(context, connectionType, null, PnPConnection.PnPManagementShellClientId, null, url.ToString(), null, PnPPSVersionTag, InitializationType.DeviceLogin) { ConnectionMethod = ConnectionMethod.DeviceLogin, AzureEnvironment = azureEnvironment }; return(spoConnection); } }
private void StartConsentFlow(string loginEndPoint, AzureApp azureApp, string redirectUri, string token, HttpClient httpClient, PSObject record) { var consentUrl = $"{loginEndPoint}/{Tenant}/v2.0/adminconsent?client_id={azureApp.AppId}&scope=https://microsoft.sharepoint-df.com/.default&redirect_uri={redirectUri}"; if (OperatingSystem.IsWindows() && !NoPopup) { var waitTime = 60; CmdletMessageWriter.WriteFormattedWarning(this, $"Waiting {waitTime} seconds to launch consent flow in a popup window.\n\nThis wait is required to make sure that Azure AD is able to initialize all required artifacts. You can always navigate to the consent page manually:\n\n{consentUrl}"); for (var i = 0; i < waitTime; i++) { if (Convert.ToDouble(i) % Convert.ToDouble(10) > 0) { Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, "-"); } else { Host.UI.Write(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{i}]"); } System.Threading.Thread.Sleep(1000); // Check if CTRL+C has been pressed and if so, abort the wait if (Stopping) { break; } } if (!Stopping) { Host.UI.WriteLine(ConsoleColor.Yellow, Host.UI.RawUI.BackgroundColor, $"[{waitTime}]"); Host.UI.WriteLine(); BrowserHelper.GetWebBrowserPopup(consentUrl, "Please provide consent", new[] { (redirectUri, BrowserHelper.UrlMatchType.StartsWith) });
internal static PnPConnection CreateWithDeviceLogin(string clientId, string url, string tenantId, bool launchBrowser, CmdletMessageWriter messageWriter, AzureEnvironment azureEnvironment, CancellationTokenSource cancellationTokenSource) { var connectionUri = new Uri(url); var scopes = new[] { $"{connectionUri.Scheme}://{connectionUri.Authority}//.default" }; // the second double slash is not a typo. PnP.Framework.AuthenticationManager authManager = null; if (PnPConnection.CachedAuthenticationManager != null) { authManager = PnPConnection.CachedAuthenticationManager; PnPConnection.CachedAuthenticationManager = null; } else { authManager = PnP.Framework.AuthenticationManager.CreateWithDeviceLogin(clientId, tenantId, (deviceCodeResult) => { if (launchBrowser) { if (Utilities.OperatingSystem.IsWindows()) { ClipboardService.SetText(deviceCodeResult.UserCode); messageWriter.WriteWarning($"\n\nCode {deviceCodeResult.UserCode} has been copied to your clipboard\n\n"); BrowserHelper.GetWebBrowserPopup(deviceCodeResult.VerificationUrl, "Please log in", cancellationTokenSource: cancellationTokenSource, cancelOnClose: false); } else { messageWriter.WriteWarning($"\n\n{deviceCodeResult.Message}\n\n"); } } else { messageWriter.WriteWarning($"\n\n{deviceCodeResult.Message}\n\n"); } return(Task.FromResult(0)); }, azureEnvironment); } using (authManager) { try { var clientContext = authManager.GetContext(url.ToString(), cancellationTokenSource.Token); var context = PnPClientContext.ConvertFrom(clientContext); context.ExecutingWebRequest += (sender, e) => { e.WebRequestExecutor.WebRequest.UserAgent = $"NONISV|SharePointPnP|PnPPS/{((AssemblyFileVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttribute(typeof(AssemblyFileVersionAttribute))).Version} ({System.Environment.OSVersion.VersionString})"; }; var connectionType = ConnectionType.O365; var spoConnection = new PnPConnection(context, connectionType, null, clientId, null, url.ToString(), null, PnPPSVersionTag, InitializationType.DeviceLogin) { ConnectionMethod = ConnectionMethod.DeviceLogin, AzureEnvironment = azureEnvironment }; return(spoConnection); } catch (Microsoft.Identity.Client.MsalServiceException msalServiceException) { if (msalServiceException.Message.StartsWith("AADSTS50059:")) { cancellationTokenSource.Cancel(); throw new Exception("Please specify -Tenant with either the tenant id or hostname."); } else { throw; } } } }