Does the svc file for a WCF always need anonymous access? - wcf

Is it necessary to allow anonymous access for a svc file when hosting WCF in IIS 7.5? If yes, then why is such an access needed?
LATEST UPDATE
I found that svc doesn't need anonymous access. I think I was getting an error that seemed to be related to svc but wasn't. I am using the following security for the hosting website in IIS 7.5.
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
<windowsAuthentication enabled="true" />
</authentication>
</security>

I found the answer, thanks to Voltagex. This answer is explained under LATEST UPDATE in my initial post. However, I am mentioning it here also.
I found that svc doesn't need anonymous access. I think I was getting an error that seemed to be related to svc but wasn't. I am using the following security for the hosting website in IIS 7.5. SVC access is closely related to the security you have specified for the website hosting your WCF. In my case, I used the following security for the hosting website, where I needed to turn off anonymous access and allow only authenticated users to access the host website file resources like svc files.
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
<windowsAuthentication enabled="true" />
</authentication>
</security>

Related

Why won't Authorization Rules in IIS restrict access to my WCF service?

I have a standalone WCF service hosted in IIS 10. I would like to restrict access to the web service to a select group of users. I was able to do this for a web application by doing the following in IIS:
Authentication: Windows Authentication only (disabled Anonymous Authentication)
Authorization Rules: Allow a predefined group (i.e., Roles)
However, when I do the above steps for the web service, and changed clientCredentialType="Windows" in its web.config, it still allows any user from the domain to talk to it. Am I missing something obvious? Do web services function differently than web applications in terms of configuring authorization? Given my setup I would expect only users in the MyTestGroup to be able to talk with the web service, and all others getting 401 - Unauthorized.
As an aside, I tried setting up "Deny Everyone" rules but domain users could still talk to the web service, so I feel like the Authorization settings aren't being effectuated somehow. Looking for any insight on this.
Here are the relevant web.config contents:
<system.serviceModel>
<services>
<service name="StudyManagement.StudyManagement">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="secureHttpBinding" name="StudyManagement" contract="StudyManagement.IStudyManagement" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="1048576" />
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="false" />
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Allow" users="" roles="MyAllowGroup" />
</authorization>
</security>
</system.webServer>
You can refer to this website to re-create the authorization rules. In addition, the authorization of wcf services can use ServiceAuthenticationmanager, examples and tutorials.
The following Microsoft documentation helped to answer my question:
WCF services and ASP.NET
Important takeaways:
The ASP.NET HTTP runtime handles ASP.NET requests but does not participate in the processing of requests destined for WCF services, even though these services are hosted in the same AppDomain as is the ASP.NET content. Instead, the WCF Service Model intercepts messages addressed to WCF services and routes them through the WCF transport/channel stack.
Within an AppDomain, features implemented by the HTTP runtime apply to ASP.NET content but not to WCF. Many HTTP-specific features of the ASP.NET application platform do not apply to WCF Services hosted inside of an AppDomain that contains ASP.NET content. Examples of these features include the following:
File-based authorization: The WCF security model does not allow for the access control list (ACL) applied to the .svc file of the service when deciding if a service request is authorized.
Configuration-based URL Authorization: Similarly, the WCF security model does not adhere to any URL-based authorization rules specified in System.Web’s configuration element. These settings are ignored for WCF requests if a service resides in a URL space secured by ASP.NET’s URL authorization rules.
Solution:
Use ASP.NET Compatibility Mode by configuring web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Unlike the default side-by-side configuration, where the WCF hosting infrastructure intercepts WCF messages and routes them out of the HTTP pipeline, WCF services running in ASP.NET Compatibility Mode participate fully in the ASP.NET HTTP request lifecycle. In compatibility mode, WCF services use the HTTP pipeline through an IHttpHandler implementation, similar to the way requests for ASPX pages and ASMX Web services are handled. As a result, WCF behaves identically to ASMX with respect to the following ASP.NET features:
File-based authorization: WCF services running in ASP.NET compatibility mode can be secure by attaching file system access control lists (ACLs) to the service’s .svc file.
Configurable URL authorization: ASP.NET’s URL authorization rules are enforced for WCF requests when the WCF service is running in ASP.NET Compatibility Mode.
I recommend reading the entire article for additional information. It's a short and helpful read.
Thanks to #Shiraz Bhaiji for the article reference on WCF Authorization using IIS and ACLs.

IIS Anonymous Authentication enabled but credentials required

We have a some web services hosted in IIS8 that were running fine with anonymous authentication set. Then a couple of days ago anonymous authentication was disabled in favour for windows authentication which made it impossible to connect to the web services. Now we have reverted to anonymous authentication but the site still asks for windows credentials:
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'Negotiate,NTLM'.
What we have done is this:
in web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="CustomHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
and in IIS Manager we only have Anonymous Authentication checked:
In the applicationHost.config file everything seems correct:
<location path="Path/WebServices">
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="false" useKernelMode="true">
<providers>
<clear />
<add value="NTLM" />
<add value="Negotiate" />
</providers>
<extendedProtection tokenChecking="None" />
</windowsAuthentication>
<anonymousAuthentication enabled="true" />
<basicAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
App-pools, site, and server have all been restarted/recycled.
Where else should I look? Thanks.
I agree that everything looks correct from what you've shown. I would recommend reviewing all your visible configuration for any anonymous/Windows auth that may apply that you may not be seeing. To do this, in IIS Manager click on the Server on the Left, then select Configuration Editor. On the right, select Search Configuration. The search at the top only accepts "section names" so things like WindowsAuthentication and AnonymousAuthentication are good searches. Review each place in your config that may apply to your site/app.
It turned out that the DNS pointed to a different server than the one I was doing my changes in.

