/// <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()); }
/// <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()); }
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++; } })); }
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()); }
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)); }
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()); }
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); } }
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; } } }