using System; using System.Reflection; using System.Web; using GeneralApi.Core.Infrastructure.IoC; using System.Web.UI; namespace Taloyhtio.GeneralSSO.Server.CodeFiles.Infrastructure.Web { public class InitializationModule : IHttpModule { private static bool initialized; private static readonly object lockObject = new object(); public void Init(HttpApplication context) { context.BeginRequest += context_BeginRequest; // the following handler is needed for sending 401 status to jquery ajax when it is returned from dataapi.svc. // Without it ASP.Net will return 302 status and redirect url to the login page because forms based authentication is used. // See http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx. context.EndRequest += OnEndRequest; } public void Dispose() {} private static void context_BeginRequest(object sender, EventArgs e) { // configuration is required only once per AppDomain if (!initialized) { lock (lockObject) { if (!initialized) { IoCConfiguration.Configure(); log4net.Config.XmlConfigurator.Configure(); // DotNetOpenAuth uses the following call in order to determine whether log4net available or not: // Assembly.Load("log4net"); // (see DotNetOpenAuth.Loggers.Log4NetLogger.IsLog4NetPresent). If it is not available it will // use simple trace logger which logs records to trace output, which also can be problematic // to read because it happens in IIS worker process (DebugView utility has problem with it). // The problem that it fails when log4net is located in GAC. For fixing it we need to attach own // handler for AppDomain.AssemblyResolve event and resolve it by full name AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; initialized = true; } } } // with CORS jquery.ajax() first sends OPTIONS request to endpoint and asks // whether appropriate origin (caller), verb and headers are allowed. // We need to answer on it with appropriate values. if (HttpContext.Current.Request.RawUrl.ToLower().Contains("dataapi.svc")) { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "WWW-Authenticate"); if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Authorization, Content-Type"); HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "120"); HttpContext.Current.Response.End(); } } //if (HttpContext.Current.Request.RawUrl.ToLower().Contains("/pages/root.aspx")) //{ // Page page = HttpContext.Current.CurrentHandler as Page; // page.MasterPageFile = "/_catalogs/taloyhtio_custom_layout.master"; //} } private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { if (args.Name == "log4net") { return Assembly.Load("log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a"); } return null; } private void OnEndRequest(object source, EventArgs args) { var context = (HttpApplication)source; var response = context.Response; var request = context.Request; string contentType = request.Headers["Content-Type"]; if (contentType != null && contentType.ToLower().Contains("application/json") && response.StatusCode == 302) { response.TrySkipIisCustomErrors = true; response.ClearContent(); response.StatusCode = 401; response.RedirectLocation = null; } } } }