Exemplo n.º 1
0
        /// <summary>
        /// This is called during the routing phase, before the request processing starts
        /// and allows this middleware to alter the behavour of middleware further up the pipeline
        /// </summary>
        public Task RouteRequest(IOwinContext context, Func <Task> next)
        {
            Console.WriteLine("ROUTE: Template page rendering");

            // At this point a real template rendering middleware would figure out from
            // the request which template it is going to render (if any) and from that
            // figure out what's needed in the pipeline - for example does the request
            // have to come fromm a logged on authenticated user with certain permissions
            // For the purpose of this example I am saying any aspx page is a template
            if (context.Request.Method == "GET" &&
                context.Request.Path.HasValue &&
                context.Request.Path.Value.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))
            {
                context.Set("templateToRender", context.Request.Path.Value);

                // Get upstream communication interfaces if available
                var upstreamSession        = context.GetFeature <IUpstreamSession>();
                var upstreamIdentification = context.GetFeature <IUpstreamIdentification>();

                // Tell the session middleware that a session is required for this request
                if (upstreamSession != null)
                {
                    upstreamSession.EstablishSession();
                }

                // Tell the identification middleware that a anonymous users are ok for this request
                if (upstreamIdentification != null)
                {
                    upstreamIdentification.AllowAnonymous = true;
                }

                // No more routing needed, this middleware will process the request
                return(null);
            }

            // Invoke the next middleware in the chain
            return(next());
        }
Exemplo n.º 2
0
        /// <summary>
        /// Constructs an object that will capture the output from downstream middleware.
        /// If multiple middleware components do this, then the response will only be
        /// captured once and they will all share the same output buffer.
        /// </summary>
        /// <param name="owinContext"></param>
        public ResponseCapture(IOwinContext owinContext)
        {
            _prior       = owinContext.GetFeature <IResponseRewriter>();
            _owinContext = owinContext;

            if (_prior == null)
            {
                _originalStream           = owinContext.Response.Body;
                _memoryStream             = new MemoryStream();
                owinContext.Response.Body = _memoryStream;
            }

            owinContext.SetFeature <IResponseRewriter>(this);
        }
        public Task Invoke(IOwinContext context, Func <Task> next)
        {
            var identification = context.GetFeature <IIdentification>() as Identification;

            if (identification == null)
            {
                throw new Exception("Something went terribly wrong");
            }

            if (identification.IsAnonymous && !identification.AllowAnonymous)
            {
                return(Task.Factory.StartNew(() => context.Response.Redirect(SecureHomePage)));
            }

            return(next());
        }
Exemplo n.º 4
0
        public Task RouteRequest(IOwinContext context, Func <Task> next)
        {
            // Get a reference to the session middleware
            var upstreamSession = context.GetFeature <IUpstreamSession>();

            if (upstreamSession == null)
            {
                throw new Exception("The forms identification middleware needs a session to be available");
            }

            // Tell the session middleware that a session must be established for this request
            // because forms identification can not work without it.
            upstreamSession.EstablishSession();

            // Execute the next step in routing the request
            return(next());
        }
        public Task Invoke(IOwinContext context, Func <Task> next)
        {
            if (!string.Equals(context.Request.Method, "GET", StringComparison.OrdinalIgnoreCase))
            {
                return(next());
            }


            if (!string.IsNullOrEmpty(_configuration.DocumentationRootUrl) &&
                context.Request.Path.Value.Equals(_configuration.DocumentationRootUrl, StringComparison.OrdinalIgnoreCase))
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning configuration documentation");
                return(DocumentConfiguration(context));
            }

            var outputCache = context.GetFeature <IUpstreamOutputCache>() as OutputCacheContext;

            if (outputCache == null)
            {
                return(next());
            }

            if (outputCache.CachedContentIsAvailable &&
                outputCache.UseCachedContent)
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning cached response");
                _useCachedContentCount++;
                return(outputCache.SendCachedResponse());
            }

            outputCache.CaptureResponse();
            context.SetFeature <IOutputCache>(outputCache);

            return(next().ContinueWith(t =>
            {
                _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " flushing captured response to actual response stream");
                outputCache.SendCapturedOutput();

                _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " saving response to cache");
                if (outputCache.SaveToCache())
                {
                    _addedToCacheCount++;
                }
            }));
        }
