So I routinely use windows authentication on internal applications at my current job. Lately we have been using the WebAPI framework with MVC to expose more REST services from these apps as well. We always want to lock down screens to users that should have access, however web API's we are less restrictive with, though mixing the two practices is a bit strange in the same application.
After some head scratching, this is how its done. So first, to limit the app to only authenticated users, we use this in the web.config under system.web
<authentication mode="Windows" />
<deny users="?" />
Its rather simple, it just requires all users be authenticated through windows. We implemented a version of the entity framework to tie these to a custom role database for users on applications to lock down individual controller functions, but that's code for a different post. This post will look at how to expose the API as unauthenticated. How we do this is to add this to the web.config (as well as the above), this time under the configuration tag.
<!-- All anonymous users access to the virtual path api -->
<allow users="?" />
<!-- Need to include the security overrides else it will inherit from the root of the application -->
<validation validateIntegratedModeConfiguration="false" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
So in short, this adds a second set of configs for things under the path API (which you need to make sure your api functions are under that url) to allow users ?. I also needed to add system.webserver info that I copied from the existing one so all the plugins I have would work as well. That should do it, you should have anonymous access to API now.