Saturday 11 June 2011

Microsoft Framework 4.0 WCF Service and IIS 7.5 Application Pool permissions

Hi,
Here is an article about how you can fix tonns of problems with IIS 7.5 and app pool permissions.
You probbaly created already WCF service in Visual Studio 2010, installed on Vindown 7, with intalled IIS 7.5. New version of IIS has ne security model and it cann affect your testing and if you don't know what to do, you can spend hours to find the problem.

Lets say you created new WCF project in Visual Studio 2010, set it as sturtup project and set startup svc file as startup page. When you run project in debug mode Visual Studio runs "Microsoft WCF test client". So far so good. you can see your wcf service definition in wcf test client:


you can find that it uses specific port. It is because by default Visual Studio uses "Visual Studio Development Server". It some cases it is fine to use development server, but in most cases development environment should be close to production configuration. It means that it is better to use IIS during development process, so you can test all scenarions, such as using Integrated or Classic application pool pipe line mode, 32 or 64 bit compatibility, security and many other things.
If you want to switch from "Visual Studio Development Server" to Microsoft Internet Information Server you should change project web properties as shown below:


It will ask you to confirm to create Application at IIS and it is pretty it, but ...... when you run project again you can find that "Microsoft WCF test client" starts show error:


here is sample an error, which you can get:

Error: Cannot import wsdl:portTypeDetail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporterError: Schema with target namespace 'http://tempuri.org/' could not be found.XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IService1']Error: Cannot import wsdl:bindingDetail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.XPath to wsdl:portType: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:portType[@name='IService1']XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='BasicHttpBinding_IService1']Error: Cannot import wsdl:portDetail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.XPath to wsdl:binding: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:binding[@name='BasicHttpBinding_IService1']XPath to Error Source: //wsdl:definitions[@targetNamespace='http://tempuri.org/']/wsdl:service[@name='Service1']/wsdl:port[@name='BasicHttpBinding_IService1']Warning: No code was generated.If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or servicesor because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool.Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.

The obvious question is why????? and the answer is Application pool permissions on temporary folder. In may case it is "c:\windows\temp".

Here are possible solutions:

1) If you have IIS version older than 7.5 just check application pool identity user and grant him full access to c:\windows\temp folder or simply switch app pool credentials to the user, which has full access to that folder. On a production it is usually should be resolved by first method.

2) If you have IIS 7.5, like in my case, the solution is a little bit tricky. Fist of all you will find that default application pool user identity is set to "ApplicationPoolIdentity" (in older iis versions default identity user was "network service").


Microsoft brought new security model to IIS, so you have to handle it in your solutions.
You can find more details about it in Microsoft article:
http://technet.microsoft.com/en-us/library/dd548356(WS.10).aspx
Virtual accounts - it is how they call it. It is the process to isolate physical account permissions from app pool permissions. It is make sense because IIS worker processes can run third-party code , such as Classic ASP, ASP.NET, PHP code ...., it was time to isolate IIS worker processes from other Windows system services and run IIS worker processes under unique identities.

Like in previous solution, you should grant access application pool access to windows temporary folder. You can do it by 2 ways:
2a) grant permissions directly to c:\windows\temp folder
right click on folder and select properties in popup menu. select security tab and click continue:



And here is a trick. If you application pool is set with "ApplicationPoolIdentity" you will not be able to find such user in list of local users. Instead of that you should use following user pattern:
IIS APPPOOL\<Application Pool Name>

for example: if application name is "MyTestAppPool", the user name should be
IIS APPPOOL\MyTestAppPool

a little bit unusual - isnt it?
You should select location as your local computer as shown below:


 in my case I used application pool with name "DefaultAppPool", so I selected "IIS APPPOOL\DefaultAppPool" and clicked "check names"

in the result you should see validated user:


these steps will resolve problems with application pool permissions.

2b) Add app pool identity user to local Administrators group.
Use this method for development purpose only, but not at production.
Just open computer management, select administrators group and add user by the same rule as described above.
Control panel->Administrative Tools->Computer Management.

select "Administrators" group,  right mouse click and select "Add to Group" menu option from popup menu as shown below:



all next steps in user select should be the same as described in 2a) step.

P.S.
Applying 1, 2a) or 2b) steps will fix an issue with adding reference in Visual Studio Project to wcf service (hosted by IIS 7.5) or by running "Microsoft WCF test client".

My current computer configuaration is:
Operation system: Windows 7 professional (32 bit)
Internet Information Server version: 7.5
Application Pool Pipeline mode: Integrated
Application pool account: ApplicationPoolIdentity

this arcicle can be also applicable to Windows 2008 R2 server.

10 comments:

  1. After an hour or two of annoyance I found your page here and solution 2a) worked for me on Win7 Pro (64-bit).

    Thanks very much!

    ReplyDelete
  2. Thank you so much. Soln 1 worked for me on Win 7 with IIS7

    ReplyDelete
  3. Thank you very much after one day struggling to find solution,I used the step 2 and now every thing is OK

    ReplyDelete
  4. Thank you save me a lot of time spent looking what was the issue, god bless you... :P

    ReplyDelete
  5. Steps described in step 2a works perfectly on Win2008R2 with IIS 7.5. Thanks Denis, you save the day :)

    ReplyDelete
  6. Thanks so much ^^! It is really helpful :-)

    ReplyDelete
  7. Thank you! This worked for me after a browsing the web for many hours. Keep up the awesome job

    ReplyDelete
  8. Keep sharing! My pool repair phoenix team appreciates this so much! Have a nice day.

    ReplyDelete
  9. This has saved me a lot of time, 2a worked great for me , I wish I had found this page ealier....I was trying to fix this for about an hour. Thanks

    ReplyDelete
  10. This is probably a) not the best way to handle temp files and b) not necessary as the plumbing for IIS takes care of temp storage in a way that should never enter into any issues you have. Most likely, giving admin access to an app pool solved some other issue that just appeared to be coming from the temp folder. Otherwise, people would be running into this all the time. Of the hundreds of web apps I've deployed, this has never been an issue so be careful going down this road. If you really want to eliminate temp storage as a concern, assign it on a per-app basis using web.config as described here: http://serverfault.com/questions/350550/is-it-possible-to-configure-the-location-of-temporary-asp-net-files-folder-in

    ReplyDelete