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>
Related
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.
Basic question here (I think), I was hoping someone could point me in the right direction. I don't know much about WCF but I'd like to create a web service to be called from an ASP.Net MVC application. The goal is to make sure only authorized ASP.Net users (we're using forms authentication) can call the web service, not just anyone. Are there tutorials out there I can look at on how to approach this? Many thanks.
I assume from the question that you don't care what the end (MVC) user ID is that is hitting the WCF service (in other words you don't need a specific authenticated user to hit the WCF so you can get the ID of that specific user (i.e. so you know that joeBobUser hit the WCF)). you just want to make sure that user is authenticated and authorized to use the site. You don't need every potential user of your MVC app to be authenticated/authorized.
As long as that is true, then my approach would be as follows:
run your MVC app as a specific, known user account (i.e. set up the app pool in IIS to runas a domain user such as yourdomain\youMvcAccount) instead of the default asp account. There are lots sites that have instructions on how to make this happen if you are not already running your mvc app as a domain user.
set up your WCF service endpoint configuration binding as WsHttp. Again, many sites describe how to do this. here's one that does it via GUI (I prefer hand-editing the config but whatever). So now your WCF service will only accept secure, authenticated requests
create your WCF client proxy in the MVC app. easiest way to do this (probably not best re: separation of concerns, but just to get started) is just add new web service and discover you WCF endpoint that way. Again, basic stuff easily googable if you don't know how to do that.
Now your MVC app will be making the call to the WCF service authenticated. However, at this point, any client authenticated in your domain can call the service. You are now accepting ONLY authenticated but ANY authorized user. All calls issued from your MVC app hitting the WCF will be from the identity yourDomain\yourMvcApp
Restrict authorization to the identity set in #1 restricting (authorizing) authenticated users can be done a number of ways. The get'r'done fast way (but not very flexible as any change requires recompile) is just to check the identity of the request is the same as the identity of your WCF service directly in your service call. Alternatively, you can set up more robust (with the concurrently more goo) options such as AzMan or other WCF authentication rule sets. Again, many sites have instructions on setting that sort of thing up after you have an authenticated user. Here is a SO question that limits authorization to a windows group post (I'd do it that way--more flexible but you need to add that user to a group on your domain), and another article that goes more into the details of WCF security and allowing only a specific user access to the service.
I have a WCF web service, and I want to use Basic authentication. I am getting lost in the authentication options:
In IIS 6 Manager, I can go in to the properties of the web site and set authentication options.
In the web site's web.config file, under system.web, there is an <authentication mode="Windows"/> tag
In the web site's web.config file, under system.serviceModel, I can configure:
<wsHttpBinding>
<binding name="MyBinding">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</wsHttpBinding>
What is the difference between these three? How should each be configured?
Some context: I have a simple web site project that contains a single .svc web service, and I want it to use Basic authentication over SSL. (Also, I want it to not use Windows accounts, but maybe that is another question.)
The first two are really about access to an ASP.NET virtual directory or virtual application in IIS6 - that has basically nothing to do with WCF (WCF is actually not part nor dependent on ASP.NET). The settings control how the HTTP request coming into the IIS6 web server is being handled in terms of authentication. This basically controls whether anonymous callers from the internet can just call in without authenticating, or whether they need to enter username/password, or whether only callers with a valid Windows identity in this domain are allowed in.
The only reason this is interesting to your WCF service is the fact that when you host the WCF service in IIS (only one of the many options), then you have a (myservice).svc file that needs to reside inside a virtual directory. Of course, access to that SVC file is controlled by the authentication settings of IIS6/ASP.NET.
The security mode inside the <wsHttpBinding> section is the security-related definition of how the WCF service will communicate with its clients. Mode=Transport means, you're securing the actual transport layer - typically using SSL - not each message separately. This setting works great in Intranet scenarios where you have all clients behind a corporate firewall - but it won't work too well in Internet scenarios, since you can't really control the whole chain from the client (anywhere on this planet) over a series of intermediary hops to your server - you just can't. In this case, you'd have to use Mode=Message which basically encrypts and signs each message that goes over the wires - that works over any number of routers and relays along the way from the point of origin to your server.
The first two are related, if they don't match your service will not be able to activate. If you choose Windows authentication obviously there is an assumption that you will be tied to a windows domain or local machine.
Since you are going to be doing SSL basic authentication you are going to set this to None and then configure your transport security.
Your one stop shop for setting up transport + basic authentication
MSDN Article on Transport+Username + Windows Forms
I am not sure if you are still planning out how you are going to be doing security but i would recommend thinking about using message security versus transport(personal bias toward message security)..
Transport vs Message Comparison
Patterns & Practices on Message and Transport Security
I have this existing environment:
1) ASP.NET 3.5 web application
2) forms authentication with the SqlMembershipProvider
I need to add the following:
1) a Silverlight charting object embedded in a web page.
2) a WCF service to be consumed by:
a) the Silverlight component embedded in an authenticated
web page, as mentioned above
b) server-based WCF clients with certificate based authentication
My question is - what is the easiest/best way to configure the WCF endpoints for the Silverlight object to authenticate to the WCF service using the security context of the already logged-in user (via the page that’s hosting the Silverlight object) without having to use the user's username/password again?
I've researched a lot of the MSDN and Patterns & Practices material and I thought I had a decent grasp of many of the potential authentication scenarios. But I can't seem to figure out a way to tie them together for the scenario I've outlined. I've found other people posting similar questions to mine but none of the answers I've read seem to fully answer their questions either. (Maybe I'm making this harder than it needs to be?)
I would think that the solution would be to somehow use the authentication token/cookie generated in the asp.net form login and somehow pass that to the Silverlight object which then includes it in the WCF request. But I don't see how to configure the WCF endpoint to use that token.
(In some of my other projects I've implemented the server-to-server scenario in 2.b above using certificate-based authentication, so I'm not too worried about adding that to the current mix I've outlined.)
Thanks in advance for any insight or pointers to the path forward.
Terry
Thanks codemeit for trying to help but I finally figured out what I was doing wrong - it was pilot error.
In trying to configure the endpoints for my Silverlight app I was testing with an asp.net page. I finally realized that when I test that way, the client endpoint is no longer originating from the authenticated browser - the client endpoint is the IIS server which in turn executes the request against the WCF server endpoint. So the security context changes and HttpContext.Current.User.Identity is always empty at the WCF server endpoint.
Once I got my test SL app running in the browser, it automatically inherited the security context of the authenticated browser and then HttpContext.Current.User.Identity was correct and authenticated at the WCF server endpoint.
Have you tried to enable your WCF services with aspNet compatibility, then see if the following is true.
string currentUserName = HttpContext.Current.User.Identity.Name;
bool isLoggedIn = HttpContext.Current.User.Identity.IsAuthenticated;
if these properties are being populated with the expected values, then this is the one you are after.
To enable aspNet Compatibility
add to web.config
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
add to the service impl class
[AspNetCompatibilityRequirements
(RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
In this case, the endpoint would be using basicHttpBinding, and you could check the authentication at run time within WCF.
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).