taking parameter values from ihttp handler - c#

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()
{
}
}

Related

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.
}

Can I extend ServiceStackHost to handle requests from a CEF browser in my application?

I have a solution which includes a thick client (implemented using CefSharp for the majority of the user interface), and the javascript application needs to execute some C# logic in the application hosting the CEF browser. I considered using WebView.RegisterJsObject(), but I can write less glue code if I can just use $.ajax() from the html pages.
I already have ServiceStack set up for the web services and the web client in this solution. I'd like to route requests from the CEF browser to a local ServiceStack host (without actually using http).
Here's some psuedo code to illustrate what I would like to do:
public partial class MainWindow : IRequestHandler {
WebView _webView;
CefSharpServiceStackHost _serviceHost;
public MainWindow() {
// initialize CefSharp...
_webView.RequestHandler = this;
// initialize ServiceStackHost...
}
// other IRequestHandler methods...
// method this intercepts ajax calls from the CEF browser
public bool OnBeforeResourceLoad(IWebBrowser browser, IRequestResponse requestResponse) {
// translate CefSharp.IRequestResponse to ServiceStack.IRequest or HttpRequest
// should execute HelloService.Any() for the requestResponse.Url = "/hello/Zach"
var response = _serviceHost.ExecuteService(Translate(requestResponse));
requestResponse.RespondWith(response.Stream);
return false;
}
}
[Route("/hello/{Name}")]
public class Hello {
public string Hello { get; set; }
}
public class HelloService {
public object Any(Hello request) { // ... }
}
The part I can't figure out is how to extend ServiceStackHost so I can pass some sort of request object to it. Is this even possible?
This might be a stupid answer, but why not just use http anyway? The web is so heavily based on it that things actually gets easier if you use it even in cases like this (where it isn't really necessary).
If this isn't OK, you can implement a custom scheme handler that routes requests to foo://bar to your C# code, and do whatever you like. The CefSharp.Wpf.Example has an example custom scheme handler, so it should help you along the way.
What you're after sounds similar to how MQ Servers execute services in ServiceStack by simply routing messages to:
ServiceController.ExecuteMessage(IMessage)
There are a number of other API's on ServiceController you can use to execute requests in ServiceStack:
//Execute the Request DTO with an empty Request context:
object Execute(object requestDto)
//Execute the Request DTO with the supplied Request context:
object Execute(object requestDto, IRequest request)
For the IRequest context, you can use the built-in BasicRequest class, or your own that implements IRequest.

Limiting HttpModule to only process certain requests

We use directory browsing on a specific section of our website, but our users don't really like the default ASP.NET
directory browsing. To be honest, we don't particularly care for it either.
I came across mvolo's custom directory browsing module and I attempted to use it. However, I discovered that if I have it enabled in my root web.config, it allows directory browsing on all folders without a default page (as you would expect). If I set enabled="false" in the root, it throws an HttpException, which is being caught by my generic error page, but every request is causing the exception, like when the page requested has additional images to request during the load.
As I believe (and I could be wrong), the default directory browsing module only checks for the enabled attribute if there is no default folder and you aren't requesting a specific file (for example, mysite.com/images/ versus mysite.com/images/logo.gif).
I have reconstructed the functionality of the custom module, but I am unable to figure out how to limit the module to only fully execute in situations where directory browsing would be necessary if enabled -- and not for every single request. Here is a chunk of code from the module:
public void Init(HttpApplication app)
{
app.PreRequestHandlerExecute += new EventHandler(this.OnPreRequestHandlerExecute);
}
public void OnPreRequestHandlerExecute(object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
config = (DirectoryListingConfigSection)WebConfigurationManager.GetSection("directoryBrowsing", context.Request.Path);
if (this.config == null)
{
throw new Exception("Missing <directoryBrowsing> configuration section.");
}
/* I only want to check this if it's necessary, not for things
like mysite.com/images/logo.gif or mysite.com/about/history.aspx
-- those shouldn't give a 403 error */
if (!config.Enabled)
{
context.Response.Status = "403 Forbidden";
}
/* The rest of the code goes below, and should only process
if Directory Browsing is necessary and enabled */
}
Modules are executed on every request that goes through the ASP.Net, there is no way to restrict calls to module based on type of request.
You need to built checks into your module's code to only handle requests that are of interest of that module.
Depending on the stage you should have access to most of information about request. During PreRequestHandlerExecute you have all possible information about incoming request, including Url, headers and related session state if present.

Creating a protected link

Is there a way to create a protected download link which is random, expiry, requires a password and pointing to a specific file in C# that is associated with IIS 7.0?
Several random links can link to the same file.
Built-in codes or perhaps 3rd party libraries?
For example, http://www.example.com/<some random gibberish>/<md5 of file>/file.jpg
One way to do this would be to use GUIDs. GUIDs are designed not to collide, and that design also leads to a difficulty in guessing valid GUIDs. I'm sure someone out there will tell me that this is not very secure! Well, you are also protecting with a password. It is pretty easy to generate a GUID in C#.
I guess what you need is firstly a way of ingesting the files that you want to protect in this way, and secondly a handler that will respond to requests in a given path and inspect the GUID in the path to determine if it's valid.
You'd then need a database back end to maintain lists of GUIDs corresponding to URLs, the password (preferably crypted) and the expiry date. The handler would inspect the entry for the requested URL/GUID to see if the link has expired, then prompt the user (could do this via a web form easily enough) for the password and check this against the crypted password stored in the database.
To generate a GUID, you want:
System.Guid.NewGuid().ToString()
To create a module that is called before every request (for IIS7) you can add an entry to your web.config like so:
<modules>
<add name="MyDownloadModule" type="Example.MyDownloadModule, Example"/>
</modules>
where MyDownloadModule is the class containing your handler, in the namespace Example.
Inside that class you then need to implement the IHttpModule interface, in particular overriding the methods:
public string ModuleName {
get { return "MyDownloadModule"; }
}
public void Init(HttpApplication app) {
// Add an event handle which is called at the beginning of each request
app.BeginRequest += new EventHandler(this.AppBeginRequest);
}
//
// Our event handler for the BeginRequest event
//
private void AppBeginRequest(Object source, EventArgs e)
{
HttpRequest request = app.Context.Request;
//
// Is this a file download?
//
if (request.AppRelativeCurrentExecutionFilePath == "~/downloads") // or whatever
{
// this is where you work your GUID inspecting magic
}
}
Going about it this way means this will be called for every request to the server, which may not be what you want.
You could always create your own HttpHandler, and then implement your own proprietary expiration/validation code.
Something like:
http://www.example.com/download?token={your_token}
It would then be a trivial matter to have the handler intercept the request and grab the file from disk, and deliver it to the client if the ?token querystring value is correct.
For more information on the IHttpHandler interface, see MSDN http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx

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