/// <summary> /// Process an incoming serialized message. /// /// The message will be deserialized, its signature verified, /// and it will be routed. /// /// If the message is a command to execute, the execution will /// run and the periodicUpdateFunction will be run regularly to /// update the caller on the runtime status. /// /// If the message is a status update, the periodicUpdateFunction /// will be executed only once. /// </summary> /// <param name="serializedMessage">Serialized Agent message</param> /// <param name="periodicUpdateFunction">Function which is invoked periodically to communicate runtime status</param> /// <returns></returns> public async Task ProcessMessageAsync( string serializedMessage, Func <ProviderWorkflowActionCollection, Task> periodicUpdateFunction) { var envelope = JsonConvert.DeserializeObject <AgentMessageEnvelope>(serializedMessage); envelope.MessageObject = null; if (envelope.Target != _options.Value.InstanceId) { return; } if (!await envelope.VerifyAndUnpack(_cryptographicImplementation)) { await _eventDispatcher.DispatchEvent( EventSinks.AuthJanitorSystemEvents.AnomalousEventOccurred, nameof(AuthJanitorService.ProcessMessageAsync), "Failed to verify agent message! This may indicate agent compromise."); throw new Exception("Message verification failed!"); } if (envelope.MessageObject is AgentProviderCommandMessage) { var message = envelope.MessageObject as AgentProviderCommandMessage; await ExecuteAsync(message.ValidPeriod, periodicUpdateFunction, message.Providers.ToArray()); } if (envelope.MessageObject is AgentProviderStatusMessage) { var message = envelope.MessageObject as AgentProviderStatusMessage; var taskId = Guid.Parse(message.State); await periodicUpdateFunction(message.WorkflowActionCollection); } }
public async Task <AccessTokenCredential> GetTokenCredentialAsync(Guid taskId, CancellationToken cancellationToken) { var task = await _rekeyingTasks.GetOne(taskId, cancellationToken); // Retrieve credentials for Task AccessTokenCredential credential = null; try { if (task.ConfirmationType == TaskConfirmationStrategies.AdminCachesSignOff) { if (task.PersistedCredentialId == default) { throw new KeyNotFoundException("Cached sign-off is preferred but no credentials were persisted!"); } if (_secureStorageProvider == null) { throw new NotSupportedException("Must register an ISecureStorageProvider"); } credential = await _secureStorageProvider.Retrieve <AccessTokenCredential>(task.PersistedCredentialId); } else if (task.ConfirmationType == TaskConfirmationStrategies.AdminSignsOffJustInTime) { credential = await _identityService.GetAccessTokenOnBehalfOfCurrentUserAsync(); } else if (task.ConfirmationType.UsesServicePrincipal()) { credential = await _identityService.GetAccessTokenForApplicationAsync(); } else { throw new NotSupportedException("No Access Tokens could be generated for this Task!"); } if (credential == null || string.IsNullOrEmpty(credential.AccessToken)) { throw new InvalidOperationException("Access Token was found, but was blank or invalid"); } credential.DisplayUserName = credential.Username; credential.DisplayEmail = credential.Username; if (task.ConfirmationType.UsesOBOTokens()) { if (!string.IsNullOrEmpty(task.PersistedCredentialUser)) { credential.DisplayUserName = task.PersistedCredentialUser; } else { credential.DisplayUserName = _identityService.UserName; credential.DisplayEmail = _identityService.UserEmail; } } return(credential); } catch (Exception ex) { await _eventDispatcherService.DispatchEvent(AuthJanitorSystemEvents.RotationTaskAttemptFailed, nameof(TaskExecutionMetaService.ExecuteTask), task); throw ex; } }