ASP.NET Core disable Windows Authentication

I have .NET Core MVC web application where during creation I set Windows authentication. Now I want to disable Windows authentication and enable anonymous authentication (I have my own authentication mechanism). Here is what I have set in my config file
.vs\config\applicationhost.config
<security>
<authentication>
<anonymousAuthentication enabled="true" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
My problem is that when I reopen the solution and run it, the config is changing to:
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
How it's possible that something is changing the config and what should I do to prevent this change?
The file is managed by Visual Studio and it is being regenerated.
To disable Windows Authentication, you must change project settings is Visual Studio. This setting is stored in the launchSettings.json file and Visual Studio generates applicationhost.config for the IIS Express process - when ASP.NET Core is hosted in the IIS Express.
Details about this configuration are here: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-2.2

Allow access to WCF based on a group set in web.config

I have created a WCF service that uses windows authentication and would like to set it so it can only be accessed if the user is in a Windows group. I Currently use the following attribute in code to make this happen
[PrincipalPermission(SecurityAction.Demand, Role = "Domain\MyGroup")]
Problem with this is I have to do it on each method and compile if I want to change the group. Is there a way so I can set the group that has access in the config file and for the services as an whole?
I have tried the following in my config file but this does not appear to work
<security>
<authentication>
<windowsAuthentication authPersistSingleRequest="true" enabled="true"/>
</authentication>
<authorization>
<add accessType="Allow" roles="Domain\MyGroup" />
</authorization>
</security>
Ok I figured it out. I have the config file set like the following
<security>
<authentication>
<windowsAuthentication enabled="true" />
</authentication>
<authorization>
<remove users="*" roles="" verbs="" />
<remove users="?" roles="" verbs="" />
<add accessType="Deny" users="?" />
<add accessType="Allow" roles="Domain\MyGroup" />
</authorization>
</security>
Also had to set
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
And on my class that implements the WCF contract
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
I guess this means Im using ASP authentication rather than WCF but I works for me
The PrincipalPermission attribute is from the .NET code access security functionality and isn't related to WCF. A more flexible way to do this if the service is hosted in IIS is shown in this MSDN post. WCF also supports different custom authentication mechanisms as described here.

Webservice does not seem to be doing any authentication despite config in IIS7.5

The Problem
I have a WCF webservice that I am hosting as a webservice in IIS7.5. I want this service to only be accessible by two groups. The webservice is running successfully, although there does not seem to be any authentication being done.
I was under the impression ( having read gobs of MSDN pages attesting to this) that all one really had to do was enable Windows Authentication on the Application site, disable Anonymous Authentication, set the mode to windows in the web.config and add Allow/Deny rules to the authorization section as diaplayed below:
<system.web>
<authentication mode="Windows" />
<compilation debug="false" strict="false" explicit="true" targetFramework="4.0" />
<pages /> <!-- Omitted -->
<authorization>
<allow roles="Managers" />
<allow roles="Operations" />
<deny users="*" />
<deny users="?" />
</authorization>
</system.web>
With the above steps and web.config changes done, and after going to the Authorization page in IIS and reloading the Auth rules, calling the service through the WCFTestclient shows it working flawlessly. Except I am not part of either of those two groups...
The Questions
It looks like it is just letting anyone in. My questions are these:
Is there a way to see passed and failed authentication checks on the webservice? (If so, I can see if any kind of authentication is going on).
Does the above look correct? It seems a bit simple, but given the Microsoft Method, it is not far fetched that something so standard would be fairly simple to set up.
Bottom-line
I have a service with the above web.config file, and an IIS7.5 instance with Windows Authentication installed and enabled. Anonymous Authentication is disabled. Auth rules are defined for two groups to have access, and all others to be denied and yet despite the fact that I am in those groups, I can access the service.
EDIT:
So I appear to have authentication working. If I only have the Allow All Users rule in place, I have access to the webservice. If I enact a Deny All Users rule, I no longer have access. However, if I add my account ("domain\MyAccount" as an allow (regardless of position in the web.config) I still don't have access.
What I have changed to get here,
Added the following to the service definition:
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
Added the following to the web.config:
<system.web>
<authentication mode="Windows"/>
<authorization>
<deny users="*"/>
<allow users="sierra\cblissittekeps"/>
</authorization>
</system.web>
and
<system.servicemodel>
<bindings>
<basicHttpBinding>
<binding name="ADServiceBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<system.servicemodel>
Alright! So apparently the steps I took in the original post are not in fact enough. You have to add that aspnetcompatabilityrequirements attribute to the service class (which implements your service iterface), you have to add to the serviceHostingEnvironment tag an aspNetCompatibility attribute:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"
aspNetCompatibilityEnabled="true" />
And, something that no-one seems to mention, the order of your Allow/Deny rules makes a difference. Adding an allow AFTER a Deny All Users means that all users are still denied. Putting it before means that all users are denied except the ones in the allow.