different web.config settings for http and https - asp.net

Is it possible to configure your web.config file of your asp.net website to use different settings for users accessing the site via HTTPS?
(eg. I need to have validateRequest attribute for https access set to false, but for internal access (using http) set to true...)
thanks!

For security reasons, I would recommend deploying internal and extenal sites a different sites altogether. That means you could use windows authentication internally and forms authentication externally, and change whatever other config settings you desire. It also means you can limit the attack surface for external evil-doers by not providing access to methods intended for internal users only.

Disable request validation in the Web.config file:
<system.web>
<pages validateRequest="false"/>
</system.web>
And in the Global.asax file, add an event handler for BeginRequest along the lines of:
public class Global : HttpApplication
{
public override Init()
{
base.Init();
BeginRequest += ToggleValidation;
}
void ToggleValidation(object sender, EventArgs e)
{
if (Request.IsSecureConnection)
Request.ValidateInput();
}
}

Related

httpmodules(Classic Mode) Vs Modules (Integrated mode) not parsing request in the same way

I have an ASP.NET FW 4.5 application, normally it is running under Classic Mode , and we use a HttpModule that parse every request to webpages.
The Module checks in the DB if the user has access.
No problem with that.
When we switch to integrated mode we put a < webserver > < module > as recommended in the migration guide.
The problem is that the module is parsing every request to the application, also the css, jss and images.
In Classic mode this does not happen, only pages are parsed.
Is there a different behavior between classic and integrated?
The module implements methods like:
private void OnBeginRequest(object sender, EventArgs e)
private void OnAuthorization(object sender, EventArgs e)
This question is a bit old but just in case somebody else finds it I'll provide the answer...
In integrated mode, any modules you provide in <system.webserver> are invoked for every IIS request (including non ASP.NET pages) unless you add a constraint via the preCondition attribute. e.g.
<system.webserver>
<modules>
<add preCondition="managedHandler" name="..." type="..."/>
</modules>
</system.webserver>
Specifying managedHandler means the module will be invoked only for ASP.Net managed resources such as .aspx files, but not unmanaged resources such as html, images and javascript.
Note, however, this setting is overridden if you specify runAllManagedModulesForAllRequests="true" on the <modules> element, which causes all modules (and your Global.asax class if present) to be notified about all requests.
There's a useful write-up of the Life Cycle of an IIS 7.x request on MSDN, but this does not mention the preCondition attribute. However you can read about it in the IIS Settings Schema documentation.
TL;DR
You might be wondering how it's possible that a module can be invoked for a non-managed resource when the event handlers defined in your Global.asax file are not invoked. After all, modules register their event handlers with the HttpApplication object that is passed to the IHttpModule.Init method like this:-
public void Init(System.Web.HttpApplication context)
{
context.AuthenticateRequest += my_request_handler;
}
The HttpApplication passed to Init is the same as that defined in Global.asax, so why aren't the Global application event handlers invoked? The answer is simply that when a module registers its event handlers with the HttpApplication object, the HttpApplication is aware that it is in module initialization mode, and registers the event handlers separately, along with flags to indicate if the event handler should be called for non-managed resources. You can investigate further by looking at the
HttpApplication reference source code.

How to define error-handling logic at the server level

For a website/ vpath, it's possible to handle the Application_Error event to catch errors before they get sent back to the browser. Is it possible to also do this at the server level somehow? That is, define a method at the root level that will execute if an error occurs in a website, but that website fails to handle the error for whatever reason.
I know you can use the web.config at the root level to define custom error messages per HTTP status code. However, this isn't ideal for my case, because I want to return different types of content (ie, HTML or something else) depending on the application logic.
A custom http module can be registered at applicationHost.config. Then this module is used by all IIS applications on the target machine.
1) Create a signed class library project with http module:
public class ErrorHandlingModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.Error += new EventHandler(context_Error);
}
void context_Error(object sender, EventArgs e)
{
// handle error
}
}
2) Install the class library into GAC, so it can be shared by all IIS applications.
3) Install the http module to applicationHost.config file. This file usualy resides in C:\Windows\System32\inetsrv\config. Files in this folder can be accessed only by 64-bit processes (there is no such issue on 32-bit OSes), VS2010 cannot see them but Explorer can. The applicationHost.config fragment could look like this:
<location path="" overrideMode="Allow">
<system.webServer>
<modules>
<add name="MyModule" preCondition="managedHandler" type="GlobalErrorHandler.ErrorHandlingModule, GlobalErrorHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bfd166351ed997df" />
I am not clear what your question is but as per my understanding. inside application_error you can use ,
Server.GetLastError() to get last error occured in server level.

WCF - Using ServiceRoutes instead of svc files -- My app states I need AspNetCompatability only when I first attempt to connect?

