Q1 -IIS7 by default automatically registers FormsAuthenticationModule ( which is defined in root web.config file ), but does the term “Http module being integrated into IIS 7 processing pipeline refers” only to cases where this registered module is also configured to work with non-Asp.Net applications?
In my opinion if module is not configured to work with non-Asp.Net applications, even if it is automatically registered by IIS 7, then we can’t really claim that it is integrated into IIS 7’s processing pipeline?!
Q2
A) IIS7 automatically registers some of the modules defined in root web.config file.
If we configure ( via IIS7 manager ) UrlAuthorizationModule ( which is defined in root web.config and which IIS 7 registers by default ) to be used with non-Asp.Net apps also, then IIS7 puts the following entry into application’s root web.config file:
<modules>
<remove name="UrlAuthorization" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
But why did IIS 7 also include <remove name="UrlAuthorization" /> element?
B) I assume if we then change our mind and decide to use this module only with Asp.Net applications, we can safely remove the following element:
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
from application’s root web.config file, since now our application can use UrlAuthorizationModule defined in root web.config?!
Q3
I realize IIS7 by default registers FormsAuthenticationModule defined in root web.config file, but assume we register another FormsAuthenticationModule in web.config contained in a root directory of some web application.
I assume when request for web page is received, two instances of FormsAuthenticationModule will be executed for that request?
thanx
EDIT:
A1.
"integrated" vs "classic" processing pipelines is a property on the application pool. It is correct that modules can be set to run only in "integrated" pipelines.
My question was referring to IIS 7 in integrated mode. Namely, my book uses the term “Http module being integrated into IIS 7 processing pipeline refers” to describe a situation where custom Http handler has been registered with IIS 7 (running in integrated mode). But it doesn’t say whether the term refers to situation when this registered handler is configured to work with non-asp.net applications also or do we also use this term when registered Http handler is configured to only work with Asp.Net applications?
A2. B. Yes, you can remove the "remove" as well as the "add" lines. This is what the GUI will do if you change it back to inherit the settings.
But in my case IIS 7 doesn’t remove
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="" />
from application’s root web.config file,,it just changes the value of preCondition attribute back to "managedHandler"
A3. I think you'll get an error if you try to add 2 modules that have the same "name" attribute. If you really want it in there twice then change the "name" of the 2nd one.
I apologize, I should be more specific, but my question was referring to a situation where two modules would have different names.
So in that case there will be two instances of FormsAuthenticationModule running?
thanx
Just noticed that you are using Stackoverflow. Please check my latest answers at iis.net.
http://forums.iis.net/t/1157580.aspx
An important thing is that applicationHost.config and root web.config actually have different meaning still, so don't be confused if an item appears in both files. That actually has different meanings.
A1. "integrated" vs "classic" processing pipelines is a property on the application pool. It is correct that modules can be set to run only in "integrated" pipelines.
A2.
A. In order to change the "preCondition" attribute, it had to remove the first version and add it again.
A2. B. Yes, you can remove the "remove" as well as the "add" lines. This is what the GUI will do if you change it back to inherit the settings.
A3. I think you'll get an error if you try to add 2 modules that have the same "name" attribute. If you really want it in there twice then change the "name" of the 2nd one.
Related
I'm trying to host my WCF service with a custom ServiceHost on IIS. I found a couple of articles on MSDN like this: Custom Service Host. Here, I'm supposed to add something to my services svc file, but I don't have one and I can't add one in visual studio either. Then I found this article: Configuration-Based Activation in IIS and WAS. This says
"The configuration-based activation feature removes the requirement to have a .svc file and therefore the associated overhead."
so I can just create a serviceHostingEnvironment entry in my Web.config (which I don't have either, but I guess App.config is equivalent since it contains my system.serviceModel configuration). However, I have to specify a relativeAddress for the service activation.
"The relativeAddress attribute must be set to a relative address such as <sub-directory>/service.svc or ~/<sub-directory/service.svc. "
So it should point to my svc file? I'm a bit confused, could you point me to the right direction?
I know documentation on MSDN is little confusing. Here is configuration that you need to put in web.confi/app.config
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="MyNonExistingServiceSVC.svc" service="MyService" factory=”MyServiceHostFactory”/>
</serviceActivations>
</serviceHostingEnvironment>
Here relative address will be just any dummy name. This name will be used to browse your service metadata. Please note that this name can be anything of your choice and it DOES NOT require same physical file to be present on disk. It just needs any name with .SVC extension.
So while accessing service metadata your URL will be
http://myserver/myservice/MyNonExistingServiceSVC.svc
I am using IIS7.5, .net 4.0. I am working locally.
I have installed Application Request Routing, Web Farm Framework, WebDeploy and UrlRewrite to set up a reverse proxy. This works fine for the most part.
I have two websites:
DefaultWebSite (port 80, app pool: Default App Pool (.net 4)) and
Target (port 8085, app pool: TargetAppPool(my identity, .net 4)).
I have a rewrite rule on DefaultWebSite (created as directed on IIS.net) which redirects all localhost (port 80) traffic to localhost:8085 just as detailed in the above link. This works fine for most document types (.aspx, .xap, .htm, .ico) but a request to MyService.svc fails. It returns a 404.
To be clear:
When I paste localhost:8085/MyService.svc into a browser I get the requested WCF page.
When I paste localhost/MyService.svc into a browser I get a 404.
When I paste localhost:8085/MyIcon.ico into a browser I get the requested resource.
When I paste localhost/MyIcon.ico into a browser I get the requested resource.
.svc is the only document type that I've found that returns a 404.
I've got two pieces of info that might be of relevance.
App Pools. When I change the DefaultWebSite's app pool to TargetAppPool then the 404 becomes a 500 ("Failed to map the path '/'"). All other requests are successful when this change is made. Not sure if this relevant or not.
FREB (Failed Request Tracing) Log. I found a page (http://blogs.msdn.com/b/asiatech/archive/2011/08/25/return-404-4-not-found-when-url-rewrite.aspx) which details the steps in a FREB log when a URL rewrite is more successful than mine (it fails later on). I've not been able to find out how to generate a FREB log for a successful rewrite (if that's possible) so I can only compare my FREB log to the one on that blog. I can see that their step 21 (URL_CHANGED) in my FREB log but not 22 (URL_REWRITE_END). I've not got enough experience with these logs to notice anything more significant than that (suggestions welcomed).
My main question is: does anyone know why just URLs requesting .svc resources are not being rewritten?
A secondary question is: does anyone know how to generate a FREB log for successful request (if it's even possible)?
Thanks
Update:
I have changed the architecture to try to get more info.
I have moved the Target website to a different PC on which I have installed Microsoft Network Monitor to capture the incoming traffic.
Before I changed the url-rewrite rule to point at this new website I got the correct response when I made a request to MyService.svc on the new PC. Fine.
As soon as I changed the rewrite rule to route the request to the new Target website then it responds as before (404). I have made both POST and GET requests. There is no sign of any of the requests in the Network Monitor log (all other calls -200, 404 or otherwise- appear in this log).
This leads me to think that there is something incompatible with url-rewrites and *.svc requests. I tried making a request to MyService.asmx (having created this file) and it correctly returned a page, so it is limited to *.svc. Any ideas?
The solution to this is in the config file of the Target web site.
In web.config (in the Target application) there is a section which read:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>.
I changed this to read:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />.
Credit must go to http://forums.iis.net/post/1956671.aspx for this (although s/he claims it is the proxy's config which needs to be changed, but I found it be the Target app, not the proxy server).
If you still can't get it running, make sure you don't have the WCF handlers on the website which acts as the reverse proxy.
I disabled this by adding this web.config of the reverse proxy:
<system.webServer>
...
<handlers>
<remove name="svc-ISAPI-4.0_64bit" />
<remove name="svc-ISAPI-4.0_32bit" />
<remove name="svc-Integrated-4.0" />
</handlers>
</system.webServer>
Because the rewrite appears to work for all resources except when the extension is .svc I would say this would be the area to concentrate on.
I would imagine that the rewrite rules are matching your other resources, but not your service, and because these are usually regular expressions (which are often complicated) I would say it would be worth testing any rules you find with your urls. Details of how to find the regular expressions for an UrlRewrite can be found here.
It is also probably also worth looking at any outbound rules with the same mindset.
I have two projects that is on iis like this:
inetpub/wwwroot/mysites/secure/web_application_1 --> has its own web.config
inetpub/wwwroot/mysites/secure/web_application_2 --> has its own web.config
The two applications are totally different applications, however, they both have their own client authentications & custom role & custom membership.
web_application_1 works fine as its the old application.
web_application_2 is the new application, when I ran it on the web, I got errors:
It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level.
I am not sure what is wrong in the web.config?
The web.config is same with the exception that:
connection strings is different as they both uses different db
custom membership & custom role is different as they both uses the namespace of the project
The whole IIS & URL was set up for web_application_1; and since it takes like forever to request new setup from my sysadmin, we both suggested i could just do this:
https://www.mywebsite.com/secure/web_application_1
inetpub/wwwroot/mysites/secure/web_application_1 --> has its own web.config
https://www.mywebsite.com/secure/web_application_2
inetpub/wwwroot/mysites/secure/web_application_2 --> has its own web.config
ok found my own solution:
Add the folder “web_application_2” as an application in IIS manager:
http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/b5488995-fa99-460f-96d7-29d1ddcf3fac.mspx?mfr=true
I am trying to build a webservice that manipulates http requests POST and GET.
Here is a sample:
public class CodebookHttpHandler: IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
if (context.Request.HttpMethod == "POST")
{
//DoHttpPostLogic();
}
else if (context.Request.HttpMethod == "GET")
{
//DoHttpGetLogic();
}
}
...
public void DoHttpPostLogic()
{
...
}
public void DoHttpGetLogic()
{
...
}
I need to deploy this but I am struggling how to start. Most online references show making a website, but really, all I want to do is respond when an HttpPost is sent. I don't know what to put in the website, just want that code to run.
Edit:
I am following this site as its exactly what I'm trying to do.
I have the website set up, I have the code for the handler in a .cs file, i have edited the web.config to add the handler for the file extension I need. Now I am at the step 3 where you tell IIS about this extension and map it to ASP.NET. Also I am using IIS 7 so interface is slightly different than the screenshots. This is the problem I have:
1) Go to website
2) Go to handler mappings
3) Go Add Script Map
4) request path - put the extension I want to handle
5) Executable- it seems i am told to set aspnet_isapi.dll here. Maybe this is incorrect?
6) Give name
7) Hit OK button:
Add Script Map
Do you want to allow this ISAPI extension? Click "Yes" to add the extension with an "Allowed" entry to the ISAPI and CGI Restrictions list or to update an existing extension entry to "Allowed" in the ISAPI and CGI Restrictions list.
Yes No Cancel
8) Hit Yes
Add Script Map
The specified module required by this handler is not in the modules list. If you are adding a script map handler mapping, the IsapiModule or the CgiModule must be in the modules list.
OK
edit 2: Have just figured out that that managed handler had something to do with handlers witten in managed code, script map was to help configuring an executable and module mapping to work with http Modules. So I should be using option 1 - Add Managed Handler.
I know what my request path is for the file extension... and I know name (can call it whatever I like), so it must be the Type field I am struggling with. In the applications folder (in IIS) so far I just have the MyHandler.cs and web.config (Of course also a file with the extension I am trying to create the handler for!)
edit3: progress
So now I have the code and the web.config set up I test to see If I can browse to the filename.CustomExtension file:
HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.
So in IIS7 I go to Handler Mappings and add it in. See this MSDN example, it is exactly what I am trying to follow
The class looks like this:
using System.Web;
namespace HandlerAttempt2
{
public class MyHandler : IHttpHandler
{
public MyHandler()
{
//TODO: Add constructor logic here
}
public void ProcessRequest(HttpContext context)
{
var objResponse = context.Response;
objResponse.Write("<html><body><h1>It just worked");
objResponse.Write("</body></html>");
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
I add the Handler in as follows:
Request path: *.whatever
Type: MyHandler (class name - this appears correct as per example!)
Name: whatever
Try to browse to the custom file again (this is in app pool as Integrated):
HTTP Error 500.21 - Internal Server Error
Handler "whatever" has a bad module "ManagedPipelineHandler" in its module list
Try to browse to the custom file again (this is in app pool as CLASSIC):
HTTP Error 404.17 - Not Found
The requested content appears to be script and will not be served by the static file handler.
Direct Questions
1) Does the website need to be in CLASSIC or INTEGRATED mode? I don't find any reference of this in the online material, whether it should be either.
2) Do I have to compile the MyHandler.cs to a .dll, or can I just leave it as .cs? Does it need to be in a bin folder, or just anywhere in root?
RE your questions:
I don't know the answer to the first one (CLASSIC or INTEGRATED); but I can help with the second...
Yes you'll need to compile it first. I have never tried deploying dll's to anywhere other than the bin, given that that's the standard I would be suspect in putting them anywhere else even if it did work.
The way I deploy HttpHandlers is quiet straight forward - all the hard work's done in web.config, I'v enever had to go into IIS to change any settings.
For a start, for the http request to be handled by ASP.NET you need to use a request suffix that's already piped to ASP.NET - like .aspx or ashx. If you want to use something else you will need to config IIS to do this, as per your managed handler img above.
I tend to use .ashx e.g: http://localhost/foo/my/httphandler/does/this.ashx
All you need to do (assuming you've compiled athe HttpHandler into a DLL and deployed it to the site) is add the necessary config.
<configuration>
<system.web>
<httpHandlers>
<add verb="*"
path="*.ashx"
type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
</httpHandlers>
</system.web>
</configuration>
Obviously (?) you can change / restrict the scope using the path, e.g:
path="*.ashx"
path="*ListWidgets.ashx"
path="*Admin/ListWidgets.ashx"
More info here: http://msdn.microsoft.com/en-us/library/ms820032.aspx
An important gotcha to look out for is the order in which you declare your HttpHandlers in the config; from what I remember ones declared first take precedent. So in this example...
<add verb="*" path="*foo.ashx" type="MyApp.PublishingSystem.HttpHandlers.FooHandler, MyApp.PublishingSystem" />
<add verb="*" path="*.ashx" type="MyApp.PublishingSystem.HttpHandlers.GroovyHandler, MyApp.PublishingSystem" />
...the groovy handler will handle all HttpRequests except any that end in foo.ashx
By the way, I make use of HttpHanldrs in my open source .net CMS / app framework, you might find some helpful code there (?): http://morphfolia.codeplex.com/
Make sure the app pool's .NET Framework Version is set correctly...
I deployed a .NET 4.0 web app on a .NET 2.0 app pool and got this error. Set the app pool to v4.X and the ashx was served like a champ.
We have a web application where we are using global.asax for url rewriting. We use a compiled version of the site on the live server.
As a part of modification request, we had to add some custom native AJAX code where javascript would call a webservice to update the content of the page. For being able to call the webservice with extension .asmx, we modified the url rewriting code to handle asmx requests seperately.
this arrangement works fine on the local machine, but when we publish the site and deploy it on the live server, the new code doesnt seem to get included. It still skips the condition to check the ".asmx" extension, and throws a page not found exception considering the webservice name as a page name.
We have tried looking all over and googled for such things as well.. but no avail..
any pointers on what might be going wrong.. ?
Assuming your URL rewriting is good (isn't that normally implemented as a HttpModule?) I'd check to make sure that there's an ISAPI mapping in IIS on production that sends .asmx requests to ASP.NET.
If you think your changes to the global.asax haven't been rejitted then you can always stop the application pool, go find your web applications compiled bits in c:\windows\microsoft.net\framework[version]\temporary asp.net files... and delete the jitted version. I've seen ASP.NET miss when it comes to Jitting changes before.
I'd also consider running http fiddler (IE) or tamper data (FireFox extension) on one of the pages that makes calls to the web service. It will tell you exactly how the page is calling the web service and you can validate that the called URL is correct.
There is machine.config file where you can add HttpModules. I also think that you can do that through web.config.
One reason I can think of is that in the Web.config, you might have configured the routing module in the system.web section but not in system.webServer (or at least forgot something in there).
I the similar problem before and the solution was to remove the module & add it again in the system.webServer section of the Web.config like this:
<system.webServer>
<modules>
<remove name="UrlRoutingModule" />
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, e="RoleManager" type="System.Web.Security.RoleManagerModule"/>
</modules>
</system.webServer>
It might be a different module or handler but the idea is basically the same. It's important to "remove" the module first.