/// <summary> /// CreateConversation /// </summary> /// Create a new Conversation. /// /// POST to this method with a /// * Bot being the bot creating the conversation /// * IsGroup set to true if this is not a direct message (default is false) /// * Members array contining the members you want to have be in the /// conversation. /// /// The return value is a ResourceResponse which contains a conversation id /// which is suitable for use /// in the message payload and REST API uris. /// /// Most channels only support the semantics of bots initiating a direct /// message conversation. An example of how to do that would be: /// /// ``` /// var resource = await connector.conversations.CreateConversation(new /// ConversationParameters(){ Bot = bot, members = new ChannelAccount[] { new /// ChannelAccount("user1") } ); /// await connect.Conversations.SendToConversationAsync(resource.Id, new /// Activity() ... ) ; /// /// ``` /// <param name='operations'> /// The operations group for this extension method. /// </param> /// <param name='parameters'> /// Parameters to create the conversation from /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public static async Task <ConversationResourceResponse> CreateConversationAsync(this IConversations operations, ConversationParameters parameters, CancellationToken cancellationToken = default(CancellationToken)) { using (var _result = await operations.CreateConversationWithHttpMessagesAsync(parameters, null, cancellationToken).ConfigureAwait(false)) { var res = await _result.HandleErrorAsync <ConversationResourceResponse>().ConfigureAwait(false); MicrosoftAppCredentials.TrustServiceUrl(res.ServiceUrl); return(res); } }
/// <summary> /// Create a new direct conversation between a bot and a user /// </summary> /// <param name='operations'>The operations group for this extension method.</param> /// <param name='botAddress'>Bot to create conversation from</param> /// <param name='userAddress'>User to create conversation with</param> /// <param name="activity">(OPTIONAL) initial message to send to the new conversation</param> /// <param name='cancellationToken'>The cancellation token</param> public static async Task <ConversationResourceResponse> CreateDirectConversationAsync(this IConversations operations, string botAddress, string userAddress, Activity activity = null, CancellationToken cancellationToken = default(CancellationToken)) { var _result = await operations.CreateConversationWithHttpMessagesAsync(GetDirectParameters(botAddress, userAddress, activity), null, cancellationToken).ConfigureAwait(false); var res = _result.Body; if (res.ServiceUrl != null) { MicrosoftAppCredentials.TrustServiceUrl(res.ServiceUrl); } return(res); }
public async override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { if (!await Options.IsAuthenticationDisabledAsync()) { var activities = GetActivities(context); foreach (var activity in activities) { MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl); } } await next(); }
/// <summary> /// Authenticates the incoming request and add the <see cref="IActivity.ServiceUrl"/> for each /// activities to <see cref="MicrosoftAppCredentials.TrustedHostNames"/> if the request is authenticated. /// </summary> /// <param name="request"> The request that should be authenticated.</param> /// <param name="activities"> The activities extracted from request.</param> /// <param name="token"> The cancellation token.</param> /// <returns></returns> public async Task <bool> TryAuthenticateAsync(HttpRequestMessage request, IEnumerable <IActivity> activities, CancellationToken token) { var identityToken = await this.TryAuthenticateAsync(request, token); if (identityToken.Authenticated) { foreach (var activity in activities) { MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl); } } return(identityToken.Authenticated); }
public async Task SendEmulateOAuthCardsAsync(bool emulateOAuthCards) { bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("emulateOAuthCards", emulateOAuthCards); ServiceClientTracing.Enter(_invocationId, this, "SendEmulateOAuthCards", tracingParameters); } var cancellationToken = default(CancellationToken); // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/usertoken/emulateOAuthCards?emulate={emulate}").ToString(); _url = _url.Replace("{emulate}", emulateOAuthCards.ToString()); // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("POST"); _httpRequest.RequestUri = new System.Uri(_url); MicrosoftAppCredentials.TrustServiceUrl(_url); // Set Credentials if (Client.Credentials != null) { await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } }
/// <summary> /// Send a dummy OAuth card when the bot is being used on the Emulator for testing without fetching a real token. /// </summary> /// <param name="emulateOAuthCards">Indicates whether the Emulator should emulate the OAuth card.</param> /// <returns>A task that represents the work queued to execute.</returns> public async Task SendEmulateOAuthCardsAsync(bool emulateOAuthCards) { bool shouldTrace = ServiceClientTracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("emulateOAuthCards", emulateOAuthCards); ServiceClientTracing.Enter(invocationId, this, "SendEmulateOAuthCards", tracingParameters); } var cancellationToken = default(CancellationToken); // Construct URL var tokenUrl = new Uri(new Uri(_uri + (_uri.EndsWith("/") ? "" : "/")), "api/usertoken/emulateOAuthCards?emulate={emulate}").ToString(); tokenUrl = tokenUrl.Replace("{emulate}", emulateOAuthCards.ToString()); // Create HTTP transport objects var httpRequest = new HttpRequestMessage(); HttpResponseMessage httpResponse = null; httpRequest.Method = new HttpMethod("POST"); httpRequest.RequestUri = new Uri(tokenUrl); // add botframework api service url to the list of trusted service url's for these app credentials. MicrosoftAppCredentials.TrustServiceUrl(tokenUrl); // Set Credentials if (_client.Credentials != null) { await _client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } if (shouldTrace) { ServiceClientTracing.SendRequest(invocationId, httpRequest); } httpResponse = await _client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { ServiceClientTracing.ReceiveResponse(invocationId, httpResponse); } }
private void TrustServiceUrls(IdentityToken identityToken, IEnumerable <IActivity> activities) { // add the service url to the list of trusted urls only if the JwtToken // is valid and identity is not null if (identityToken.Authenticated && identityToken.Identity != null) { if (activities.Any()) { foreach (var activity in activities) { MicrosoftAppCredentials.TrustServiceUrl(activity?.ServiceUrl); } } else { } } }
internal void TrustServiceUrls(IdentityToken identityToken, IEnumerable <IActivity> activities) { // add the service url to the list of trusted urls only if the JwtToken // is valid and identity is not null if (identityToken.Authenticated && identityToken.Identity != null) { if (activities.Any()) { foreach (var activity in activities) { MicrosoftAppCredentials.TrustServiceUrl(activity?.ServiceUrl); } } else { #if NET45 Trace.TraceWarning("No ServiceUrls added to trusted list"); #endif } } }
public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken) { var provider = this.GetCredentialProvider(); var botAuthenticator = new BotAuthenticator(provider, OpenIdConfigurationUrl, DisableEmulatorTokens); var identityToken = await botAuthenticator.TryAuthenticateAsync(actionContext.Request, cancellationToken); // the request is not authenticated, fail with 401. if (!identityToken.Authenticated) { actionContext.Response = GenerateUnauthorizedResponse(actionContext.Request); return; } // authenticated but no identity, auth is disabled; if (identityToken.Authenticated && identityToken.Identity == null) { await base.OnActionExecutingAsync(actionContext, cancellationToken); return; } // trust the service url in activities var activities = GetActivities(actionContext); if (activities.Any()) { foreach (var activity in activities) { MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl); } } else { Trace.TraceWarning("No ServiceUrls added to trusted list"); } await base.OnActionExecutingAsync(actionContext, cancellationToken); }
public async Task <bool> SignOutUserAsync(string userId, string connectionName, CancellationToken cancellationToken = default(CancellationToken)) { if (connectionName == null) { throw new ValidationException(ValidationRules.CannotBeNull, "connectionName"); } if (userId == null) { throw new ValidationException(ValidationRules.CannotBeNull, "userId"); } bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("userId", userId); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(_invocationId, this, "SignOutUserAsync", tracingParameters); } // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/usertoken/SignOut?&userId={userId}&connectionName={connectionName}").ToString(); _url = _url.Replace("{connectionName}", System.Uri.EscapeDataString(connectionName)); _url = _url.Replace("{userId}", System.Uri.EscapeDataString(userId)); MicrosoftAppCredentials.TrustServiceUrl(_url); // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("DELETE"); _httpRequest.RequestUri = new System.Uri(_url); // Set Credentials if (Client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } HttpStatusCode _statusCode = _httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (_statusCode == HttpStatusCode.OK) { return(true); } else { return(false); } }
public async Task <string> GetSignInLinkAsync(IActivity activity, string connectionName, CancellationToken cancellationToken = default(CancellationToken)) { if (connectionName == null) { throw new ValidationException(ValidationRules.CannotBeNull, "connectionName"); } if (activity == null) { throw new ValidationException(ValidationRules.CannotBeNull, "activity"); } bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("activity", activity); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(_invocationId, this, "GetSignInLinkAsync", tracingParameters); } var tokenExchangeState = new TokenExchangeState() { ConnectionName = connectionName, Conversation = new ConversationReference() { ActivityId = activity.Id, Bot = activity.Recipient, // Activity is from the user to the bot ChannelId = activity.ChannelId, Conversation = activity.Conversation, ServiceUrl = activity.ServiceUrl, User = activity.From }, MsAppId = (Client.Credentials as MicrosoftAppCredentials)?.MicrosoftAppId }; var serializedState = JsonConvert.SerializeObject(tokenExchangeState); var encodedState = Encoding.UTF8.GetBytes(serializedState); var finalState = Convert.ToBase64String(encodedState); // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/botsignin/getsigninurl?&state={state}").ToString(); _url = _url.Replace("{state}", finalState); MicrosoftAppCredentials.TrustServiceUrl(_url); // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("GET"); _httpRequest.RequestUri = new System.Uri(_url); // Set Credentials if (Client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } HttpStatusCode _statusCode = _httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (_statusCode == HttpStatusCode.OK) { var link = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); return(link); } return(String.Empty); }
/// <summary> /// Gets a user token for a given user and connection. /// </summary> /// <param name="userId">The user's ID.</param> /// <param name="connectionName">Name of the auth connection to use.</param> /// <param name="magicCode">The user entered code to validate.</param> /// <param name="customHeaders"></param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>If the task completes successfully, the <see cref="TokenResponse"/> contains the user token.</remarks> public async Task <TokenResponse> GetUserTokenAsync(string userId, string connectionName, string magicCode, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(userId)) { throw new ArgumentNullException(nameof(userId)); } if (string.IsNullOrWhiteSpace(connectionName)) { throw new ArgumentNullException(nameof(connectionName)); } // Tracing bool shouldTrace = ServiceClientTracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("userId", userId); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("magicCode", magicCode); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(invocationId, this, "GetUserTokenAsync", tracingParameters); } // Construct URL var tokenUrl = new Uri(new Uri(_uri + (_uri.EndsWith("/") ? "" : "/")), "api/usertoken/GetToken?userId={userId}&connectionName={connectionName}{magicCodeParam}").ToString(); tokenUrl = tokenUrl.Replace("{connectionName}", Uri.EscapeDataString(connectionName)); tokenUrl = tokenUrl.Replace("{userId}", Uri.EscapeDataString(userId)); if (!string.IsNullOrEmpty(magicCode)) { tokenUrl = tokenUrl.Replace("{magicCodeParam}", $"&code={Uri.EscapeDataString(magicCode)}"); } else { tokenUrl = tokenUrl.Replace("{magicCodeParam}", String.Empty); } // Create HTTP transport objects var httpRequest = new HttpRequestMessage(); HttpResponseMessage httpResponse = null; httpRequest.Method = new HttpMethod("GET"); httpRequest.RequestUri = new Uri(tokenUrl); // add botframework api service url to the list of trusted service url's for these app credentials. MicrosoftAppCredentials.TrustServiceUrl(tokenUrl); // Set Credentials if (_client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await _client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (shouldTrace) { ServiceClientTracing.SendRequest(invocationId, httpRequest); } httpResponse = await _client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { ServiceClientTracing.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode statusCode = httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (statusCode == HttpStatusCode.OK) { string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); try { var tokenResponse = Rest.Serialization.SafeJsonConvert.DeserializeObject <TokenResponse>(responseContent); return(tokenResponse); } catch (JsonException) { // ignore json exception and return null httpRequest.Dispose(); if (httpResponse != null) { httpResponse.Dispose(); } return(null); } } else if (statusCode == HttpStatusCode.NotFound) { return(null); } else { return(null); } }
/// <summary> /// Get the raw signin link to be sent to the user for signin for a connection name. /// </summary> /// <param name="activity">An activity from the user to the bot.</param> /// <param name="connectionName">Name of the auth connection to get a link for.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>If the task completes successfully and the call to the OAuth client is successful, /// the result contains the signin link.</remarks> public async Task <string> GetSignInLinkAsync(IActivity activity, string connectionName, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(connectionName)) { throw new ArgumentNullException(nameof(connectionName)); } if (activity == null) { throw new ArgumentNullException(nameof(activity)); } bool shouldTrace = ServiceClientTracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("activity", activity); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(invocationId, this, "GetSignInLinkAsync", tracingParameters); } var tokenExchangeState = new TokenExchangeState() { ConnectionName = connectionName, Conversation = new ConversationReference() { ActivityId = activity.Id, Bot = activity.Recipient, // Activity is from the user to the bot ChannelId = activity.ChannelId, Conversation = activity.Conversation, ServiceUrl = activity.ServiceUrl, User = activity.From }, MsAppId = (_client.Credentials as MicrosoftAppCredentials)?.MicrosoftAppId }; var serializedState = JsonConvert.SerializeObject(tokenExchangeState); var encodedState = Encoding.UTF8.GetBytes(serializedState); var finalState = Convert.ToBase64String(encodedState); // Construct URL var tokenUrl = new Uri(new Uri(_uri + (_uri.EndsWith("/") ? "" : "/")), "api/botsignin/getsigninurl?&state={state}").ToString(); tokenUrl = tokenUrl.Replace("{state}", finalState); // add botframework api service url to the list of trusted service url's for these app credentials. MicrosoftAppCredentials.TrustServiceUrl(tokenUrl); // Create HTTP transport objects var httpRequest = new HttpRequestMessage(); HttpResponseMessage httpResponse = null; httpRequest.Method = new HttpMethod("GET"); httpRequest.RequestUri = new Uri(tokenUrl); // Set Credentials if (_client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await _client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (shouldTrace) { ServiceClientTracing.SendRequest(invocationId, httpRequest); } httpResponse = await _client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { ServiceClientTracing.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode statusCode = httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (statusCode == HttpStatusCode.OK) { var link = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); return(link); } return(String.Empty); }
/// <summary> /// Signs the user out of a connection. /// </summary> /// <param name="userId">The user's ID.</param> /// <param name="connectionName">Name of the auth connection to sign out of.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>If the task completes successfully, the response indicates whether the call to /// sign the user out was successful.</remarks> public async Task <bool> SignOutUserAsync(string userId, string connectionName, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } if (string.IsNullOrEmpty(connectionName)) { throw new ArgumentNullException(nameof(connectionName)); } bool shouldTrace = ServiceClientTracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("userId", userId); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(invocationId, this, "SignOutUserAsync", tracingParameters); } // Construct URL var tokenUrl = new Uri(new Uri(_uri + (_uri.EndsWith("/") ? "" : "/")), "api/usertoken/SignOut?&userId={userId}&connectionName={connectionName}").ToString(); tokenUrl = tokenUrl.Replace("{connectionName}", Uri.EscapeDataString(connectionName)); tokenUrl = tokenUrl.Replace("{userId}", Uri.EscapeDataString(userId)); // add botframework api service url to the list of trusted service url's for these app credentials. MicrosoftAppCredentials.TrustServiceUrl(tokenUrl); // Create HTTP transport objects var httpRequest = new HttpRequestMessage(); HttpResponseMessage httpResponse = null; httpRequest.Method = new HttpMethod("DELETE"); httpRequest.RequestUri = new Uri(tokenUrl); // Set Credentials if (_client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await _client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (shouldTrace) { ServiceClientTracing.SendRequest(invocationId, httpRequest); } httpResponse = await _client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { ServiceClientTracing.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode _statusCode = httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (_statusCode == HttpStatusCode.OK) { return(true); } else { return(false); } }
/// <summary> /// Get the raw signin link to be sent to the user for signin for a connection name. /// </summary> /// <param name="state">A serialized and encoded parameter of a TokenExchangeState parameter.</param> /// <param name="finalRedirect">The endpoint URL for the final page of a succesful login attempt.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>If the task completes successfully and the call to the OAuth client is successful, /// the result contains the signin link.</remarks> public async Task <string> GetSignInLinkAsync(string state, string finalRedirect = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrEmpty(state)) { throw new ArgumentNullException(nameof(state)); } bool shouldTrace = ServiceClientTracing.IsEnabled; string invocationId = null; if (shouldTrace) { invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("state", state); tracingParameters.Add("finalRedirect", finalRedirect); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(invocationId, this, "GetSignInLinkAsync", tracingParameters); } // Construct URL var tokenUrl = new Uri(new Uri(_uri + (_uri.EndsWith("/") ? "" : "/")), "api/botsignin/getsigninurl?&state={state}{finalRedirectParam}").ToString(); tokenUrl = tokenUrl.Replace("{state}", state); tokenUrl = tokenUrl.Replace("{finalRedirectParam}", string.IsNullOrEmpty(finalRedirect) ? String.Empty : $"&finalRedirect={Uri.EscapeDataString(finalRedirect)}"); // add botframework api service url to the list of trusted service url's for these app credentials. MicrosoftAppCredentials.TrustServiceUrl(tokenUrl); // Create HTTP transport objects var httpRequest = new HttpRequestMessage(); HttpResponseMessage httpResponse = null; httpRequest.Method = new HttpMethod("GET"); httpRequest.RequestUri = new Uri(tokenUrl); // Set Credentials if (_client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await _client.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (shouldTrace) { ServiceClientTracing.SendRequest(invocationId, httpRequest); } httpResponse = await _client.HttpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); if (shouldTrace) { ServiceClientTracing.ReceiveResponse(invocationId, httpResponse); } HttpStatusCode statusCode = httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if (statusCode == HttpStatusCode.OK) { var link = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); return(link); } return(String.Empty); }
public override async Task OnActionExecutionAsync(ActionExecutingContext actionContext, ActionExecutionDelegate next) { MicrosoftAppId = MicrosoftAppId ?? _configuration[MicrosoftAppIdSettingName]; if (Debugger.IsAttached && String.IsNullOrEmpty(MicrosoftAppId)) { // then auth is disabled return; } var tokenExtractor = new JwtTokenExtractor(JwtConfig.GetToBotFromChannelTokenValidationParameters(MicrosoftAppId), OpenIdConfigurationUrl); var frameRequestHeaders = actionContext.HttpContext.Request.Headers as FrameRequestHeaders; if (frameRequestHeaders == null) { //TODO: ... throw new NotSupportedException("frameRequestHeaders is null"); } //TODO: Надо проверить! var identity = await tokenExtractor.GetIdentityAsync(frameRequestHeaders.HeaderAuthorization.FirstOrDefault()); // No identity? If we're allowed to, fall back to MSA // This code path is used by the emulator if (identity == null && !DisableSelfIssuedTokens) { tokenExtractor = new JwtTokenExtractor(JwtConfig.ToBotFromMSATokenValidationParameters, JwtConfig.ToBotFromMSAOpenIdMetadataUrl); //TODO: Надо проверить! identity = await tokenExtractor.GetIdentityAsync(frameRequestHeaders.HeaderAuthorization.FirstOrDefault()); // Check to make sure the app ID in the token is ours if (identity != null) { // If it doesn't match, throw away the identity if (tokenExtractor.GetBotIdFromClaimsIdentity(identity) != MicrosoftAppId) { identity = null; } } } // Still no identity? Fail out. if (identity == null) { tokenExtractor.GenerateUnauthorizedResponse(actionContext); return; } var activity = actionContext.ActionArguments.Select(t => t.Value).OfType <Activity>().FirstOrDefault(); if (activity != null) { MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl); } else { // No model binding to activity check if we can find JObject or JArray var obj = actionContext.ActionArguments.Where(t => t.Value is JObject || t.Value is JArray).Select(t => t.Value).FirstOrDefault(); if (obj != null) { Activity[] activities = (obj is JObject) ? new Activity[] { ((JObject)obj).ToObject <Activity>() } : ((JArray)obj).ToObject <Activity[]>(); foreach (var jActivity in activities) { if (!string.IsNullOrEmpty(jActivity.ServiceUrl)) { MicrosoftAppCredentials.TrustServiceUrl(jActivity.ServiceUrl); } } } else { //LOG: Trace.TraceWarning("No activity in the Bot Authentication Action Arguments"); } } //Thread.CurrentPrincipal = new ClaimsPrincipal(identity); // Inside of ASP.NET this is required if (_httpContextAccessor.HttpContext != null) { _httpContextAccessor.HttpContext.User = new ClaimsPrincipal(identity); } await base.OnActionExecutionAsync(actionContext, next); }
public async Task <TokenResponse> GetUserTokenAsync(string userId, string connectionName, string magicCode, CancellationToken cancellationToken = default(CancellationToken)) { if (connectionName == null) { throw new ValidationException(ValidationRules.CannotBeNull, "connectionName"); } if (userId == null) { throw new ValidationException(ValidationRules.CannotBeNull, "userId"); } bool _shouldTrace = ServiceClientTracing.IsEnabled; string _invocationId = null; if (_shouldTrace) { _invocationId = ServiceClientTracing.NextInvocationId.ToString(); Dictionary <string, object> tracingParameters = new Dictionary <string, object>(); tracingParameters.Add("userId", userId); tracingParameters.Add("connectionName", connectionName); tracingParameters.Add("magicCode", magicCode); tracingParameters.Add("cancellationToken", cancellationToken); ServiceClientTracing.Enter(_invocationId, this, "GetUserTokenAsync", tracingParameters); } // Construct URL var _baseUrl = Client.BaseUri.AbsoluteUri; var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "api/usertoken/GetToken?userId={userId}&connectionName={connectionName}{magicCodeParam}").ToString(); _url = _url.Replace("{connectionName}", System.Uri.EscapeDataString(connectionName)); _url = _url.Replace("{userId}", System.Uri.EscapeDataString(userId)); if (!string.IsNullOrEmpty(magicCode)) { _url = _url.Replace("{magicCodeParam}", $"&code={System.Uri.EscapeDataString(magicCode)}"); } else { _url = _url.Replace("{magicCodeParam}", String.Empty); } // Create HTTP transport objects var _httpRequest = new HttpRequestMessage(); HttpResponseMessage _httpResponse = null; _httpRequest.Method = new HttpMethod("GET"); _httpRequest.RequestUri = new System.Uri(_url); MicrosoftAppCredentials.TrustServiceUrl(_url); // Set Credentials if (Client.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false); } cancellationToken.ThrowIfCancellationRequested(); if (_shouldTrace) { ServiceClientTracing.SendRequest(_invocationId, _httpRequest); } _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); if (_shouldTrace) { ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); } HttpStatusCode _statusCode = _httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); string _responseContent = null; if (_statusCode == HttpStatusCode.OK) { _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); try { var tokenResponse = Rest.Serialization.SafeJsonConvert.DeserializeObject <TokenResponse>(_responseContent); return(tokenResponse); } catch (JsonException) { _httpRequest.Dispose(); if (_httpResponse != null) { _httpResponse.Dispose(); } return(null); } } else if (_statusCode == HttpStatusCode.NotFound) { return(null); } else { return(null); } }