public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
private static void RegisterRoutes(ICollection<RouteBase> routes)
{
routes.Add(new ServiceRoute("Calculator", new WebServiceHostFactory(), typeof(CalculatorService)));
}
}
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true">
<serviceActivations>
<add factory="System.ServiceModel.Activation.ServiceHostFactory"
relativeAddress="Calculator.svc"
service="MyServer.CalculatorService"/>
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
When I do this and go to http://localhost/MyApp/Calculator.svc I get an error saying I need AspNetCompatability. So I added [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] and it works, the only thing is I'm worried that I will want my service to use alternative means of transport (not just http) if I want to get into using alternative non-http bindings.
The strange thing is that if I don't set the attribute to Allowed or Required then when I rebuild my page I get that error. After I get that error I hit refresh and everything is fine. And it isn't just if I query the svc through a web browser, but if I have an app it crashes the first time it connects (if the server was restarted) and afterwards it works. What gives?
I think that your problem is messed configuration. You are adding a route and in the same time you are registering the service with configuration based activation. Use either one or second. Also you can use routes and only Http based protocols or non-http protocols but without routes.
Unfortunately, yes, you must enable ASP.NET compatibility to use ServiceRoutes. This is because the ASP.NET runtime is now responsible for routing the traffic instead of just IIS modules.

asp.net authentication - use credentials from web.config - problem

I have a simple problem which is giving me headaches for a couple of days.
I've created very simple application with login control. I keep user data in web.config file:
<authentication mode="Forms">
<forms name=".RzeskoLoginCookie">
<credentials passwordFormat="Clear">
<user name="test" password="test"/>
</credentials>
</forms>
</authentication>
I will deploy this simple website to IIS on computer on which I do not want to use SQL Server.
My login button event looks like this:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Now the problem:
When I am running a website on VS2008 built in webserver, everything works fine (I can log in). When I copy my website to IIS I am constantly getting this annoying error (after I click Login button):
Failed to generate a user instance of
SQL Server due to failure in
retrieving the user's local
application data path. Please make
sure the user has a local user profile
on the computer. The connection will
be closed.
I also observed that in my App_Data folder some weird files are being created.
To sum up. What I want to achieve is to use user credentials from web.config file, without using sql server.
I'd appreciate any help
Kind Regards
PK
From the MSDN page for Login control:
*
The Login control uses a membership
provider to obtain user credentials.
Unless you specify otherwise, the
Login control uses the default
membership provider defined in the
Web.config file. To specify a
different provider, set the
MembershipProvider property to one of
the membership provider names defined
in your application's Web.config file.
For more information, see Membership
Providers.
*
The default Membership provider is the AspNetSqlProvider which uses a SQL Server database as its user store.
If you want to provide a custom authentication routine, you can either write your own custom Membership provider or handle the OnAuthenticate method of the Login control to provide your own authentication logic.
If you notice in your code, you have the method declaration for handling the <asp:Login> control's LoggingIn event:
protected void Login1_LoggingIn(object sender, LoginCancelEventArgs e)
This control interfaces with the ASP.NET Membership provider which is probably why it is looking for a connection string.
So rather than using the <asp:Login> control, simply use a button and handle the Click event so that there is no use of Membership:
<asp:Button id="LoginButton" Text="Login" OnClick="Login_OnClick" runat="server" />
Code behind (notice the different signature of the method):
public void Login_OnClick(object sender, EventArgs args)
{
if(FormsAuthentication.Authenticate(Login1.UserName, Login1.Password))
{
FormsAuthentication.RedirectFromLoginPage(Login1.UserName, Login1.RememberMeSet);
}
}
Ok, thanks everybody for pointing out the solution.
I finally managed to avoid that error by creating my own authentication event (associated with the login control).

IIS 6, Wildcard Application Mapping, and FrontPage

While I'd love to get rid of requiring FrontPage Extensions on a heavy traffic site I host, the client requires it to administrate the site. Having just implemented Wildcard Application Mapping in IIS 6 on this site in order to provide integrated Forms Authentication security between ASP and ASP.NET resources, this breaks FrontPage extensions. Everything works like a charm, including encrypting and caching roles that are now available even to ASP, except for the loss of FrontPage. Specifically, you cannot even login to FrontPage administration (incorrect credentials).
Has anyone gotten FrontPage to work with Wildcard Application Mapping routing through the ASP.NET 2.0 aspnet_isapi.dll?
UPDATE: I've marked #Chris Hynes answer even though I have not had the time to test (and the current configuration is working for the client). It makes sense and goes along with what I thought was occurring and possibly how to deal with, but did not know where to route the request at that point (fpadmdll.dll). Much thanks!
The issue here sounds like the wildcard mapping is taking precedence over the frontpage extensions ISAPI handler and/or messing up the request/response for that. I'd try creating a handler that does nothing and mapping it to fpadmdll.dll.
Something like this:
namespace YourNamespace
{
public IgnoreRequestHandler : IHttpHandler
{
public IsReusable { get { return true; } }
public void ProcessRequest(HttpContext context)
{ }
}
}
Then map it up in the web.config:
<httpHandlers>
<add verb="*" path="fpadmdll.dll" type="YourNamespace.IgnoreRequestHandler, YourDll" />
</httpHandlers>

Resources