private async Task <ResourceResponse> ProcessActivityAsync(ClaimsIdentity claimsIdentity, string conversationId, string replyToActivityId, Activity activity, CancellationToken cancellationToken) { SkillConversationReference skillConversationReference; try { skillConversationReference = await _conversationIdFactory.GetSkillConversationReferenceAsync(conversationId, cancellationToken).ConfigureAwait(false); } catch (NotImplementedException) { // Attempt to get SkillConversationReference using deprecated method. // this catch should be removed once we remove the deprecated method. // We need to use the deprecated method for backward compatibility. #pragma warning disable 618 var conversationReference = await _conversationIdFactory.GetConversationReferenceAsync(conversationId, cancellationToken).ConfigureAwait(false); #pragma warning restore 618 skillConversationReference = new SkillConversationReference { ConversationReference = conversationReference, OAuthScope = ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope }; } if (skillConversationReference == null) { throw new KeyNotFoundException(); } ResourceResponse resourceResponse = null; var callback = new BotCallbackHandler(async(turnContext, ct) => { turnContext.TurnState.Add(SkillConversationReferenceKey, skillConversationReference); activity.ApplyConversationReference(skillConversationReference.ConversationReference); turnContext.Activity.Id = replyToActivityId; turnContext.Activity.CallerId = $"{CallerIdConstants.BotToBotPrefix}{JwtTokenValidation.GetAppIdFromClaims(claimsIdentity.Claims)}"; switch (activity.Type) { case ActivityTypes.EndOfConversation: await _conversationIdFactory.DeleteConversationReferenceAsync(conversationId, cancellationToken).ConfigureAwait(false); ApplyEoCToTurnContextActivity(turnContext, activity); await _bot.OnTurnAsync(turnContext, ct).ConfigureAwait(false); break; case ActivityTypes.Event: ApplyEventToTurnContextActivity(turnContext, activity); await _bot.OnTurnAsync(turnContext, ct).ConfigureAwait(false); break; default: resourceResponse = await turnContext.SendActivityAsync(activity, cancellationToken).ConfigureAwait(false); break; } }); await _adapter.ContinueConversationAsync(claimsIdentity, skillConversationReference.ConversationReference, skillConversationReference.OAuthScope, callback, cancellationToken).ConfigureAwait(false); return(resourceResponse ?? new ResourceResponse(Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture))); }
/// <summary> /// Initializes a new instance of the <see cref="SkillHandler"/> class, /// using a credential provider. /// </summary> /// <param name="adapter">An instance of the <see cref="BotAdapter"/> that will handle the request.</param> /// <param name="bot">The <see cref="IBot"/> instance.</param> /// <param name="conversationIdFactory">A <see cref="SkillConversationIdFactoryBase"/> to unpack the conversation ID and map it to the calling bot.</param> /// <param name="credentialProvider">The credential provider.</param> /// <param name="authConfig">The authentication configuration.</param> /// <param name="channelProvider">The channel provider.</param> /// <param name="logger">The ILogger implementation this adapter should use.</param> /// <exception cref="ArgumentNullException">throw ArgumentNullException.</exception> /// <remarks>Use a <see cref="MiddlewareSet"/> object to add multiple middleware /// components in the constructor. Use the Use(<see cref="IMiddleware"/>) method to /// add additional middleware to the adapter after construction. /// </remarks> public SkillHandler( BotAdapter adapter, IBot bot, SkillConversationIdFactoryBase conversationIdFactory, ICredentialProvider credentialProvider, AuthenticationConfiguration authConfig, IChannelProvider channelProvider = null, ILogger logger = null) : base(credentialProvider, authConfig, channelProvider) { if (adapter == null) { throw new ArgumentNullException(nameof(adapter)); } if (bot == null) { throw new ArgumentNullException(nameof(bot)); } if (conversationIdFactory == null) { throw new ArgumentNullException(nameof(conversationIdFactory)); } _inner = new SkillHandlerImpl( SkillConversationReferenceKey, adapter, bot, conversationIdFactory, () => ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope, logger ?? NullLogger.Instance); }
private async Task <SkillConversationReference> GetSkillConversationReferenceAsync(string conversationId, CancellationToken cancellationToken) { SkillConversationReference skillConversationReference; try { skillConversationReference = await _conversationIdFactory.GetSkillConversationReferenceAsync(conversationId, cancellationToken).ConfigureAwait(false); } catch (NotImplementedException) { _logger.LogWarning("Got NotImplementedException when trying to call GetSkillConversationReferenceAsync() on the ConversationIdFactory, attempting to use deprecated GetConversationReferenceAsync() method instead."); // Attempt to get SkillConversationReference using deprecated method. // this catch should be removed once we remove the deprecated method. // We need to use the deprecated method for backward compatibility. #pragma warning disable 618 var conversationReference = await _conversationIdFactory.GetConversationReferenceAsync(conversationId, cancellationToken).ConfigureAwait(false); #pragma warning restore 618 skillConversationReference = new SkillConversationReference { ConversationReference = conversationReference, OAuthScope = ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope }; } if (skillConversationReference == null) { _logger.LogError($"Unable to get skill conversation reference for conversationId {conversationId}."); throw new KeyNotFoundException(); } return(skillConversationReference); }
/// <summary> /// Creates a streaming specific connector client. /// </summary> private IConnectorClient CreateStreamingConnectorClient(Activity activity, StreamingRequestHandler requestHandler) { var emptyCredentials = (ChannelProvider != null && ChannelProvider.IsGovernment()) ? MicrosoftGovernmentAppCredentials.Empty : MicrosoftAppCredentials.Empty; var streamingClient = new StreamingHttpClient(requestHandler, Logger); var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), emptyCredentials, customHttpClient: streamingClient); return(connectorClient); }
/// <summary> /// Creates a streaming specific connector client. /// </summary> private IConnectorClient CreateStreamingConnectorClient(Activity activity, StreamingRequestHandler requestHandler) { var emptyCredentials = (ChannelProvider != null && ChannelProvider.IsGovernment()) ? MicrosoftGovernmentAppCredentials.Empty : MicrosoftAppCredentials.Empty; #pragma warning disable CA2000 // Dispose objects before losing scope (We need to make ConnectorClient disposable to fix this, ignoring it for now) var streamingClient = new StreamingHttpClient(requestHandler, Logger); #pragma warning restore CA2000 // Dispose objects before losing scope var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl), emptyCredentials, customHttpClient: streamingClient); return(connectorClient); }
/// <summary> /// Get the audience for the WebSocket connection from the authenticated ClaimsIdentity. /// </summary> /// <remarks> /// Setting the Audience on the StreamingRequestHandler enables the bot to call skills and correctly forward responses from the skill to the next recipient. /// i.e. the participant at the other end of the WebSocket connection. /// </remarks> /// <param name="claimsIdentity">ClaimsIdentity for authenticated caller.</param> private string GetAudience(ClaimsIdentity claimsIdentity) { if (claimsIdentity.AuthenticationType != AuthenticationConstants.AnonymousAuthType) { var audience = ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope; if (SkillValidation.IsSkillClaim(claimsIdentity.Claims)) { audience = JwtTokenValidation.GetAppIdFromClaims(claimsIdentity.Claims); } return(audience); } return(null); }
public async Task <InvokeResponse <T> > PostActivityAsync <T>(string fromBotId, BotFrameworkSkill toSkill, Uri callbackUrl, Activity activity, CancellationToken cancellationToken) { var originatingAudience = ChannelProvider != null && ChannelProvider.IsGovernment() ? GovernmentAuthenticationConstants.ToChannelFromBotOAuthScope : AuthenticationConstants.ToChannelFromBotOAuthScope; return(await PostActivityAsync <T>(originatingAudience, fromBotId, toSkill, callbackUrl, activity, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Logic to build an <see cref="AppCredentials"/> object to be used to acquire tokens /// for this HttpClient. /// </summary> /// <param name="appId">The application id.</param> /// <param name="oAuthScope">The optional OAuth scope.</param> /// <returns>The app credentials to be used to acquire tokens.</returns> protected virtual async Task <AppCredentials> BuildCredentialsAsync(string appId, string oAuthScope = null) { var appPassword = await CredentialProvider.GetAppPasswordAsync(appId).ConfigureAwait(false); return(ChannelProvider != null && ChannelProvider.IsGovernment() ? new MicrosoftGovernmentAppCredentials(appId, appPassword, HttpClient, Logger, oAuthScope) : new MicrosoftAppCredentials(appId, appPassword, HttpClient, Logger, oAuthScope)); }