Exemple #1
0
        public IServiceTransport CreateConnection(OpenConnectionMessage message, IServiceConnection serviceConnection)
        {
            var dispatcher = new HubDispatcher(_configuration);

            dispatcher.Initialize(_configuration.Resolver);

            var responseStream = new MemoryStream();
            var hostContext    = GetHostContext(message, responseStream, serviceConnection);

            if (dispatcher.Authorize(hostContext.Request))
            {
                // ProcessRequest checks if the connectionToken matches "{connectionid}:{userName}" format with context.User
                _ = dispatcher.ProcessRequest(hostContext);

                // TODO: check for errors written to the response
                if (hostContext.Response.StatusCode != 200)
                {
                    Log.ProcessRequestError(_logger, message.ConnectionId, hostContext.Request.QueryString.ToString());
                    Debug.Fail("Response StatusCode is " + hostContext.Response.StatusCode);
                    var errorResponse = GetContentAndDispose(responseStream);
                    throw new InvalidOperationException(errorResponse);
                }

                return((AzureTransport)hostContext.Environment[AspNetConstants.Context.AzureSignalRTransportKey]);
            }

            // This happens when hub is not found
            Debug.Fail("Unauthorized");
            throw new InvalidOperationException("Unable to authorize request");
        }
        public void DuplicateHubNamesThrows()
        {
            // Arrange
            var mockHub        = new Mock <IHub>();
            var mockHubManager = new Mock <IHubManager>();

            mockHubManager.Setup(m => m.GetHub("foo")).Returns(new HubDescriptor {
                Name = "foo", HubType = mockHub.Object.GetType()
            });

            var serviceProvider = new ServiceCollection()
                                  .AddOptions()
                                  .AddHosting()
                                  .AddDataProtection()
                                  .AddSignalR()
                                  .AddInstance <IHubManager>(mockHubManager.Object)
                                  .BuildServiceProvider();

            var dispatcher  = new HubDispatcher(serviceProvider.GetRequiredService <IOptions <SignalROptions> >());
            var testContext = new TestContext("/ignorePath", new Dictionary <string, string>
            {
                { "connectionData", @"[{name: ""foo""}, {name: ""Foo""}]" },
            });

            // Act & Assert
            dispatcher.Initialize(serviceProvider);
            Assert.Throws <InvalidOperationException>(() => dispatcher.Authorize(testContext.MockRequest.Object));
        }
        public void DuplicateHubNamesThrows()
        {
            // Arrange
            var dispatcher = new HubDispatcher(new HubConfiguration());
            var request    = new Mock <IRequest>();
            var qs         = new NameValueCollection();

            request.Setup(m => m.QueryString).Returns(qs);
            qs["connectionData"] = @"[{name: ""foo""}, {name: ""Foo""}]";

            var mockHub        = new Mock <IHub>();
            var mockHubManager = new Mock <IHubManager>();

            mockHubManager.Setup(m => m.GetHub("foo")).Returns(new HubDescriptor {
                Name = "foo", HubType = mockHub.Object.GetType()
            });

            var dr = new DefaultDependencyResolver();

            dr.Register(typeof(IHubManager), () => mockHubManager.Object);

            dispatcher.Initialize(dr, new HostContext(null, null));
            Assert.Throws <InvalidOperationException>(() => dispatcher.Authorize(request.Object));
        }
        public void DuplicateHubNamesThrows()
        {
            // Arrange
            var mockHub = new Mock<IHub>();
            var mockHubManager = new Mock<IHubManager>();
            mockHubManager.Setup(m => m.GetHub("foo")).Returns(new HubDescriptor { Name = "foo", HubType = mockHub.Object.GetType() });

            var serviceProvider = ServiceProviderHelper.CreateServiceProvider(services => services.AddInstance(mockHubManager.Object));

            var dispatcher = new HubDispatcher(serviceProvider.GetRequiredService<IOptions<SignalROptions>>());
            var testContext = new TestContext("/ignorePath", new Dictionary<string, string>
            {
                {"connectionData", @"[{name: ""foo""}, {name: ""Foo""}]"},
            });

            // Act & Assert
            dispatcher.Initialize(serviceProvider);
            Assert.Throws<InvalidOperationException>(() => dispatcher.Authorize(testContext.MockRequest.Object));
        }
        public void DuplicateHubNamesThrows()
        {
            // Arrange
            var dispatcher = new HubDispatcher(new HubConfiguration());
            var request = new Mock<IRequest>();
            var qs = new NameValueCollection();
            request.Setup(m => m.QueryString).Returns(new NameValueCollectionWrapper(qs));
            qs["connectionData"] = @"[{name: ""foo""}, {name: ""Foo""}]";

            var mockHub = new Mock<IHub>();
            var mockHubManager = new Mock<IHubManager>();
            mockHubManager.Setup(m => m.GetHub("foo")).Returns(new HubDescriptor { Name = "foo", HubType = mockHub.Object.GetType() });

            var dr = new DefaultDependencyResolver();
            dr.Register(typeof(IHubManager), () => mockHubManager.Object);

            dispatcher.Initialize(dr);
            Assert.Throws<InvalidOperationException>(() => dispatcher.Authorize(request.Object));
        }
        private Task ProcessNegotiationRequest(IOwinContext owinContext, HostContext context)
        {
            var claims = BuildClaims(owinContext, context.Request);

            var dispatcher = new HubDispatcher(_configuration);

            try
            {
                dispatcher.Initialize(_configuration.Resolver);
                if (!dispatcher.Authorize(context.Request))
                {
                    string error = null;
                    if (context.Request.User != null && context.Request.User.Identity.IsAuthenticated)
                    {
                        // If the user is authenticated and authorize failed then 403
                        error = "Forbidden";
                        context.Response.StatusCode = 403;
                    }
                    else
                    {
                        // If failed to authorize the request then return 401
                        error = "Unauthorized";
                        context.Response.StatusCode = 401;
                    }
                    Log.NegotiateFailed(_logger, error);
                    return(context.Response.End(error));
                }
            }
            catch (Exception e)
            {
                Log.NegotiateFailed(_logger, e.Message);
                context.Response.StatusCode = 500;
                return(context.Response.End(""));
            }

            IServiceEndpointProvider provider;

            try
            {
                // Take the service endpoints for the app
                provider = _endpointManager.GetEndpointProvider(_router.GetNegotiateEndpoint(owinContext, _endpointManager.GetEndpoints(_appName)));

                // When status code changes, we consider the inner router changed the response, then we stop here
                if (context.Response.StatusCode != 200)
                {
                    // Inner handler already write to context.Response, no need to continue with error case
                    return(Task.CompletedTask);
                }

                // Consider it as internal server error when we don't successfully get negotiate response
                if (provider == null)
                {
                    var message = "Unable to get the negotiate endpoint";
                    Log.NegotiateFailed(_logger, message);
                    context.Response.StatusCode = 500;
                    return(context.Response.End(message));
                }
            }
            catch (AzureSignalRNotConnectedException e)
            {
                Log.NegotiateFailed(_logger, e.Message);
                context.Response.StatusCode = 500;
                return(context.Response.End(e.Message));
            }

            // Redirect to Service
            var    clientProtocol = context.Request.QueryString["clientProtocol"];
            string originalPath   = null;
            string queryString    = null;

            // add OriginalPath and QueryString when the clients protocol is higher than 2.0, earlier ASP.NET SignalR clients does not support redirect URL with query parameters
            if (!string.IsNullOrEmpty(clientProtocol) && Version.TryParse(clientProtocol, out var version) && version >= ClientSupportQueryStringVersion)
            {
                var clientRequestId = _connectionRequestIdProvider.GetRequestId();
                if (clientRequestId != null)
                {
                    // remove system preserved query strings
                    queryString = "?" +
                                  string.Join("&",
                                              context.Request.QueryString.Where(s => !PreservedQueryParameters.Contains(s.Key)).Concat(
                                                  new[]
                    {
                        new KeyValuePair <string, string>(
                            Constants.QueryParameter.ConnectionRequestId,
                            clientRequestId)
                    })
                                              .Select(s => $"{Uri.EscapeDataString(s.Key)}={Uri.EscapeDataString(s.Value)}"));
                }

                originalPath = GetOriginalPath(context.Request.LocalPath);
            }

            var url = provider.GetClientEndpoint(null, originalPath, queryString);

            return(GenerateClientAccessTokenAsync(provider, context, url, claims));
        }
