After having searched for an answer thoroughly on SO, I have to ask my first question for good this time !
Here goes :
I have a Windows Forms app, which uses a dozen WCF services to handle all the business logic.
WIF is implemented on every single WCF service, and users are authenticated through a basic UserName authentication.
Everything works well except the Ping() method that we have.
Before WIF was implemented, we used to call every WCF service with a dummy Ping() method during the splash screen to ensure the service was up, but now the user can't access this method since he's not logged yet.
Is there a way to distinguish Authenticated and Anonymous Methods in a service on which WIF is implemented ? I suppose there isn't, so I'd like to know if maybe an anonymous token could be issued by the STS ?
I'm pretty out of ideas right now, so any help or just some hints would be greatly appreciated :)
Depending on your configuration, you could create a set of services within a specific folder in your site, then add custom configuration to that location that would not include the Authentication and Session modules.
As an example:
<location path="AnonymousServices">
<system.webServer>
<modules>
<remove name="WSFederationAuthenticationModule" />
<remove name="SessionAuthenticationModule" />
</modules>
</system.webServer>
</location>
I have not tried this in practice, but it should work.
Related
Windows Server 2012 R2, IIS 8
I did some more diagnostics. What is it about this line in the web.config file which overrides the Authentication configuration specified in IIS?
<configuration>
<system.webServer>
<modules>
<add name="Webhook" type="MyApp.Webhook" preCondition="" />
</modules>
</system.webServer>
</configuration>
I copied my Webhook folder to a Webgate folder and mapped the Webgate site to the Webgate folder. Through trial and error I can see that as long as that module is defined in the web.config file, the site can be accessed anonymously. As soon as I remove that line, I see the 401 Unauthorized on an anonymous request. Strange, why should the specification of my module which handles request, override the IIS specification which stipulates that request must be authenticated before they can be executed?
Here is the original question with the background on what I've been trying to do and the problem I've been having:
I have a web application - Webgate - set up to Disallow Anonymous access. Here's what this looks like:
The problem is, when I use Postman to interact with this application without any Authentication, the transaction succeeds. Here's what this looks like:
How can this be?
One more screenshot to confirm that this is the application which answers to that URL:
Here is the one complexity, although I fail to see how this could have anything to do with the issue. Both Webgate and Webhook (see screenshot above) are two sites within IIS which are mapped to the same web application in the filesystem. Webgate is configured to insist on Authentication, Webhook is configured to allow Anonymous access. Again, I fail to see how Webhook's allowance of Anonymous access could have any impact on a transaction which comes in on the Webgate binding. Some background for context: Application capabilities when coming in via Webgate will be a superset of what is accessible via Webhook. Security can't be short-circuited by coming in on the wrong interface because transactions are checked at the application level to confirm whether the current transaction is identified or anonymous. The whole purpose of the two sites is so that accesses via the open interface - Webhook - are never challenged for identity, whereas transactions coming in on the protected interface - Webgate - are always challenged for Authentication.
I've done this before, although not recently, and I've never run into this problem. There is that little complexity, but bottom line, if a site is set up to disallow Anonymous access and insist on Basic Authentication, how are transactions getting through without being challenged? That is something I have never seen before. Thank you for your advice.
The Issue Revisited
To summarize what we learned so far,
You wrote a managed module for ASP.NET.
This module hooks to pipeline event OnBeginRequest to perform some business logic and calls ctx.ApplicationInstance.CompleteRequest() when finishing.
Anonymous authentication was used on IIS side.
Everything works fine there, but you found that,
When Basic authentication is used on IIS side things started to break in integrated pipeline mode
Switching back to classic mode seems to solve it.
The Cause
Your module works in classic mode no matter what authentication method is used, because the whole ASP.NET pipeline runs behind IIS authentication module.
However, integrated mode works differently from classic mode, where your module no longer executes behind authentication but ahead of.
You confirmed that by collecting FRT.
The Solution
Like we discussed, the solution is to simply change your module so that it hooks to OnPostAuthenticateRequest instead.
References
Microsoft published the pipeline changes in an important article, so everyone should get familiar with the details.
Migrating from classic to integrated requires a good guide
FRT is always a handy helper for module/handler developers
I have an ASP.NET WebApi application running locally using IISExpress that allows me to accept requests from any domain. I am doing this using a DelegatingHandler similar to the one provided one this blob post.
Locally this runs perfectly however after uploading to an Azure Website, I get the typical 'Origin http://localhost:8080 is not allowed by Access-Control-Allow-Origin.' under Chrome.
I've tried to debug this by adding trace statements into the Handler with no output and it seems like SendAsync is never being executed, almost as if IIS is responding to the OPTIONS request instead of passing it on to my application.
Has anyone come across anything similar going from development to production?
IIS (including the one in your Azure web site) has a default OPTIONS handler. You will need to remove it in Web.config. It answers the OPTIONS call before your message handler has an opportunity to respond.
<configuration>
...
<system.webServer>
<handlers>
<remove name="OPTIONSVerbHandler" />
...
</handlers>
</system.webServer>
</configuration>
I am learning and designing a WCF service. I have picked to use Windows credential as the authentication method, and I have configured it correctly, hopefully, because I can see the authentication audit log from event log viewer when I am testing my service hosted in the local machine.
But now I come up with this weird question: what users will not be authenticated under such configuration? Does my service authenticate all Windows user within the same Windows domain, or can I specify what specific users within my domain will/will not get authenticated?
Or, does it mean that I can only control what users (in my domain) can perform what operations my service is providing through authorization(that I know how to do)?
It sounds simple but all the material I found only tell you how to perform authentication, doesn't say how to deny authentication request.
Update:
After reading #syneptody answer, I still have two questions:
I must say my confusion between authentication and authorization is still there. The authentication means to identify the user. But if I want to tell a user belonging to the same domain as the service host(it's IIS, by the way), who just makes a request to my service, "you are not authenticated", what I really should say is "I do authenticate you, but you are not authorized (to perform your request)", is it right? There is not a state of "Unauthenticated" for a user in my domain? And what if a user not belonging to my domain makes a request? My service will tell him "You are not authenticated" or "You are not authorized"? As long as this user has an identity, the service will authenticate it, and continue to investigate whether it should be authorized?
#syneptody mentioned This "authorization" element. It belongs to ASP.NET, and it specifies which roles can/can't access the resource (whether it is the website or an application hosted in the website, depending on which Web.config file it is in). Is it right? But what if I don't use ASP.NET or don't host the WCF in ASP.NET Compatibility Mode, will it still work like that? Actually the requirement for us is to only provide the service, so I didn't think of using ASP.NET because in my opinion it is more like a web client consuming my service.
By the way, my usage scenario is this service will be hosted and consumed within intranet. So I choose Windows credential for authentication and Windows Groups for role-based authorization because it requires minimum work in my opinion.
Take a look at this article:
http://msdn.microsoft.com/en-us/library/aa702682.aspx
It does a pretty good job explaining the connection between WCF and ASP.NET. If you are able to run your services in ASP.NET compatibility mode you can use the ASP.NET authorization rules. In a domain environment where you can leverage Integrated Authentication there is no easier way to provide authorization to your services.
Your service implementation:
[AspNetCompatibilityRequirements(RequirementsMode AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior]
public class Foo { ... }
Then in your configuration:
<system.web>
<authorization>
<allow users="?" />
<allow roles="DOMAIN_SECURITY_GROUP" />
<deny users="*" />
</authorization>
<authentication mode="Windows" />
<identity impersonate="false" />
</system.web>
i'm trying to secure some WCF services. I'd like to use IIS or the Web.config todo all of the heavy lifting/configuration if possible. I don't want to embed anything in my code - thought I know that may not be feasible. If possible, I'd like to achieve this without having to resort to AspCompatibilityMode :(
I'm using a custom BasicHttp binding with TransportCredential enabled.
This works fine. Any valid domain or machine account seems to validate against the service.
My problem is I only want users from specific windows groups to be able to access my service. I wanted to use ACLs on the actual folders to achieve this, but I don't think it is possible.
Would appreciate your help!
Thanks
TM
In your web.config try the following:
<authentication mode="Windows" />
<identity impersonate="false" />
<authorization>
<allow users="MYDOMAIN\YourGroup" />
<deny users="*" />
</authorization>
This will block it at the web config level. You can also put an ACL on your folder. Note the Windows authentication and the impersonate = false means that it is the users credentials that are being used to access the directory.
I have a silverlight application that calls my wcf services so its a basichttpbinding. and we use forms authentication. I want to do a authentication check for every call that I receive except for the "AuthenticationService" (as this is the method which will do the basic authentication for login) so after user logs in and tries to call other services then I want this authentication check to be performed so that only authenticated users will be granted access to them. Is there is any best way to implement this... ???
After searching through various blogs, I came to know that we can use HttpContext.Current....IsAuthenticated property to check if user is authenticated or not. But my question is how secure and valid is HttpContext? Can we rely on that? or should we be using OperationContext? (and yes aspnetcompatability is set to true).
Please suggest!!
Thanks in advance
Sai
If you're hosting your WCF services in the ASP.NET runtime (i.e. <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />) then you should absolutely be able to rely on ASP.NET's security system.
Check out this answer I gave to another question on how to leverage ASP.NET security for ASMX services. The same approach can be used to secure a WCF service as long as you're enabling ASP.NET as your service hosting environment.
Here are some articles that may help:
http://msdn.microsoft.com/en-us/library/dd560702(VS.95).aspx
http://silverlightuk.blogspot.com/2008/03/silverlight-wcf-and-aspnet.html
http://smehrozalam.wordpress.com/2009/01/07/securing-silverlight-application-and-wcf-service-using-aspnet-authentication-techniques/
Short answer is you can use the asp.net controls to do authorization, or use HttpContext.Current directly (as long as AspNetCompatMode is enabled).