Exemplo n.º 6
0
        public Task RouteRequest(IOwinContext context, Func <Task> next)
        {
            var versionContext = new VersioningContext(context, _configuration, _traceFilter);

            if (context.GetFeature <IRequestRewriter>() == null)
            {
                context.SetFeature <IRequestRewriter>(versionContext);
            }

            context.SetFeature(versionContext);

            versionContext.RemoveVersionNumber(context);
            if (versionContext.IsVersioned)
            {
                _versionedAssetCount++;
            }

            return(next());
        }
        public Task RouteRequest(IOwinContext context, Func <Task> next)
        {
            var configuration = _configuration;

            if (!configuration.Enabled)
            {
                return(next());
            }

            var requestRewriter = context.GetFeature <IRequestRewriter>() ?? new DefaultDocumentContext(context);

            if (!context.Request.Path.HasValue || context.Request.Path.Value == "/" || context.Request.Path.Value == "")
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " identified a request for the default document");
                if (configuration.DefaultPageString.HasValue)
                {
                    _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " modifying request path to '" + configuration.DefaultPageString.Value + "'");
                    context.Request.Path = configuration.DefaultPageString;
                    context.SetFeature(requestRewriter);
                    return(next());
                }
            }

            if (configuration.DefaultFolderPaths != null)
            {
                foreach (var path in configuration.DefaultFolderPaths)
                {
                    if (context.Request.Path.Equals(path.FolderPathString))
                    {
                        var p = path;
                        _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " modifying '" + p.FolderPathString + "' path to '" + p.DefaultPageString.Value + "'");
                        context.Request.Path = path.DefaultPageString;
                        context.SetFeature(requestRewriter);
                        return(next());
                    }
                }
            }

            return(next());
        }
Exemplo n.º 8
0
        Task IRoutingProcessor.RouteRequest(IOwinContext context, Func <Task> next)
        {
            CssFileContext cssFileContext;

            if (!ShouldServeThisFile(context, out cssFileContext))
            {
                return(next());
            }

            context.SetFeature(cssFileContext);
            context.SetFeature <IResponseProducer>(cssFileContext);

            var outputCache = context.GetFeature <InterfacesV1.Upstream.IUpstreamOutputCache>();

            if (outputCache != null && outputCache.CachedContentIsAvailable)
            {
                if (outputCache.TimeInCache.HasValue)
                {
                    var timeSinceFileChanged = DateTime.UtcNow - cssFileContext.PhysicalFile.LastWriteTimeUtc;
                    if (outputCache.TimeInCache.Value > timeSinceFileChanged)
                    {
                        _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " file has changed since output was cached. Output cache will not be used");
                        outputCache.UseCachedContent = false;
                        _fileModificationCount++;
                    }
                    else
                    {
                        _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " instructing output cache to use cached output");
                        outputCache.UseCachedContent = true;
                    }
                }
            }

            _traceFilter.Trace(context, TraceLevel.Information, () =>
                               GetType().Name + " this is a css file request" +
                               (cssFileContext.NeedsCompiling ? " that needs compiling" : ""));

            return(null);
        }
        private void SendPasswordReset(IOwinContext context, Identification identification)
        {
            var form     = context.Request.ReadFormAsync().Result;
            var userName = form["username"];

            if (userName == null)
            {
                SetOutcome(context, identification, "No user name provided");
            }
            else
            {
                var token = _tokenStore.CreateToken("passwordReset", new[] { "ResetPassword" }, userName);

                var session = context.GetFeature <ISession>();
                if (session != null)
                {
                    session.Set("reset-token", token);
                }

                SetOutcome(context, identification, "Password reset token is: " + token);
            }
            GoHome(context, identification);
        }
        public Task Invoke(IOwinContext context, Func <Task> next)
        {
            if (context.Request.Path == _configPage)
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning configuration documentation");
                return(DocumentConfiguration(context));
            }

            string template;

            if (_pageTemplateFile != null && _pageTemplateFile.Exists)
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning template file");
                using (var stream = _pageTemplateFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var reader = new StreamReader(stream, true);
                    template = reader.ReadToEnd();
                }

                var outputCache = context.GetFeature <IOutputCache>();
                if (outputCache != null)
                {
                    outputCache.Priority = CachePriority.Low;
                    _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " setting output cache priority " + outputCache.Priority);
                }
            }
            else
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning embedded template response");
                template = GetEmbeddedResource("template.html");
            }

            _notFoundCount++;
            context.Response.StatusCode   = 404;
            context.Response.ReasonPhrase = "Not Found";
            return(context.Response.WriteAsync(template));
        }
Exemplo n.º 11
0
        public Task Invoke(IOwinContext context, Func <Task> next)
        {
            var output = "User identification for " + context.Request.Uri + ".";

            var identification = context.GetFeature <IIdentification>();

            if (identification != null)
            {
                if (identification.IsAnonymous)
                {
                    output += " Anonymous user.";
                }
                else
                {
                    output += " User " + identification.Identity + ".";
                }

                if (identification.Purposes != null && identification.Purposes.Count > 0)
                {
                    output += " limited to " + string.Join(" and ", identification.Purposes) + ".";
                }

                if (identification.Claims != null && identification.Claims.Count > 0)
                {
                    output += " claiming";
                    foreach (var claim in identification.Claims)
                    {
                        output += " " + claim.Name + "=" + claim.Value + "(" + claim.Status + ")";
                    }
                    output += ".";
                }
            }

            Console.WriteLine(output);

            return(next());
        }
