What event should I use in the IHttpModule to disable website? - c#

I want to disable a website programatically for licensing reasons, and I want to do it in a httpmodule.
Ive tried to redirect the context :
public void Init(HttpApplication context)
{
context.Response.Redirect("http://vls.pete.videolibraryserver.com");
}
But I get the error:
Response is not available in this context.
Anybody know how I can effectively disable the website and preferably send them to a custom page.

you can use BeginRequest event for redirection, like following:
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
application.Context.Response.Redirect("http://vls.pete.videolibraryserver.com");
}

Use Server.Transfer as this will save a round trip provided the custom page is on the same machine; HTTPModule BeginRequest should us Response.Redirect or Server.Transfer (this is my own question I answered - not trying to be self promoting)

Perhaps a better way to close the site would be to programmatically write out an App_Offline.htm file to the root of the website. To quote from Scott Guthrie's blog:
"The way app_offline.htm works is that
you place this file in the root of the
application. When ASP.NET sees it, it
will shut-down the app-domain for the
application (and not restart it for
requests) and instead send back the
contents of the app_offline.htm file
in response to all new dynamic
requests for the application. When
you are done updating the site, just
delete the file and it will come back
online."

public void Init(HttpApplication context)
{
context.Response.Write("for licence visit this link");
context.Response.End();
}
you can use this code

Related

How do I make Umbraco play nice with NWebSec's built in CSP Report event handler?

I'm working on a website which uses the Umbraco CMS version 7. I'm using NWebSec to implement a CSP header on the website. NWebSec has built in functionality to raise a .Net event when there's a CSP violation. Normally you'd catch that event with something like this:
protected void NWebSecHttpHeaderSecurityModule_CspViolationReported(object sender, CspViolationReportEventArgs e)
{
var report = e.ViolationReport;
var serializedReport = JsonConvert.SerializeObject(report.Details);
// Do a thing with the report
}
in the Global.asax.cs file. But so far as I can tell, Umbraco preempts the Global.asax.cs file, and it eats any event that's thrown. I have a file with a few custom event handlers like:
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
to handle the standard pieces of application startup code that would normally be in the Global.asax.cs file, but putting the NWebSec event handler in that same file doens't work. Presumably it's because it's using the .Net event handler syntax rather than whatever Umbraco replaces it with.
How do I access the events thrown by NWebSec?
the Global.asax class inherits from UmbracoApplication so no, you can't use that. There are a number of reasons for this including enabling the ability to "run" Umbraco outside of the web context - i.e. in a console application).
After reviewing the available documentation on the NWebSec documentation website, I don't think you can just place your NWebSecHttpHeaderSecurityModule_CspViolationReported event handler method in the class, you will need to wire it up as well. It should probably look something like this:
public class MyGlobalEventHandler : ApplicationEventHandler {
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var nWebSecHttpHeaderSecurityModule = umbracoApplication.Modules["NWebSecHttpHeaderSecurityModule"] as HttpHeaderSecurityModule;
if (nWebSecHttpHeaderSecurityModule != null) {
nWebSecHttpHeaderSecurityModule.CspViolationReported += NWebSecHttpHeaderSecurityModule_CspViolationReported;
}
base.ApplicationStarted(umbracoApplication, applicationContext);
}
protected void NWebSecHttpHeaderSecurityModule_CspViolationReported(object sender, CspViolationReportEventArgs e)
{
var report = e.ViolationReport;
var serializedReport = JsonConvert.SerializeObject(report.Details);
// Do a thing with the report
}
}
If you're using a newer version of Umbraco that supports OWIN (7.3.0), you could use the NWebsec.Owin library which may give you a better result and more flexibility perhaps.

Intercept Session Start event for all applications

I have an IIS server (7.5) that hosts several applications each of them run in their own application pool identity. I am trying to write some code that intercepts the Session On Start event. I have successfully written other IHttpModules that are processed for all requests but, in this case I only want to intercept the first time the session is initiated. I want to do this for all the web applications at a global level within my web site. My plan is to use this to capture the last logon date for the user on a per web app basis to satisify an auditing requirement.
I have all the pieces in place except the event that I need to intercept. It seems all IHttpModule Events fire on all requests. I figured the Session_Start event would be ideal but it doesn't look like I can tie into this from an IHttpModule.
I looked at the SessionStateUtility but I do not want to rewrite session functionality, I just want to intercept the start event.
Is there another interface out there I can use to intercept Session_Start? Any other recommendations?
Have you tried something like this?
public void Init(HttpApplication context)
{
var sessionModule = context.Modules["Session"] as SessionStateModule;
if (sessionModule != null)
{
sessionModule.Start += this.Session_Start;
}
}
private void Session_Start(object sender, EventArgs e)
{
// Do whatever you want to do here.
}

Global.asax magic functions

