public override VssCredentials GetVssCredentials(IHostContext context) { var clientId = this.CredentialData.Data.GetValueOrDefault("clientId", null); var authorizationUrl = this.CredentialData.Data.GetValueOrDefault("authorizationUrl", null); // We expect the key to be in the machine store at this point. Configuration should have set all of // this up correctly so we can use the key to generate access tokens. var keyManager = context.GetService <IRSAKeyManager>(); var signingCredentials = VssSigningCredentials.Create(() => keyManager.GetKey()); var clientCredential = new VssOAuthJwtBearerClientCredential(clientId, authorizationUrl, signingCredentials); var agentCredential = new VssOAuthCredential(new Uri(authorizationUrl, UriKind.Absolute), VssOAuthGrant.ClientCredentials, clientCredential); // Construct a credentials cache with a single OAuth credential for communication. The windows credential // is explicitly set to null to ensure we never do that negotiation. return(new VssCredentials(null, agentCredential, CredentialPromptType.DoNotPrompt)); }
public override VssCredentials GetVssCredentials(IHostContext context) { var clientId = this.CredentialData.Data.GetValueOrDefault("clientId", null); var authorizationUrl = this.CredentialData.Data.GetValueOrDefault("authorizationUrl", null); ArgUtil.NotNullOrEmpty(clientId, nameof(clientId)); ArgUtil.NotNullOrEmpty(authorizationUrl, nameof(authorizationUrl)); // For TFS, we need make sure the Schema/Host/Port component of the authorization url also match configuration url. // We can't do this for VSTS, since its SPS/TFS urls are different. var configStore = context.GetService <IConfigurationStore>(); if (configStore.IsConfigured()) { UriBuilder configServerUrl = new UriBuilder(configStore.GetSettings().ServerUrl); UriBuilder authorizationUrlBuilder = new UriBuilder(authorizationUrl); if (!UrlUtil.IsHosted(configServerUrl.Uri.AbsoluteUri) && Uri.Compare(configServerUrl.Uri, authorizationUrlBuilder.Uri, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) != 0) { authorizationUrlBuilder.Scheme = configServerUrl.Scheme; authorizationUrlBuilder.Host = configServerUrl.Host; authorizationUrlBuilder.Port = configServerUrl.Port; var trace = context.GetTrace(nameof(OAuthCredential)); trace.Info($"Replace authorization url's scheme://host:port component with agent configure url's scheme://host:port: '{authorizationUrlBuilder.Uri.AbsoluteUri}'."); authorizationUrl = authorizationUrlBuilder.Uri.AbsoluteUri; } } // We expect the key to be in the machine store at this point. Configuration should have set all of // this up correctly so we can use the key to generate access tokens. var keyManager = context.GetService <IRSAKeyManager>(); var signingCredentials = VssSigningCredentials.Create(() => keyManager.GetKey()); var clientCredential = new VssOAuthJwtBearerClientCredential(clientId, authorizationUrl, signingCredentials); var agentCredential = new VssOAuthCredential(new Uri(authorizationUrl, UriKind.Absolute), VssOAuthGrant.ClientCredentials, clientCredential); // Construct a credentials cache with a single OAuth credential for communication. The windows credential // is explicitly set to null to ensure we never do that negotiation. return(new VssCredentials(null, agentCredential, CredentialPromptType.DoNotPrompt)); }
public override VssCredentials GetVssCredentials(IHostContext context) { var clientId = this.CredentialData.Data.GetValueOrDefault("clientId", null); var authorizationUrl = this.CredentialData.Data.GetValueOrDefault("authorizationUrl", null); // For back compat with .credential file that doesn't has 'oauthEndpointUrl' section var oauthEndpointUrl = this.CredentialData.Data.GetValueOrDefault("oauthEndpointUrl", authorizationUrl); ArgUtil.NotNullOrEmpty(clientId, nameof(clientId)); ArgUtil.NotNullOrEmpty(authorizationUrl, nameof(authorizationUrl)); // We expect the key to be in the machine store at this point. Configuration should have set all of // this up correctly so we can use the key to generate access tokens. var keyManager = context.GetService <IRSAKeyManager>(); var signingCredentials = VssSigningCredentials.Create(() => keyManager.GetKey(), StringUtil.ConvertToBoolean(CredentialData.Data.GetValueOrDefault("requireFipsCryptography"), false)); var clientCredential = new VssOAuthJwtBearerClientCredential(clientId, authorizationUrl, signingCredentials); var agentCredential = new VssOAuthCredential(new Uri(oauthEndpointUrl, UriKind.Absolute), VssOAuthGrant.ClientCredentials, clientCredential); // Construct a credentials cache with a single OAuth credential for communication. The windows credential // is explicitly set to null to ensure we never do that negotiation. return(new VssCredentials(agentCredential, CredentialPromptType.DoNotPrompt)); }
private async Task <VssCredentials> GetNewOAuthAuthorizationSetting(CancellationToken token) { Trace.Info("Start checking oauth authorization url update."); while (true) { var backoff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(45)); await HostContext.Delay(backoff, token); try { var migratedAuthorizationUrl = await _runnerServer.GetRunnerAuthUrlAsync(_settings.PoolId, _settings.AgentId); if (!string.IsNullOrEmpty(migratedAuthorizationUrl)) { var credData = _configStore.GetCredentials(); var clientId = credData.Data.GetValueOrDefault("clientId", null); var currentAuthorizationUrl = credData.Data.GetValueOrDefault("authorizationUrl", null); Trace.Info($"Current authorization url: {currentAuthorizationUrl}, new authorization url: {migratedAuthorizationUrl}"); if (string.Equals(currentAuthorizationUrl, migratedAuthorizationUrl, StringComparison.OrdinalIgnoreCase)) { // We don't need to update credentials. Trace.Info("No needs to update authorization url"); await Task.Delay(TimeSpan.FromMilliseconds(-1), token); } var keyManager = HostContext.GetService <IRSAKeyManager>(); var signingCredentials = VssSigningCredentials.Create(() => keyManager.GetKey()); var migratedClientCredential = new VssOAuthJwtBearerClientCredential(clientId, migratedAuthorizationUrl, signingCredentials); var migratedRunnerCredential = new VssOAuthCredential(new Uri(migratedAuthorizationUrl, UriKind.Absolute), VssOAuthGrant.ClientCredentials, migratedClientCredential); Trace.Info("Try connect service with Token Service OAuth endpoint."); var runnerServer = HostContext.CreateService <IRunnerServer>(); await runnerServer.ConnectAsync(new Uri(_settings.ServerUrl), migratedRunnerCredential); await runnerServer.GetAgentPoolsAsync(); Trace.Info($"Successfully connected service with new authorization url."); var migratedCredData = new CredentialData { Scheme = Constants.Configuration.OAuth, Data = { { "clientId", clientId }, { "authorizationUrl", migratedAuthorizationUrl }, { "oauthEndpointUrl", migratedAuthorizationUrl }, }, }; _configStore.SaveMigratedCredential(migratedCredData); return(migratedRunnerCredential); } else { Trace.Verbose("No authorization url updates"); } } catch (Exception ex) { Trace.Error("Fail to get/test new authorization url."); Trace.Error(ex); try { await _runnerServer.ReportRunnerAuthUrlErrorAsync(_settings.PoolId, _settings.AgentId, ex.ToString()); } catch (Exception e) { // best effort Trace.Error("Fail to report the migration error"); Trace.Error(e); } } } }