Exemplo n.º 12
0
        int?IUserSegmenter.GetSegmentIndex(IOwinContext owinContext)
        {
            var identification = owinContext.GetFeature <IIdentification>();

            // Not logged in users get the default website behavior

            if (identification == null || identification.IsAnonymous)
            {
                return(null);
            }

            // If the user has visited before use the cookie to segment them

            var segmentCookie = owinContext.Request.Cookies[_cookieName];

            foreach (var segment in _segments)
            {
                if (segmentCookie == segment.Key)
                {
                    return(segment.Index);
                }
            }

            // If the user has not visited before then put them in a random segment

            var randomSegment = _segments[_random.Next(_segments.Length)];

            owinContext.Response.Cookies.Append(
                _cookieName,
                randomSegment.Key,
                new CookieOptions {
                Expires = DateTime.UtcNow.AddDays(7)
            });

            return(randomSegment.Index);
        }
        private void SetAuthentication(IOwinContext context, IAuthenticationResult authenticationResult)
        {
            var session = context.GetFeature <ISession>();

            if (session == null)
            {
                return;
            }

            var claims = _identityDirectory.GetClaims(authenticationResult.Identity);

            session.Set("claims", string.Join(", ", claims.Select(c => c.Name + (c.Status == ClaimStatus.Verified ? " = " : " ~ ") + c.Value)));

            session.Set("identity", authenticationResult.Identity);
            session.Set("outcome", authenticationResult.Status.ToString());
            session.Set("purposes", string.Join(", ", authenticationResult.Purposes ?? new List <string>()));

            if (!string.IsNullOrEmpty(authenticationResult.RememberMeToken))
            {
                var credential = _identityStore.GetRememberMeCredential(authenticationResult.RememberMeToken);
                session.Set("purposes", string.Join(", ", credential.Purposes ?? new List <string>()));
                session.Set("username", credential.Username);
            }
        }