When creating an ASP.NET Mvc project in Visual Studio, a Global.asax & Global.asax.cs will be created. In this .cs file you will find the standard Application_Start method.
My question is the following, how is this function called? because it is not a override. So my guess is that this method name is by convention. The same goes for the Application_Error method.
I want to know where these methods are hooked. Because I write those methods (not override them) I couldn't find any documentation on them in MSDN. (I found this page but it only tells you to hook to the Error event and shows a Application_Error(object sender, EventArgs e) but not how the Event and the method are linked.)
//Magicly called at startup
protected void Application_Start()
{
//Omitted
}
//Magicly linked with the Error event
protected void Application_Error(object sender, EventArgs e)
{
//Omitted
}
It isn't really magical.. the ASP.NET Pipeline wires all of this up.
You can see the documentation regarding this here.
Specifically you will be interested in the parts below:
An HttpApplication object is assigned to the request.
Which consists of a list of events that are fired and in what order.
There are links all over that page (too many to contain here) that link off to various other pages with even more information.
ASP.NET automatically binds application events to handlers in the
Global.asax file using the naming convention Application_event, such
as Application_BeginRequest. This is similar to the way that ASP.NET
page methods are automatically bound to events, such as the page's
Page_Load event.
Source: http://msdn.microsoft.com/en-us/library/ms178473.aspx
To demystify the 'magic' of the accepted answer, the ASP.Net pipeline is automagically binding the HttpApplication events to the methods with the Application_EventName in the class. If (much like me) you would rather see the events explicitly bound to a handler these can be bound by overriding HttpApplication.Init() and Visual Studio will generate the handler method with the correct signature.
public override void Init()
{
this.BeginRequest += MvcAppliction_BeginRequest;
}
private void MvcApplication_BeginRequest(object sender, EventArgs e)
{
...
}
There is an example of this method of binding events
ASP.Net itself creates it. Here is the flow as per MSDN -
User requests an application resource from the Web server.
ASP.NET receives the first request for the application.
ASP.NET core objects are created for each request.
An HttpApplication object is assigned to the request. In this step Global.asax will be processed and events will be associated automatically.
The request is processed by the HttpApplication pipeline. In this step the HttpApplication Global events are raised.
Here is the reference - ASP.Net Application Life Cycle.
From the reference - ASP.NET automatically binds application events to handlers in the Global.asax file using the naming convention Application_event, such as Application_BeginRequest.

taking parameter values from ihttp handler

Let us consider a sample website application and running in local host.say for example www.asdf.com . when ever the user hitting the url in browser
Can it can be captured by inheriting ihttp handler or ihttp module to our class
If the url has been hitted by changing www.asdf.com?t=value is it possible to take that value.
In java this concept is used as servelet filters . Is there any thing like that in dotnet
waiting for your responses
Modules and Handlers do two different things.
Modules plug into the application and request lifecycles and respond to any number of events along the way to affect some bit of functionality to each request. Usually, it for stuff like security, logging, compression, etc. For example, FormsAuthenticationModule responds to the AuthorizeRequest (amongst others) event during each request, where it checks to see if there is an authentication ticket, validate it, and then indicate to the current context whether or not the user is authenticated (and who).
Handlers are designed to wait for a request to certain paths or extensions and do something useful. For example, requests to .ASPX files are handled by a Page handler, which parses and executes an ASPX and its associated codebehind (if there is one).
Both Modules and Handlers have access to the HttpContext object, which allows them to inspect and in many cases manipulate the current application, the current request and response, the user, etc. So yes, either can access the query string values provided during a request.
I believe modules are most analogous to a servlet filters.
This module looks for the t query string and echoes it at the beginning of every request.
public class MyModule : IHttpModule {
public String ModuleName {
get { return "MyModule"; }
}
public void Init(HttpApplication application) {
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
}
private void Application_BeginRequest(Object source, EventArgs e) {
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write(string.Format("The value of \"t\" is {0}", context.Request.QueryString["t"]);
}
public void Dispose()
{
}
}

Analyze the use of a ASP.NET webservice

long time ago I wrote webservice that is still in use. Now I plan to refactor it. The webservice is full of most likely unused functions and I have no idea how it is used by the clients. In order to strip away the unused functions I need to analyze the function calls and data of currently installed webservice.
Is there a (free/opensource) tool that will enable me to log all activities of the webservice.
The ideal output of the tool I'm looking for could be a database containing all the called functions and a list of the data that was send to it for each call.
Solution
With the help of Martins answer I created this HttpModule which does exactly what I wanted:
public class LoggingModule : IHttpModule
{
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequest);
}
private void BeginRequest(object sender, EventArgs e)
{
TryAppendLog("Content-Type");
TryAppendLog("SOAPAction");
}
void TryAppendLog(string key)
{
string value = HttpContext.Current.Request.Headers[key];
if (string.IsNullOrEmpty(value)) { return; }
HttpContext.Current.Response
.AppendToLog(string.Format("{0}: {1} ", key, value));
}
#region IHttpModule Member
public void Dispose() { }
#endregion
}
As Kobi wrote, you can find the required information in the IIS log files (i.e. in c:\WINDOWS\system32\LogFiles\W3SVC1).
If you want to log the usage into a database, you could write a simple HttpModule, which checks every request, and logs it into the DB if it is a call to your web service.
E.g. here's the relevant parts of a very simple HttpModule, which logs calls to mywebservice.asmx:
public class MyWebServiceDiagnosticsModule : IHttpModule
{
public MyWebServiceDiagnosticsModule ()
{
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(BeginRequest);
}
private void BeginRequest(object sender, EventArgs e)
{
HttpContext ctx = HttpContext.Current;
string url = ctx.Request.Url.ToString().ToLower();
if (url.Contains("mywebservice.asmx"))
{
LogMethodCall(url); // parse URL and write to DB
}
}
}
You can potentially write your own IHttpHandler that would log all the information and then delegate the call to appropriate .NET HTTP Handler, but that wouldn't be a simple task.
And a word on terminology. "Refactoring" is not about changing external behavior, so if refactoring is really what you're heading for, I'd recommend to keep the public contract (interface) of the web service intact. Instead, roll out a new version of the same service with only core functionality.
You can enable logging in the IIS, they can get very detailed depending on your choices.
There are tools made specifically for analyzing IIS logs.
Depending a little bit on your load/criticality and similar constraints you could also probably just route the traffic through as Soap Proxy like SoapUI to capture and analyze traffic for a period of time. If you set up the proxy and re-route at the firewall level it should be transparent for end-users.
I have not tried this for a system with heavy load; be warned.

Categories