Exemple #7
0
        private Task ProcessNegotiationRequest(IOwinContext owinContext, HostContext context)
        {
            string accessToken = null;
            var    claims      = BuildClaims(owinContext, context.Request);

            var dispatcher = new HubDispatcher(_configuration);

            try
            {
                dispatcher.Initialize(_configuration.Resolver);
                if (!dispatcher.Authorize(context.Request))
                {
                    string error = null;
                    if (context.Request.User != null && context.Request.User.Identity.IsAuthenticated)
                    {
                        // If the user is authenticated and authorize failed then 403
                        error = "Forbidden";
                        context.Response.StatusCode = 403;
                    }
                    else
                    {
                        // If failed to authorize the request then return 401
                        error = "Unauthorized";
                        context.Response.StatusCode = 401;
                    }
                    Log.NegotiateFailed(_logger, error);
                    return(context.Response.End(error));
                }
            }
            catch (Exception e)
            {
                Log.NegotiateFailed(_logger, e.Message);
                context.Response.StatusCode = 500;
                return(context.Response.End(""));
            }

            IServiceEndpointProvider provider;

            try
            {
                provider = _endpointManager.GetEndpointProvider(_router.GetNegotiateEndpoint(owinContext, _endpointManager.Endpoints));

                // When status code changes, we consider the inner router changed the response, then we stop here
                if (context.Response.StatusCode != 200)
                {
                    // Inner handler already write to context.Response, no need to continue with error case
                    return(Task.CompletedTask);
                }

                // Consider it as internal server error when we don't successfully get negotiate response
                if (provider == null)
                {
                    var message = "Unable to get the negotiate endpoint";
                    Log.NegotiateFailed(_logger, message);
                    context.Response.StatusCode = 500;
                    return(context.Response.End(message));
                }
            }
            catch (AzureSignalRNotConnectedException e)
            {
                Log.NegotiateFailed(_logger, e.Message);
                context.Response.StatusCode = 500;
                return(context.Response.End(e.Message));
            }

            // Redirect to Service
            // TODO: add OriginalPath and QueryString when the clients support it
            var url = provider.GetClientEndpoint(null, null, null);

            try
            {
                accessToken = provider.GenerateClientAccessToken(null, claims);
            }
            catch (AzureSignalRAccessTokenTooLongException ex)
            {
                Log.NegotiateFailed(_logger, ex.Message);
                context.Response.StatusCode = 413;
                return(context.Response.End(ex.Message));
            }

            return(SendJsonResponse(context, GetRedirectNegotiateResponse(url, accessToken)));
        }