public ConnectorClientFactory(IMessageActivity message, MicrosoftAppCredentials credentials)
        {
            SetField.NotNull(out this.message, nameof(message), message);
            SetField.NotNull(out this.credentials, nameof(credentials), credentials);
            SetField.CheckNull(nameof(message.ServiceUrl), message.ServiceUrl);

            this.serviceUri = new Uri(message.ServiceUrl);
            this.isEmulator = message.ChannelId?.Equals("emulator", StringComparison.OrdinalIgnoreCase);
        }
 public JwtTokenRefresher(MicrosoftAppCredentials credentials)
     : base()
 {
     if (credentials == null)
     {
         throw new ArgumentNullException(nameof(credentials));
     }
     this.credentials = credentials;
 }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
            }
        }
Example #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ConnectorClient"/> class.
 /// </summary>
 /// <param name="baseUri">Base URI for the Connector service.</param>
 /// <param name="credentials">Credentials for the Connector service.</param>
 /// <param name="addJwtTokenRefresher">(DEPRECATED).</param>
 /// <param name="handlers">Optional. The delegating handlers to add to the http client pipeline.</param>
 public ConnectorClient(Uri baseUri, MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(baseUri, credentials, null, addJwtTokenRefresher, handlers)
 {
     AddDefaultRequestHeaders(HttpClient);
 }
Example #6
0
        private static DelegatingHandler[] AddJwtTokenRefresher(DelegatingHandler[] srcHandlers, MicrosoftAppCredentials credentials)
        {
            var handlers = new List <DelegatingHandler>(srcHandlers);

            handlers.Add(new JwtTokenRefresher(credentials));
            return(handlers.ToArray());
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ConnectorClient"/> class.
 /// </summary>
 /// <param name="baseUri">Base URI for the Bot Connector service.</param>
 /// <param name="credentials">Credentials for the Bot Connector service.</param>
 /// <param name="addJwtTokenRefresher">Deprecated, do not use.</param>
 /// <param name="customHttpClient">The HTTP client to use for this connector client.</param>
 /// <param name="handlers">Optional, an array of <see cref="DelegatingHandler"/> objects to
 /// add to the HTTP client pipeline.</param>
 public ConnectorClient(Uri baseUri, MicrosoftAppCredentials credentials, HttpClient customHttpClient, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(baseUri, credentials as ServiceClientCredentials, customHttpClient, addJwtTokenRefresher, handlers)
 {
 }
Example #8
0
        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);
            }
        }
 /// <summary>
 /// Create a new instance of the StateClient class
 /// </summary>
 /// <remarks> This constructor will use http://api.botframework.com as the baseUri</remarks>
 /// <param name="credentials">Credentials for the Connector service</param>
 /// <param name="addJwtTokenRefresher">True, if JwtTokenRefresher should be included; False otherwise.</param>
 /// <param name="handlers">Optional. The delegating handlers to add to the http client pipeline.</param>
 public StateClient(MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(addJwtTokenRefresher ? AddJwtTokenRefresher(handlers, credentials) : handlers)
 {
     this.Credentials = credentials;
 }
Example #10
0
        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);
        }
 /// <summary>
 /// Create a new instance of the ConnectorClient class
 /// </summary>
 /// <param name="baseUri">Base URI for the Connector service</param>
 /// <param name="credentials">Credentials for the Connector service</param>
 /// <param name="addJwtTokenRefresher">True, if JwtTokenRefresher should be included; False otherwise.</param>
 /// <param name="handlers">Optional. The delegating handlers to add to the http client pipeline.</param>
 public ConnectorClient(Uri baseUri, MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(baseUri, addJwtTokenRefresher ? AddJwtTokenRefresher(handlers, credentials) : handlers)
 {
     this.Credentials = credentials;
 }
Example #12
0
 public StateClient(Uri baseUri, MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(baseUri, handlers)
 {
     this.Credentials = credentials;
 }
Example #13
0
 /// <summary>
 /// Create a new instance of the OAuthClient class
 /// </summary>
 /// <remarks> This constructor will use https://state.botframework.com as the baseUri</remarks>
 /// <param name="credentials">Credentials for the Connector service</param>
 /// <param name="addJwtTokenRefresher">(DEPRECATED)</param>
 /// <param name="handlers">Optional. The delegating handlers to add to the http client pipeline.</param>
 public OAuthClient(MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(handlers)
 {
     this.Credentials = credentials;
 }
Example #14
0
        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);
            }
        }
Example #15
0
        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);
        }
Example #16
0
        /// <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>
 /// Create a new instances of the ConnectorClient.
 /// </summary>
 /// <param name="baseUri">Base URI for the Connector service</param>
 /// <param name="credentials">Credentials for the Connector service</param>
 /// <param name="httpClientHandler">The httpClientHandler used by http client</param>
 /// <param name="addJwtTokenRefresher">(DEPRECATED)</param>
 /// <param name="handlers">Optional. The delegating handlers to add to the http client pipeline.</param>
 public ConnectorClient(Uri baseUri, MicrosoftAppCredentials credentials, HttpClientHandler httpClientHandler, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(baseUri, httpClientHandler, handlers)
 {
     this.Credentials = credentials;
 }
        /// <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);
        }
 private static DelegatingHandler[] AddJwtTokenRefresher(DelegatingHandler[] srcHandlers, MicrosoftAppCredentials credentials)
 {
     var handlers = new List<DelegatingHandler>(srcHandlers);
     handlers.Add(new JwtTokenRefresher(credentials));
     return handlers.ToArray();
 }
Example #20
0
 public StateClient(MicrosoftAppCredentials credentials, bool addJwtTokenRefresher = true, params DelegatingHandler[] handlers)
     : this(addJwtTokenRefresher ? AddJwtTokenRefresher(handlers, credentials) : handlers)
 {
     this.Credentials = credentials;
 }