public KeyVaultTestFixture() { Initialize(string.Empty); if (vaultAddress != null && HttpMockServer.Mode == HttpRecorderMode.Record) { //Create one key to use for testing. Key creation is expensive. var myClient = new KeyVaultClient(new TestKeyVaultCredential(GetAccessToken), GetHandlers()); keyName = "sdktestkey"; var attributes = new KeyAttributes(); var createdKey = myClient.CreateKeyAsync(vaultAddress, keyName, JsonWebKeyType.Rsa, 2048, JsonWebKeyOperation.AllOperations, attributes).GetAwaiter().GetResult(); keyIdentifier = new KeyIdentifier(createdKey.Key.Kid); keyName = keyIdentifier.Name; keyVersion = keyIdentifier.Version; tokenCache = new TokenCache(); _deviceCodeForStorageTests = null; retryExecutor = new RetryPolicy <SoftDeleteErrorDetectionStrategy>(new ExponentialBackoffRetryStrategy(8, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(60), TimeSpan.FromSeconds(5))); } else { retryExecutor = new RetryPolicy <SoftDeleteErrorDetectionStrategy>(new FixedIntervalRetryStrategy(5, TimeSpan.FromSeconds(5.0))); } }
[WorkItem(1407)] // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1407 public async Task DeviceCodeExceptionsOn200OKAsync() { using (var harness = CreateTestHarness()) { TestCommon.MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); var handler = new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateInvalidClientResponseMessage() }; harness.HttpManager.AddMockHandler(handler); var parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false), account: null); DeviceCodeResult actualDeviceCodeResult = null; var deviceCodeParameters = new AcquireTokenWithDeviceCodeParameters { DeviceCodeResultCallback = result => { actualDeviceCodeResult = result; return(Task.FromResult(0)); } }; var request = new DeviceCodeRequest(harness.ServiceBundle, parameters, deviceCodeParameters); var ex = await AssertException.TaskThrowsAsync <MsalServiceException>( () => request.ExecuteAsync(CancellationToken.None)).ConfigureAwait(false); } }
public void TestSetup() { expectedTenantId = null; expectedReplyUri = null; authCode = Guid.NewGuid().ToString(); options = new TokenCredentialOptions(); expectedToken = Guid.NewGuid().ToString(); expectedUserAssertion = Guid.NewGuid().ToString(); expiresOn = DateTimeOffset.Now.AddHours(1); result = new AuthenticationResult( expectedToken, false, null, expiresOn, expiresOn, TenantId, new MockAccount("username"), null, new[] { Scope }, Guid.NewGuid(), null, "Bearer"); mockConfidentialMsalClient = new MockMsalConfidentialClient() .WithSilentFactory( (_, _tenantId, _replyUri, _) => { Assert.AreEqual(expectedTenantId, _tenantId); Assert.AreEqual(expectedReplyUri, _replyUri); return(new ValueTask <AuthenticationResult>(result)); }) .WithAuthCodeFactory( (_, _tenantId, _replyUri, _) => { Assert.AreEqual(expectedTenantId, _tenantId); Assert.AreEqual(expectedReplyUri, _replyUri); return(result); }) .WithOnBehalfOfFactory( (_, _, userAssertion, _, _) => { Assert.AreEqual(expectedUserAssertion, userAssertion.Assertion); return(new ValueTask <AuthenticationResult>(result)); }) .WithClientFactory( (_, _tenantId) => { Assert.AreEqual(expectedTenantId, _tenantId); return(result); }); expectedCode = Guid.NewGuid().ToString(); mockPublicMsalClient = new MockMsalPublicClient(); deviceCodeResult = MockMsalPublicClient.GetDeviceCodeResult(deviceCode: expectedCode); mockPublicMsalClient.DeviceCodeResult = deviceCodeResult; var publicResult = new AuthenticationResult( expectedToken, false, null, expiresOn, expiresOn, TenantId, new MockAccount("username"), null, new[] { Scope }, Guid.NewGuid(), null, "Bearer"); mockPublicMsalClient.SilentAuthFactory = (_, tId) => { Assert.AreEqual(expectedTenantId, tId); return(publicResult); }; mockPublicMsalClient.DeviceCodeAuthFactory = (_, _) => { // Assert.AreEqual(tenantId, tId); return(publicResult); }; mockPublicMsalClient.InteractiveAuthFactory = (_, _, _, _, tenant, _, _) => { Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match"); return(result); }; mockPublicMsalClient.SilentAuthFactory = (_, tenant) => { Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match"); return(result); }; mockPublicMsalClient.ExtendedSilentAuthFactory = (_, _, _, tenant, _, _) => { Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match"); return(result); }; mockPublicMsalClient.UserPassAuthFactory = (_, tenant) => { Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match"); return(result); }; mockPublicMsalClient.RefreshTokenFactory = (_, _, _, _, tenant, _, _) => { Assert.AreEqual(expectedTenantId, tenant, "TenantId passed to msal should match"); return(result); }; }
public async Task <AuthenticationHeaderValue> AcquireTokenAsync(HttpAuthentication auth) { var tenant = auth.tenant; var resourceId = auth.resourceId; var clientId = auth.clientId; // https://login.microsoftonline.com // https://login.windows.net var authority = $"https://login.windows.net/{tenant ?? "common"}"; AccountEntry account = null; if (account == null) { account = _settings.accounts.Where(entry => string.Equals(entry.authority, authority, StringComparison.Ordinal) && string.Equals(entry.resource, resourceId, StringComparison.Ordinal)).LastOrDefault(); } if (account == null) { account = _settings.accounts.Where(entry => string.IsNullOrEmpty(entry.authority) && string.Equals(entry.resource, resourceId, StringComparison.Ordinal)).LastOrDefault(); } if (account == null) { account = _settings.accounts.Where(entry => string.Equals(entry.authority, authority, StringComparison.Ordinal) && string.IsNullOrEmpty(entry.resource)).LastOrDefault(); } if (account == null) { account = _settings.accounts.Where(entry => string.IsNullOrEmpty(entry.authority) && string.IsNullOrEmpty(entry.resource)).LastOrDefault(); } var ctx = new AuthenticationContext(authority, _tokenCache); AuthenticationResult result = null; if (account != null) { if (!string.IsNullOrEmpty(account.token)) { return(new AuthenticationHeaderValue("Bearer", account.token)); } else if (!string.IsNullOrEmpty(account.password)) { var basic = $"{account.username}:{account.password}"; return(new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(basic)))); } else if (!string.IsNullOrEmpty(account.appid)) { result = await ctx.AcquireTokenAsync(resourceId, new ClientCredential(account.appid, account.secret)); } else { throw new InvalidOperationException("Account entry requires either token or appid and secret values."); } } else { if (auth.interactive == false) { throw new InvalidOperationException("Matching account credentials have not been stored, and interactive authentication is disallowed."); } try { result = await ctx.AcquireTokenSilentAsync(resourceId, clientId); } catch { DeviceCodeResult codeResult = await ctx.AcquireDeviceCodeAsync(resourceId, clientId); _console.Error.WriteLine(codeResult.Message.Color(ConsoleColor.DarkYellow)); result = await ctx.AcquireTokenByDeviceCodeAsync(codeResult); } } return(new AuthenticationHeaderValue(result.AccessTokenType, result.AccessToken)); }
private Task DeviceCodeResultCallback(DeviceCodeResult arg) { Console.WriteLine($"Please go to {arg.VerificationUrl} and use this Device Code: {arg.UserCode}"); return(Task.Delay(0)); }
//public static string aadAccessToken; static void Main(string[] args) { string slackArchiveBasePath = ""; string slackArchiveTempPath = ""; string channelsPath = ""; bool channelsOnly = false; bool copyFileAttachments = false; Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { if (!channelsOnly) { try { Utils.Files.CleanUpTempDirectoriesAndFiles(slackArchiveTempPath); } catch { // to-do: something } } }; if (args.Length > 0) { // retreive settings from appsettings.json instead of hard coding them here var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .AddEnvironmentVariables(); Configuration = builder.Build(); Console.WriteLine(""); Console.WriteLine("****************************************************************************************************"); Console.WriteLine("Welcome to Channel Master!"); Console.WriteLine("This tool makes it easy to bulk create channels in an existing Microsoft Team."); Console.WriteLine("All we need a Slack Team export ZIP file whose channels you wish to re-create."); Console.WriteLine("Or, you can define new channels in a file called channels.json."); Console.WriteLine("****************************************************************************************************"); Console.WriteLine(""); while (Configuration["AzureAd:TenantId"] == "" || Configuration["AzureAd:ClientId"] == "") { Console.WriteLine(""); Console.WriteLine("****************************************************************************************************"); Console.WriteLine("You need to provide your Azure Active Directory Tenant Name and the Application ID you created for"); Console.WriteLine("use with application to continue. You can do this by altering Program.cs and re-compiling this app."); Console.WriteLine("Or, you can provide it right now."); Console.Write("Azure Active Directory Tenant Name (i.e your-domain.onmicrosoft.com): "); Configuration["AzureAd:TenantId"] = Console.ReadLine(); Console.Write("Azure Active Directory Application ID: "); Configuration["AzureAd:ClientId"] = Console.ReadLine(); Console.WriteLine("****************************************************************************************************"); } Console.WriteLine("**************************************************"); Console.WriteLine("Tenant is " + (Configuration["AzureAd:TenantId"])); Console.WriteLine("Application ID is " + (Configuration["AzureAd:ClientId"])); Console.WriteLine("Redirect URI is " + (Configuration["AzureAd:AadRedirectUri"])); Console.WriteLine("**************************************************"); Console.WriteLine(""); Console.WriteLine("****************************************************************************************************"); Console.WriteLine("Your tenant admin consent URL is https://login.microsoftonline.com/common/oauth2/authorize?response_type=id_token" + "&client_id=" + Configuration["AzureAd:ClientId"] + "&redirect_uri=" + Configuration["AzureAd:AadRedirectUri"] + "&prompt=admin_consent" + "&nonce=" + Guid.NewGuid().ToString()); Console.WriteLine("****************************************************************************************************"); Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine("****************************************************************************************************"); Console.WriteLine("Let's get started! Sign in to Microsoft with your Teams credentials:"); AuthenticationResult authenticationResult = UserLogin(); var aadAccessToken = authenticationResult.AccessToken; if (String.IsNullOrEmpty(authenticationResult.AccessToken)) { Console.WriteLine("Something went wrong. Please try again!"); Environment.Exit(1); } else { Console.WriteLine("You've successfully signed in. Welcome " + authenticationResult.UserInfo.DisplayableId); } var selectedTeamId = Utils.Channels.SelectJoinedTeam(aadAccessToken); if (selectedTeamId == "") { Environment.Exit(0); } if (args[0].EndsWith("channels.json", StringComparison.CurrentCulture)) { channelsPath = args[0]; channelsOnly = true; } else { slackArchiveTempPath = Path.GetTempFileName(); slackArchiveBasePath = Utils.Files.DecompressSlackArchiveFile(args[0], slackArchiveTempPath); channelsPath = Path.Combine(slackArchiveBasePath, "channels.json"); } Console.WriteLine("Scanning channels.json"); var slackChannelsToMigrate = Utils.Channels.ScanSlackChannelsJson(channelsPath); Console.WriteLine("Scanning channels.json - done"); Console.WriteLine("Creating channels in MS Teams"); var msTeamsChannelsWithSlackProps = Utils.Channels.CreateChannelsInMsTeams(aadAccessToken, selectedTeamId, slackChannelsToMigrate, slackArchiveTempPath); Console.WriteLine("Creating channels in MS Teams - done"); if (channelsOnly) { Environment.Exit(0); } Console.Write("Create web pages that show the message history for each re-created Slack channel? (y|n): "); var copyMessagesResponse = Console.ReadLine(); if (copyMessagesResponse.StartsWith("y", StringComparison.CurrentCultureIgnoreCase)) { Console.Write("Copy files attached to Slack messages to Microsoft Teams? (y|n): "); var copyFileAttachmentsResponse = Console.ReadLine(); if (copyFileAttachmentsResponse.StartsWith("y", StringComparison.CurrentCultureIgnoreCase)) { copyFileAttachments = true; } Console.WriteLine("Scanning users in Slack archive"); var slackUserList = Utils.Users.ScanUsers(Path.Combine(slackArchiveBasePath, "users.json")); Console.WriteLine("Scanning users in Slack archive - done"); Console.WriteLine("Scanning messages in Slack channels"); Utils.Messages.ScanMessagesByChannel(msTeamsChannelsWithSlackProps, slackArchiveTempPath, slackUserList, aadAccessToken, selectedTeamId, copyFileAttachments); Console.WriteLine("Scanning messages in Slack channels - done"); //} Console.Beep(800, 10000); Console.WriteLine("Tasks complete. Press any key to exit"); Console.ReadKey(); Utils.Files.CleanUpTempDirectoriesAndFiles(slackArchiveTempPath); } else { Console.WriteLine("Please give us a path to your Slack archive: i.e. /path/to/your/slack-archive-zip-file/slack.zip"); Console.WriteLine("Or, give us a path to your channels.json file: i.e. /path/to/your/channels.json"); } } AuthenticationResult UserLogin() { authenticationContext = new AuthenticationContext (String.Format(CultureInfo.InvariantCulture, Configuration["AzureAd:AadInstance"], Configuration["AzureAd:TenantId"])); authenticationContext.TokenCache.Clear(); DeviceCodeResult deviceCodeResult = authenticationContext.AcquireDeviceCodeAsync(aadResourceAppId, (Configuration["AzureAd:ClientId"])).Result; Console.WriteLine(deviceCodeResult.Message); return(authenticationContext.AcquireTokenByDeviceCodeAsync(deviceCodeResult).Result); } }
private Task DeviceCodeCallback(DeviceCodeResult deviceCode, CancellationToken cancellationToken) { return(_deviceCodeCallback(new DeviceCodeInfo(deviceCode), cancellationToken)); }
public async override Task <IToken> LoginAsync() { string accessToken = string.Empty; Logger.Log("Loggin in with ADAL..."); #if UNITY_EDITOR var platformSupportsUI = false; #else var platformSupportsUI = true; #endif var authority = $"https://login.microsoftonline.com/{TenantId}"; var resource = "https://sts.mixedreality.azure.com"; // TRY https://login.microsoftonline.com/organizations authenticationContext = new AuthenticationContext(authority, new FileTokenCache(Logger)); Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationResult authenticationResult = null; try { authenticationResult = await authenticationContext.AcquireTokenSilentAsync("https://sts.mixedreality.azure.com", ClientId); } catch (AdalSilentTokenAcquisitionException adalEx) { // Exception: AdalSilentTokenAcquisitionException // Caused when there are no tokens in the cache or a required refresh failed. // Action: Case 1, resolvable with an interactive request. Logger.Log($"AdalSilentTokenAcquisitionException Message: {adalEx.Message}"); Logger.Log($"AdalSilentTokenAcquisitionException Message: {adalEx.ErrorCode.ToString()}"); try { var userId = Store.GetUserId(UserIdKey); UserIdentifier userIdentifier = UserIdentifier.AnyUser; if (!string.IsNullOrEmpty(userId)) { userIdentifier = new UserIdentifier(userId, UserIdentifierType.UniqueId); } string extraQueryParameters = string.Empty; if (platformSupportsUI) { authenticationResult = await authenticationContext.AcquireTokenAsync(resource, ClientId, new Uri("urn:ietf:wg:oauth:2.0:oob"), new PlatformParameters(PromptBehavior.Auto, false), userIdentifier, extraQueryParameters); } else { DeviceCodeResult codeResult = await authenticationContext.AcquireDeviceCodeAsync(resource, ClientId, extraQueryParameters); // Here we need a ui notification to the user to go and login elsewhere.. // display codeResult.message... Logger.Log(codeResult.Message); authenticationResult = await authenticationContext.AcquireTokenByDeviceCodeAsync(codeResult); } } catch (AdalServiceException e) { HandleAdalServiceException(e, Logger); } catch (AdalException e) { HandleAdalException(e, Logger); } } catch (AdalServiceException e) { HandleAdalServiceException(e, Logger); } catch (AdalException e) { HandleAdalException(e, Logger); } if (authenticationResult != null) { if (authenticationResult.UserInfo != null) { Logger.Log($"Provider: {authenticationResult.UserInfo.IdentityProvider}"); Logger.Log($"Given Name: {authenticationResult.UserInfo.GivenName}"); Logger.Log($"Family Name: {authenticationResult.UserInfo.FamilyName}"); Logger.Log($"ID: {authenticationResult.UserInfo.DisplayableId}"); } // Cache the user identifier... Store.SaveUser(UserIdKey, authenticationResult.UserInfo.UniqueId); accessToken = AADToken = authenticationResult.AccessToken; Username = authenticationResult.UserInfo.DisplayableId; Logger.Log($"Access Token: {accessToken}", false); } return(new AADToken(accessToken)); }
public string GetAadAuthenticatedToken(AsAzureContext asAzureContext, SecureString password, PromptBehavior promptBehavior, string clientId, string resourceUri, Uri resourceRedirectUri) #endif { var authUriBuilder = new UriBuilder((string)asAzureContext.Environment.Endpoints[AsAzureEnvironment.AsRolloutEndpoints.AdAuthorityBaseUrl]); authUriBuilder.Path = string.IsNullOrEmpty(asAzureContext.Account.Tenant) ? "common" : asAzureContext.Account.Tenant; var authenticationContext = new AuthenticationContext( authUriBuilder.ToString(), AsAzureClientSession.TokenCache); AuthenticationResult result = null; string accountType = string.IsNullOrEmpty(asAzureContext.Account.Type) ? AsAzureAccount.AccountType.User : asAzureContext.Account.Type; if (password == null && accountType == AsAzureAccount.AccountType.User) { if (asAzureContext.Account.Id != null) { #if NETSTANDARD result = authenticationContext.AcquireTokenAsync( resourceUri, clientId, resourceRedirectUri, new PlatformParameters(), new UserIdentifier(asAzureContext.Account.Id, UserIdentifierType.OptionalDisplayableId)).Result; #else result = authenticationContext.AcquireToken( resourceUri, clientId, resourceRedirectUri, promptBehavior, new UserIdentifier(asAzureContext.Account.Id, UserIdentifierType.OptionalDisplayableId)); #endif } else { #if NETSTANDARD result = authenticationContext.AcquireTokenAsync( resourceUri, clientId, resourceRedirectUri, new PlatformParameters()).Result; #else result = authenticationContext.AcquireToken( resourceUri, clientId, resourceRedirectUri, promptBehavior); #endif } asAzureContext.Account.Id = result.UserInfo.DisplayableId; asAzureContext.Account.Tenant = result.TenantId; asAzureContext.Account.UniqueId = result.UserInfo.UniqueId; } else { if (accountType == AsAzureAccount.AccountType.User) { #if NETSTANDARD //https://stackoverflow.com/a/39393039/294804 //https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/issues/482 //https://github.com/Azure-Samples/active-directory-dotnet-deviceprofile/blob/5d5499d09c918ae837810d457822474df97600e9/DirSearcherClient/Program.cs#L206-L210 // Note: More robust implementation in UserTokenProvider.Netcore.cs in DoAcquireToken DeviceCodeResult codeResult = authenticationContext.AcquireDeviceCodeAsync(resourceUri, clientId).Result; promptAction(codeResult?.Message); result = authenticationContext.AcquireTokenByDeviceCodeAsync(codeResult).Result; #else UserCredential userCredential = new UserCredential(asAzureContext.Account.Id, password); result = authenticationContext.AcquireToken(resourceUri, clientId, userCredential); #endif asAzureContext.Account.Id = result.UserInfo.DisplayableId; asAzureContext.Account.Tenant = result.TenantId; asAzureContext.Account.UniqueId = result.UserInfo.UniqueId; } else if (accountType == AsAzureAccount.AccountType.ServicePrincipal) { if (string.IsNullOrEmpty(asAzureContext.Account.CertificateThumbprint)) { #if NETSTANDARD ClientCredential credential = new ClientCredential(asAzureContext.Account.Id, ConversionUtilities.SecureStringToString(password)); result = authenticationContext.AcquireTokenAsync(resourceUri, credential).Result; #else ClientCredential credential = new ClientCredential(asAzureContext.Account.Id, password); result = authenticationContext.AcquireToken(resourceUri, credential); #endif } else { DiskDataStore dataStore = new DiskDataStore(); var certificate = dataStore.GetCertificate(asAzureContext.Account.CertificateThumbprint); if (certificate == null) { throw new ArgumentException(string.Format(Resources.CertificateNotFoundInStore, asAzureContext.Account.CertificateThumbprint)); } #if NETSTANDARD result = authenticationContext.AcquireTokenAsync(resourceUri, new ClientAssertionCertificate(asAzureContext.Account.Id, certificate)).Result; #else result = authenticationContext.AcquireToken(resourceUri, new ClientAssertionCertificate(asAzureContext.Account.Id, certificate)); #endif } } } return(result?.AccessToken); }
public override VssCredentials GetVssCredentials(IHostContext context) { ArgUtil.NotNull(context, nameof(context)); Tracing trace = context.GetTrace(nameof(AadDeviceCodeAccessToken)); trace.Info(nameof(GetVssCredentials)); ArgUtil.NotNull(CredentialData, nameof(CredentialData)); CredentialData.Data.TryGetValue(Constants.Agent.CommandLine.Args.Url, out string serverUrl); ArgUtil.NotNullOrEmpty(serverUrl, nameof(serverUrl)); var tenantAuthorityUrl = GetTenantAuthorityUrl(context, serverUrl); if (tenantAuthorityUrl == null) { throw new NotSupportedException($"This Azure DevOps organization '{serverUrl}' is not backed by Azure Active Directory."); } LoggerCallbackHandler.LogCallback = ((LogLevel level, string message, bool containsPii) => { switch (level) { case LogLevel.Information: trace.Info(message); break; case LogLevel.Error: trace.Error(message); break; case LogLevel.Warning: trace.Warning(message); break; default: trace.Verbose(message); break; } }); LoggerCallbackHandler.UseDefaultLogging = false; AuthenticationContext ctx = new AuthenticationContext(tenantAuthorityUrl.AbsoluteUri); var queryParameters = $"redirect_uri={Uri.EscapeDataString(new Uri(serverUrl).GetLeftPart(UriPartial.Authority))}"; if (PlatformUtil.RunningOnMacOS) { throw new Exception("AAD isn't supported for MacOS"); } DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync("https://management.core.windows.net/", _azureDevOpsClientId, queryParameters).GetAwaiter().GetResult(); var term = context.GetService <ITerminal>(); term.WriteLine($"Please finish AAD device code flow in browser ({codeResult.VerificationUrl}), user code: {codeResult.UserCode}"); if (string.Equals(CredentialData.Data[Constants.Agent.CommandLine.Flags.LaunchBrowser], bool.TrueString, StringComparison.OrdinalIgnoreCase)) { try { if (PlatformUtil.RunningOnWindows) { Process.Start(new ProcessStartInfo() { FileName = codeResult.VerificationUrl, UseShellExecute = true }); } else if (PlatformUtil.RunningOnLinux) { Process.Start(new ProcessStartInfo() { FileName = "xdg-open", Arguments = codeResult.VerificationUrl }); } else { throw new NotImplementedException("Unexpected platform"); } } catch (Exception ex) { // not able to open browser, ex: xdg-open/open is not installed. trace.Error(ex); term.WriteLine($"Fail to open browser. {codeResult.Message}"); } } AuthenticationResult authResult = ctx.AcquireTokenByDeviceCodeAsync(codeResult).GetAwaiter().GetResult(); ArgUtil.NotNull(authResult, nameof(authResult)); trace.Info($"receive AAD auth result with {authResult.AccessTokenType} token"); var aadCred = new VssAadCredential(new VssAadToken(authResult)); VssCredentials creds = new VssCredentials(null, aadCred, CredentialPromptType.DoNotPrompt); trace.Info("cred created"); return(creds); }
/// <summary> /// Callback used when the device code flow is in use and we need to prompt the user to /// visit the relevant web page and type in a code. /// </summary> /// <param name="result"> /// Information about the login attempt, including the code the user will need to fill in. /// </param> /// <returns>True, because we never fail.</returns> private static bool DeviceCodeFlowCallback(DeviceCodeResult result) { Console.WriteLine(result.Message); return(true); }
async Task <ExpirationMetadata <string> > GetTokenViaCode(string authority, string resource) { using (var scope = serviceScopeFactory.CreateScope()) { var http = scope.ServiceProvider.GetRequiredService <System.Net.Http.IHttpClientFactory>().CreateClient(); var req = new HttpRequestMessage(HttpMethod.Get, $"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource={resource}"); req.Headers.TryAddWithoutValidation("Metadata", "true"); try { var tokenresponse = await http.SendAsync(req); tokenresponse.EnsureSuccessStatusCode(); var token = JToken.Parse(await tokenresponse.Content.ReadAsStringAsync()).SelectToken("$.access_token").ToString(); //TODO get proper validuntil return(new ExpirationMetadata <string> { Result = token, ValidUntil = DateTimeOffset.UtcNow.AddMinutes(2) }); } catch (HttpRequestException ex) { } var a = new AzureServiceTokenProvider(); var accessToken = await a.GetAccessTokenAsync(resource); if (accessToken != null) { return(new ExpirationMetadata <string> { Result = accessToken, ValidUntil = DateTimeOffset.UtcNow.AddMinutes(2) }); } IOptions <ManagedIdentityTokenProviderOptions> options = scope.ServiceProvider.GetRequiredService <IOptions <ManagedIdentityTokenProviderOptions> >(); var ctx = new AuthenticationContext(authority ?? $"https://login.microsoftonline.com/{options.Value.TenantId}", scope.ServiceProvider.GetRequiredService <TokenCache>()); AuthenticationResult result = null; try { result = await ctx.AcquireTokenSilentAsync(resource, options.Value.ApplicationId); } catch (AdalException adalException) { if (adalException.ErrorCode == AdalError.FailedToAcquireTokenSilently || adalException.ErrorCode == AdalError.UserInteractionRequired) { try { DeviceCodeResult codeResult = await ctx.AcquireDeviceCodeAsync(resource, options.Value.ApplicationId); logger.LogInformation(codeResult.Message); var url = codeResult.VerificationUrl + "#" + codeResult.UserCode; //Process.Start( codeResult.VerificationUrl+"#"+codeResult.UserCode); var startInfo = new ProcessStartInfo("explorer.exe", url); Process.Start(startInfo); result = await ctx.AcquireTokenByDeviceCodeAsync(codeResult); } catch (Exception exc) { logger.LogError(exc, "Failed to get token"); } } } return(new ExpirationMetadata <string> { Result = result?.AccessToken, ValidUntil = result?.ExpiresOn ?? DateTimeOffset.UtcNow.AddSeconds(10) }); } }
private async Task DefaultDeviceCallback(DeviceCodeResult result) { Console.WriteLine(result.Message); await Task.FromResult(0); }
private static async Task HandlePrompt(DeviceCodeResult prompt) { await Console.Out.WriteLineAsync(prompt.Message); }
/// <summary> /// Acquires security token from the authority using an device code previously received. /// </summary> /// <param name="authority">Address of the authority to issue the token.</param> /// <param name="deviceCodeResult">The device code result received from calling AcquireDeviceCodeAsync.</param> /// <param name="clientSecret">Secret of the client requesting the token.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>An instance of <see cref="AuthenticationResult"/> that represents the access token.</returns> public async Task <AuthenticationResult> AcquireTokenByDeviceCodeAsync(Uri authority, DeviceCodeResult deviceCodeResult, string clientSecret = null, CancellationToken cancellationToken = default) { AuthenticationResponse authResponse = null; Dictionary <string, string> content; HttpResponseMessage response = null; TimeSpan timeSpan; deviceCodeResult.AssertNotNull(nameof(deviceCodeResult)); timeSpan = deviceCodeResult.ExpiresOn - DateTimeOffset.UtcNow; while (timeSpan.TotalSeconds > 0.0) { try { using (HttpRequestMessage request = new HttpRequestMessage( HttpMethod.Post, new Uri($"https://{authority.Host}/{authority.Segments[authority.Segments.Length - 1].TrimEnd('/')}/oauth2/token"))) { content = new Dictionary <string, string> { ["client_id"] = deviceCodeResult.ClientId, ["code"] = deviceCodeResult.DeviceCode, ["grant_type"] = "device_code", ["resource"] = deviceCodeResult.Resource }; if (!string.IsNullOrEmpty(clientSecret)) { content.Add("client_secret", clientSecret); } request.Content = new FormUrlEncodedContent(content); response = await HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false); authResponse = await HandleAuthenticationResponseAsync(response).ConfigureAwait(false); break; } } catch (AuthenticationException ex) { if (!ex.ErrorCode.Equals("authorization_pending", StringComparison.OrdinalIgnoreCase)) { throw; } } finally { response?.Dispose(); } await Task.Delay(TimeSpan.FromSeconds(deviceCodeResult.Interval)).ConfigureAwait(false); timeSpan = deviceCodeResult.ExpiresOn - DateTimeOffset.UtcNow; } if (authResponse == null) { throw new AuthenticationException("code_expired", "Verification code expired before contacting the server"); } return(new AuthenticationResult(authResponse)); }
/// <summary> /// Acquires the Azure management token asynchronously. /// </summary> /// <param name="tenantId">The tenant identifier.</param> /// <param name="usePrompt">The prompt behavior. If true, raises a prompt, otherwise performs silent login.</param> /// <param name="userIdentifier">Optional user for which token is to be fetched.</param> /// <returns>AAD authentication result.</returns> private async Task <UserAuthenticationDetails> AcquireAzureManagementTokenAsync( string tenantId, bool usePrompt, string userIdentifier = null) { Guid correlationId = Guid.NewGuid(); this.logger.LogInformation($"Acquiring token with correlation Id set to '{correlationId}'"); try { #if USEADAL AuthenticationContext authenticationContext = new AuthenticationContext( $"{UserAuthenticator.AADLoginAuthority}{tenantId}", validateAuthority: false, TokenCache.DefaultShared, new AzureAdHttpClientFactory()) { CorrelationId = correlationId, }; AuthenticationResult authenticationResult = null; if (userIdentifier == null) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Uri redirectUri = DefaultOsBrowserWebUi.UpdateRedirectUri(new Uri("http://localhost")); authenticationResult = await authenticationContext.AcquireTokenAsync( UserAuthenticator.AzureAADResource, UserAuthenticator.PSClientId, redirectUri, new PlatformParameters( usePrompt ? PromptBehavior.SelectAccount : PromptBehavior.Never, new DefaultOsBrowserWebUi(this.logger))).ConfigureAwait(false); } else { DeviceCodeResult deviceCodeResult = await authenticationContext.AcquireDeviceCodeAsync(UserAuthenticator.AzureAADResource, UserAuthenticator.PSClientId).ConfigureAwait(false); Console.WriteLine($"Interactive login required. Please enter {deviceCodeResult.UserCode} when asked for in the browser window. If a browser windows does not open or is not supported, follow the instructions below (these can be followed on any device) {Environment.NewLine}{deviceCodeResult.Message}"); await Task.Delay(1000).ConfigureAwait(false); authenticationResult = await authenticationContext.AcquireTokenByDeviceCodeAsync(deviceCodeResult).ConfigureAwait(false); } } else { authenticationResult = await authenticationContext.AcquireTokenSilentAsync( UserAuthenticator.AzureAADResource, UserAuthenticator.PSClientId).ConfigureAwait(false); } return(new UserAuthenticationDetails { AccessToken = authenticationResult.AccessToken, TenantId = authenticationResult.TenantId, Username = authenticationResult.UserInfo.DisplayableId, }); #else AuthenticationResult authenticationResult = null; if (userIdentifier == null) { if (this.publicClientApplication.IsSystemWebViewAvailable) { authenticationResult = await this.publicClientApplication .AcquireTokenInteractive(new List <string>() { AzureAADResource + "/.default" }) .WithAuthority($"{UserAuthenticator.AADLoginAuthority}{tenantId}", validateAuthority: false) .WithCorrelationId(correlationId) .WithPrompt(usePrompt ? Prompt.SelectAccount : Prompt.NoPrompt) .ExecuteAsync().ConfigureAwait(false); } else { authenticationResult = await this.publicClientApplication .AcquireTokenWithDeviceCode( new List <string>() { AzureAADResource + "/.default" }, async (deviceCodeResult) => { Console.WriteLine($"Interactive login required. Please enter {deviceCodeResult.UserCode} when asked for in the browser window. If a browser windows does not open or is not supported, follow the instructions below (these can be followed on any device) {Environment.NewLine}{deviceCodeResult.Message}"); await Task.Delay(1000).ConfigureAwait(false); try { // Open the browser with the url. ProcessStartInfo processStartInfo = new ProcessStartInfo { FileName = deviceCodeResult.VerificationUrl, UseShellExecute = true, }; Process.Start(processStartInfo); } catch (Exception) { Console.WriteLine($"Could not open the url for verification on this machine. Please open {deviceCodeResult.VerificationUrl} from any machine and enter code {deviceCodeResult.UserCode} when asked to do so to continue. The process will continue automatically once the login verification is done."); } }) .WithAuthority($"{UserAuthenticator.AADLoginAuthority}{tenantId}", validateAuthority: false) .WithCorrelationId(correlationId) .ExecuteAsync().ConfigureAwait(false); } } else { authenticationResult = await this.publicClientApplication .AcquireTokenSilent(new List <string>() { AzureAADResource + "/.default" }, userIdentifier) .WithAuthority($"{UserAuthenticator.AADLoginAuthority}{tenantId}", validateAuthority: false) .WithCorrelationId(correlationId) .ExecuteAsync().ConfigureAwait(false); } return(new UserAuthenticationDetails { AccessToken = authenticationResult.AccessToken, Username = authenticationResult.Account.Username, TenantId = authenticationResult.TenantId, }); #endif } catch (Exception ex) { this.logger.LogError(ex, $"Failed to acquire token. Correlation Id '{correlationId}'"); throw; } }
private static Task WriteDeviceCode(DeviceCodeResult dcr) { Console.Out.WriteLineAsync(dcr.Message); return(Task.CompletedTask); }
private Task CustomDeviceFlowCallback(DeviceCodeResult result) { Console.WriteLine(result.Message); return(Task.FromResult(0)); }
private static bool DeviceCodeHandler(DeviceCodeResult result) { Console.WriteLine(result.Message); return(true); }
// Login to the user's account and create a UCWA app static void Login() { #region Login // Clear any cached tokens. // We do this to ensure logins with different accounts work // during the same launch of the app authenticationContext.TokenCache.Clear(); Console.WriteLine("How do you want to login?"); Console.WriteLine("console | dialog | code >"); string loginStyle = Console.ReadLine(); AuthenticationResult testCredentials = null; UserCredential uc = null; switch (loginStyle.ToLower()) { case "console": uc = GetUserCredentials(); testCredentials = UcwaSfbo.AzureAdAuth.GetAzureAdToken(authenticationContext, sfboResourceAppId, clientId, redirectUri, uc); break; case "dialog": if (redirectUri == String.Empty) { Console.WriteLine("You haven't defined redirectUri which is needed if you want to sign in with a dialog"); return; } testCredentials = UcwaSfbo.AzureAdAuth.GetAzureAdToken(authenticationContext, sfboResourceAppId, clientId, redirectUri, uc); break; case "code": DeviceCodeResult deviceCodeResult = authenticationContext.AcquireDeviceCodeAsync(sfboResourceAppId, clientId).Result; Console.WriteLine(deviceCodeResult.Message); Console.WriteLine("Or, use Control-C to exit the app"); testCredentials = authenticationContext.AcquireTokenByDeviceCodeAsync(deviceCodeResult).Result; break; default: Console.Write("Please select a login style and try again"); Console.Write("\n"); return; } if (testCredentials == null) { Console.WriteLine("We encountered an Azure AD error"); Console.WriteLine("Check your tenant, clientID, and credentials"); return; } ucwaApplicationsUri = UcwaAutodiscovery.GetUcwaRootUri(authenticationContext, sfboResourceAppId, clientId, redirectUri, uc); Console.WriteLine("We'll store the base UCWA app URI for use with UCWA app calls"); Console.WriteLine("We prefix this to the links returned from the UCWA apps POST"); Console.WriteLine("Since these links aren't full URIs"); ucwaApplicationsHost = Helpers.ReduceUriToProtoAndHost(ucwaApplicationsUri); Console.WriteLine("ucwaApplicationsHost is " + ucwaApplicationsHost); Console.WriteLine("Get a token to access the user's UCWA Applications Resources from Azure AD."); Console.WriteLine("We can re-use this token for each UCWA app call"); ucwaAuthenticationResult = AzureAdAuth.GetAzureAdToken(authenticationContext, ucwaApplicationsHost, clientId, redirectUri, uc); Console.WriteLine("Now we'll create and/or query UCWA Apps via POST"); Console.WriteLine("Well create a UCWA apps object to pass to CreateUcwaApps"); UcwaApplications.UcwaMyAppsObject ucwaMyAppsObject = new UcwaApplications.UcwaMyAppsObject() { UserAgent = "myAgent", EndpointId = "1234", Culture = "en-US" }; Console.WriteLine("Making request to ucwaApplicationsUri " + ucwaApplicationsUri); createUcwaAppsResults = UcwaApplications.CreateUcwaApps(ucwaAuthenticationResult, ucwaApplicationsUri, ucwaMyAppsObject); return; }
private static Task CustomDeviceFlowCallback(DeviceCodeResult result) { // Provide custom logic to process result information and read device code. Console.WriteLine(result.Message); return(Task.FromResult(0)); }
/// <summary> /// Acquires the security token from the authority. /// </summary> /// <param name="context">Context to be used when requesting a security token.</param> /// <param name="debugAction">The action to write debug statements.</param> /// <param name="promptAction">The action to prompt the user for input.</param> /// <returns>The result from the authentication request.</returns> public AuthenticationToken Authenticate(PartnerContext context, Action <string> debugAction, Action <string> promptAction = null) { AuthenticationContext authContext; AuthenticationResult authResult; Claim claim; DateTimeOffset expiration; JwtSecurityToken token; JwtSecurityTokenHandler tokenHandler; PartnerEnvironment environment; environment = PartnerEnvironment.PublicEnvironments[context.Environment]; authContext = new AuthenticationContext( $"{environment.ActiveDirectoryAuthority}{context.Account.Properties[AzureAccountPropertyType.Tenant]}"); if (context.Account.Type == AccountType.AccessToken) { tokenHandler = new JwtSecurityTokenHandler(); token = tokenHandler.ReadJwtToken(context.Account.Properties[AzureAccountPropertyType.AccessToken]); claim = token.Claims.SingleOrDefault(c => c.Type.Equals("oid", StringComparison.InvariantCultureIgnoreCase)); context.Account.Properties[AzureAccountPropertyType.UserIdentifier] = claim?.Value; claim = token.Claims.SingleOrDefault(c => c.Type.Equals("tid", StringComparison.InvariantCultureIgnoreCase)); context.Account.Properties[AzureAccountPropertyType.Tenant] = claim?.Value; claim = token.Claims.SingleOrDefault(c => c.Type.Equals("exp", StringComparison.InvariantCultureIgnoreCase)); expiration = DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt64(claim.Value, CultureInfo.InvariantCulture)); claim = token.Claims.SingleOrDefault(c => c.Type.Equals("unique_name", StringComparison.InvariantCultureIgnoreCase)); context.AuthenticationType = claim == null ? AuthenticationTypes.AppOnly : AuthenticationTypes.AppPlusUser; debugAction( string.Format( CultureInfo.CurrentCulture, Resources.AuthenticateAccessTokenTrace, expiration.ToString(CultureInfo.CurrentCulture), context.Account.Properties[AzureAccountPropertyType.Tenant], context.Account.Properties[AzureAccountPropertyType.UserIdentifier], claim?.Value)); return(new AuthenticationToken( context.Account.Properties[AzureAccountPropertyType.AccessToken], expiration)); } else if (context.Account.Type == AccountType.ServicePrincipal) { debugAction( string.Format( CultureInfo.CurrentCulture, Resources.AuthenticateServicePrincipalTrace, environment.ActiveDirectoryAuthority, context.Account.Id, environment.AzureAdGraphEndpoint, context.Account.Properties[AzureAccountPropertyType.Tenant])); authResult = authContext.AcquireTokenAsync( environment.AzureAdGraphEndpoint, new ClientCredential( context.Account.Id, context.Account.Properties[AzureAccountPropertyType.ServicePrincipalSecret])).ConfigureAwait(false).GetAwaiter().GetResult(); context.AuthenticationType = Authentication.AuthenticationTypes.AppOnly; } else if (!context.Account.Properties.ContainsKey(AzureAccountPropertyType.UserIdentifier)) { #if NETSTANDARD debugAction( string.Format( CultureInfo.CurrentCulture, Resources.AuthenticateDeviceCodeTrace, context.ApplicationId, environment.PartnerCenterEndpoint)); DeviceCodeResult deviceCodeResult = authContext.AcquireDeviceCodeAsync( environment.PartnerCenterEndpoint, context.ApplicationId).ConfigureAwait(false).GetAwaiter().GetResult(); promptAction(deviceCodeResult.Message); authResult = authContext.AcquireTokenByDeviceCodeAsync(deviceCodeResult).ConfigureAwait(false).GetAwaiter().GetResult(); #else debugAction( string.Format( CultureInfo.CurrentCulture, Resources.AuthenticateAuthorizationCodeTrace, context.ApplicationId, environment.ActiveDirectoryAuthority, AuthenticationConstants.RedirectUriValue, environment.PartnerCenterEndpoint)); authResult = authContext.AcquireTokenAsync( environment.PartnerCenterEndpoint, context.ApplicationId, new Uri(AuthenticationConstants.RedirectUriValue), new PlatformParameters(PromptBehavior.Always), UserIdentifier.AnyUser).ConfigureAwait(false).GetAwaiter().GetResult(); #endif context.Account.Id = authResult.UserInfo.DisplayableId; context.Account.Properties[AzureAccountPropertyType.Tenant] = authResult.TenantId; context.Account.Properties[AzureAccountPropertyType.UserIdentifier] = authResult.UserInfo.UniqueId; context.AuthenticationType = Authentication.AuthenticationTypes.AppPlusUser; } else { debugAction( string.Format( CultureInfo.CurrentCulture, Resources.AuthenticateSilentTrace, context.ApplicationId, environment.ActiveDirectoryAuthority, environment.PartnerCenterEndpoint, context.Account.Id)); authResult = authContext.AcquireTokenSilentAsync( environment.PartnerCenterEndpoint, context.ApplicationId, new UserIdentifier(context.Account.Id, UserIdentifierType.RequiredDisplayableId)).ConfigureAwait(false).GetAwaiter().GetResult(); context.Account.Id = authResult.UserInfo.DisplayableId; context.Account.Properties[AzureAccountPropertyType.Tenant] = authResult.TenantId; context.Account.Properties[AzureAccountPropertyType.UserIdentifier] = authResult.UserInfo.UniqueId; context.AuthenticationType = Authentication.AuthenticationTypes.AppPlusUser; } return(new AuthenticationToken(authResult.AccessToken, authResult.ExpiresOn)); }
static async Task Main() { // Flip to true for ADAL logging - // it's pretty verbose thus pretty handy. LoggerCallbackHandler.UseDefaultLogging = false; AuthenticationContext context = new AuthenticationContext(authority); DeviceCodeResult codeResult = await context.AcquireDeviceCodeAsync(resourceId, clientId); Console.BackgroundColor = ConsoleColor.DarkCyan; Console.WriteLine("\nUsing OAuth 2.0 Device Flow. You need to sign in."); Console.WriteLine(codeResult.Message + "\n"); Console.ResetColor(); AuthenticationResult result = await context.AcquireTokenByDeviceCodeAsync(codeResult); // Get the JWT bearer token from the authorization header // Use https://jwt.ms to decode string accessToken = result.AccessToken; string accessTokenType = result.AccessTokenType; Console.WriteLine("Azure AD returned this JWT:"); Console.BackgroundColor = ConsoleColor.Red; Console.WriteLine($"\n{accessTokenType} {accessToken}\n"); Console.ResetColor(); // Get tenant information to validate incoming JWT tokens string stsDiscoveryEndpoint = $"{authority}/.well-known/openid-configuration"; OpenIdConnectConfigurationRetriever configRetriever = new OpenIdConnectConfigurationRetriever(); ConfigurationManager <OpenIdConnectConfiguration> configManager = new ConfigurationManager <OpenIdConnectConfiguration>(stsDiscoveryEndpoint, configRetriever); OpenIdConnectConfiguration config = await configManager.GetConfigurationAsync(); TokenValidationParameters validationParameters = new TokenValidationParameters { ValidIssuer = config.Issuer, // gets pulled from https://login.microsoftonline.com/swearjarbank.onmicrosoft.com/.well-known/openid-configuration ValidateIssuer = true, // compares token issuer claim with https://login.microsoftonline.com/swearjarbank.onmicrosoft.com/.well-known/openid-configuration ValidAudience = resourceId, // or ValidAudiences = new [] { resourceId, "https://2ndresource" }, ValidateAudience = true, // compares aud claim to ValidAudience ValidateIssuerSigningKey = true, IssuerSigningKeys = config.SigningKeys, RequireExpirationTime = true, RequireSignedTokens = true }; // VALIDATE TOKEN // https://stackoverflow.com/a/39870281/4148708 // "There are two steps to verity the token. // First, verify the signature of the token to ensure the token // was issued by Azure Active Directory. Second verify the claims // in the token based on the business logic." SecurityToken validatedToken = new JwtSecurityToken(); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); ClaimsPrincipal validationResult = null; try { validationResult = tokenHandler.ValidateToken(accessToken, validationParameters, out validatedToken); } catch (Exception ex) { Console.BackgroundColor = ConsoleColor.DarkRed; Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("TOKEN DID NOT PASS VALIDATION LOGIC."); Console.WriteLine(ex.Message); Console.ResetColor(); Console.ReadKey(); Environment.Exit(-1); } Console.BackgroundColor = ConsoleColor.DarkGreen; Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("TOKEN IS VALID."); Console.ResetColor(); Console.WriteLine($"Issuer: {validatedToken.Issuer}\n" + $"ValidFrom: {validatedToken.ValidFrom}\n" + $"ValidTo: {validatedToken.ValidTo}\n" + $"Public Signing Key: {validatedToken.SigningKey.KeyId}\n\n" + "Claims:"); IEnumerator claims = validationResult.Claims.GetEnumerator(); while (claims.MoveNext()) { Console.WriteLine($" {claims.Current}"); } Console.ReadKey(); }
private Task ShowDeviceCodeInTty(DeviceCodeResult dcr) { Context.Terminal.WriteLine(dcr.Message); return(Task.CompletedTask); }
internal DeviceCodeInfo(DeviceCodeResult deviceCode) : this(deviceCode.UserCode, deviceCode.DeviceCode, new Uri(deviceCode.VerificationUrl), deviceCode.ExpiresOn, deviceCode.Message, deviceCode.ClientId, deviceCode.Scopes) { }