Exemplo n.º 14
0
        Task IMiddleware.Invoke(IOwinContext context, Func <Task> next)
        {
            if (!string.IsNullOrEmpty(_configuration.DocumentationRootUrl) &&
                context.Request.Path.Value.Equals(_configuration.DocumentationRootUrl,
                                                  StringComparison.OrdinalIgnoreCase))
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning configuration documentation");
                return(DocumentConfiguration(context));
            }

            var cssFileContext = context.GetFeature <CssFileContext>();

            if (cssFileContext == null || cssFileContext.PhysicalFile == null)
            {
                return(next());
            }

            var outputCache = context.GetFeature <IOutputCache>();

            if (outputCache != null)
            {
                outputCache.Category = "Less";
                outputCache.Priority = cssFileContext.NeedsCompiling ? CachePriority.High : CachePriority.Medium;
                _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " setting output cache category='Less' and priority='" + outputCache.Priority + "'");
            }

            return(Task.Factory.StartNew(() =>
            {
                string fileContent;
                using (var streamReader = cssFileContext.PhysicalFile.OpenText())
                {
                    fileContent = streamReader.ReadToEnd();
                }
                _filesServedCount++;

                context.Response.ContentType = "text/css";
                if (cssFileContext.NeedsCompiling)
                {
                    if (_preprocessor != null)
                    {
                        _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " applying application defined pre-processing of Less file");
                        fileContent = _preprocessor(cssFileContext.PhysicalFile, fileContent);
                    }

                    _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " compiling Less file to CSS");
                    try
                    {
                        var css = dotless.Core.Less.Parse(
                            fileContent,
                            new DotlessConfiguration
                        {
                            Logger = _configuration.TraceLog ? typeof(DotLessCustomLogger) : typeof(dotless.Core.Loggers.NullLogger),
                            LogLevel = _configuration.TraceLog ? LogLevel.Debug : LogLevel.Error,
                            MinifyOutput = _configuration.Minify,
                        });
                        context.Response.Write(css);
                        _filesCompiledCount++;
                    }
                    catch (Exception ex)
                    {
                        _traceFilter.Trace(context, TraceLevel.Error, () => GetType().Name + " compilation error in LESS file, see response for details");
                        context.Response.Write("/* Compilation error in LESS file " + cssFileContext.PhysicalFile + Environment.NewLine);
                        while (ex != null)
                        {
                            context.Response.Write(ex.GetType().FullName + " " + ex.Message + Environment.NewLine);
                            ex = ex.InnerException;
                        }
                        context.Response.Write("*/" + Environment.NewLine);
                    }
                }
                else
                {
                    _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning CSS from file system");
                    context.Response.Write(fileContent);
                }
            }));
        }
        /// <summary>
        /// This method injects an access token into any html page that needs
        /// one, and also injects Javascript to delete the token when the
        /// page is unloaded.
        /// </summary>
        private Task InjectToken(IOwinContext context, Func <Task> next)
        {
            var response = context.Response;

            var newStream      = new MemoryStream();
            var originalStream = response.Body;

            response.Body = newStream;

            return(next().ContinueWith(downstream =>
            {
                if (downstream.Exception != null)
                {
                    throw downstream.Exception;
                }

                response.Body = originalStream;
                if (string.Equals(response.ContentType, "text/html", StringComparison.OrdinalIgnoreCase))
                {
                    var encoding = Encoding.UTF8;
                    var originalBytes = newStream.ToArray();
                    var html = encoding.GetString(originalBytes);

                    var apiToken = string.Empty;
                    if (html.Contains("{{api-token}}"))
                    {
                        apiToken = _tokenStore.CreateToken("api");

                        var unloadStript = "<script>\n" +
                                           "window.onunload = function(){\n" +
                                           "  var xhttp = new XMLHttpRequest();\n" +
                                           "  xhttp.open('DELETE', '" + _deleteTokenPath.Value + "', true);\n" +
                                           "  xhttp.setRequestHeader('api-token', '" + apiToken + "');\n" +
                                           "  xhttp.send();\n" +
                                           "}\n" +
                                           "</script>\n";

                        html = html.Replace("</body>", unloadStript + "</body>");
                    }

                    var identification = context.GetFeature <IIdentification>();
                    var identity = identification == null ? string.Empty : (identification.IsAnonymous ? "Anonymous" : identification.Identity);

                    var session = context.GetFeature <ISession>();
                    var regex = new Regex("{{([^}]+)}}");
                    html = regex.Replace(html, m =>
                    {
                        var key = m.Groups[1].Value.ToLower();
                        switch (key)
                        {
                        case "api-token": return apiToken;

                        case "identity": return identity;

                        default: return session == null ? string.Empty : (session.Get <string>(key) ?? string.Empty);
                        }
                    });

                    var newBytes = encoding.GetBytes(html);
                    originalStream.Write(newBytes, 0, newBytes.Length);
                }
                else
                {
                    newStream.WriteTo(originalStream);
                }
            }));
        }
        Task IMiddleware.Invoke(IOwinContext context, Func <Task> next)
        {
            if (!string.IsNullOrEmpty(_configuration.DocumentationRootUrl) &&
                context.Request.Path.Value.Equals(_configuration.DocumentationRootUrl, StringComparison.OrdinalIgnoreCase))
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " returning configuration documentation");
                return(DocumentConfiguration(context));
            }

            var staticFileContext = context.GetFeature <StaticFileContext>();

            if (staticFileContext == null || !staticFileContext.FileExists)
            {
                _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " this is not a request for a static file");
                return(next());
            }

            var configuration          = staticFileContext.Configuration;
            var physicalFile           = staticFileContext.PhysicalFile;
            var extentionConfiguration = staticFileContext.ExtensionConfiguration;

            if (configuration == null || physicalFile == null || extentionConfiguration == null)
            {
                _traceFilter.Trace(context, TraceLevel.Error, () => GetType().Name + " required data is missing, file can not be served");
                return(next());
            }

            var outputCache = context.GetFeature <IOutputCache>();

            if (outputCache != null)
            {
                var largeFile = physicalFile.Length > configuration.MaximumFileSizeToCache;
                outputCache.Category         = largeFile ? "LargeStaticFile" : "SmallStaticFile";
                outputCache.MaximumCacheTime = configuration.MaximumCacheTime;
                outputCache.Priority         = largeFile ? CachePriority.Never : CachePriority.High;
                _traceFilter.Trace(context, TraceLevel.Debug, () => GetType().Name + " configured output cache " + outputCache.Category + " " + outputCache.Priority + " " + outputCache.MaximumCacheTime);
            }

            context.Response.ContentType = extentionConfiguration.MimeType;

            if (extentionConfiguration.IsText)
            {
                _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " responding with a text file");
                _textFilesServedCount++;

                string text;
                using (var streamReader = physicalFile.OpenText())
                {
                    text = streamReader.ReadToEnd();
                }
                return(context.Response.WriteAsync(text));
            }

            _traceFilter.Trace(context, TraceLevel.Information, () => GetType().Name + " responding with a binary file");
            _binaryFilesServedCount++;

            var buffer = new byte[physicalFile.Length];

            using (var stream = physicalFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var offset = 0;
                while (true)
                {
                    var bytesRead = stream.Read(buffer, offset, buffer.Length - offset);
                    if (bytesRead == 0)
                    {
                        return(context.Response.WriteAsync(buffer));
                    }
                    offset += bytesRead;
                }
            }
        }