ASP.NET Forms Auth For Downstream WCF Authentication and Authorization - asp.net

Development Environment: Windows 7 Enterprise with
.NET 4.0 with Visual Studio 2010
Production Environment: Windows 2008 Server with IIS 7.0
I'm trying to figure out the best way to authenticate and authorize against a WCF service running on a separate machine in a separate security zone from the ASP .NET web application.
Users log in with a username and password against credentials we have stored in a database. We did not implement Membership Provider, but when the user's credentials pass mustard, we manually create a Forms Auth ticket with the user id.
I did roll my own Role Provider that implements RoleProvider. As a result, we have "standard" ASP .NET roles along with a forms auth ticket working on our ASP .NET web application.
What I need to do is somehow pass these credentials along to the WCF service that's sitting on another machine. Originally, I thought I might use the Windows Identity Foundation and create a custom Security Token Service (STS). Basically, if the user authenticates, then create a token and add in the claims based authorization along with user identity into the token and pass that along to the WCF service.
We are currently using a .NET Remoting service (.NET 1.1 timeframe) that does not authenticate or authorize at all.
That seems like it might be a bit of overkill as there might be a way to simply pass along the information I currently have with the user as when you create the Forms Auth ticket, I know the current IPrinciple is set with the IIdentity set with a "name" property set to the user id on the Thread.CurrentIdentity.
I'm pretty sure IsInRole("WhateverRole") would work correctly at this point too, but all of this is on the Web application side. Nothing gets passed to the .NET Remoting service.
Looking at these two classes:
AuthenticationService Class
ServiceAuthorization Class
I don't think they are what I want. Likewise, I've read through Michele Bustamante's Learning WCF, but I don't really see this particular scenario covered. When I read about Windows Authentication, I keep thinking that needs to be tied into some internal NTLM or Kerberos associated with the internal Windows security situation. None of our users are internal users. They're strictly external.
Now, I know that if the user gets a Forms Auth ticket, they essentially get a valid IPrinciple and the roles should be set, right?
If so, is there a way to pass this along to a WCF service setting on another machine? If I set the WCF clientCredentialType to windows and set the serviceAuthorization principlePermissionMode to "UseAspNetRoles", will these be passed along in the security context from the web application to the WCF service when I make the service call?
Nothing I can find is clear on how this might happen. Thanks.

I think what you want is this:
http://thoughtorientedarchitecture.blogspot.com/2009/10/flowing-aspnet-forms-authentication.html
This isn't super secure, since you're effectively creating your own man-in-the-middle attack, but it's probably secure enough for most needs.
Essentially this boils down to this:
Configure both servers with the same MachineKey
Grab the FormsAuthentication cookie from the user request
Attach the cookie to the outgoing WCF service call
???
Profit

Related

How to protect a WCF Rest service with username and password?

I'm new in WCF and I want to know how can I protect a WCF Rest service.
I have an asp.net website, only registered users can access it, the application uses a service hosted on the same IIS server, my question is, how can I restrict the use of this service, for that only registered users may use it, knowing that the service can be used by many clients (Android, iPhone, ...). what type of authentication I can use? to test the service I created a winform and I use an HttpWebRequest.
PS: I cant use https.
Thanks
Simplest way is to use asp.net compatibility mode. The WCF service call will result in the same preprocessing used for ASP.NET pages, including checking the ASP.NET auth and session cookies. You will also be able to check HttpContext, including httpcontext.current.user.identity.isauthenticated. If the user is not authenticated, throw an exception or return an error code. Here is some more information: http://msdn.microsoft.com/en-us/library/aa702682.aspx.
So if you are already using forms auth for your application, and the service should be called after a user has logged in to your application, you are set.
You can also create an authentication service. The service will allow the client to send a username / password, and will use ASP.NET authentication to authenticate the user. It will send back an auth cookie, and then you can check future service calls as above. See http://msdn.microsoft.com/en-us/library/bb386582.aspx.
I believe the authentication service can called using json. See How to Call .NET AuthenticationService from json client without ASP.NET.

ASP.NET and WCF Authentication Options

What are the authentication options for having a ASP.NET web application communicating with a WCF service?
The scenario:
User enters their username and password in an ASP.NET form.
ASP.NET needs to pass this to WCF to authenticate the user.
If authenticated, the user can perform actions on the website. Each action would require sending data to different WCF operations. WCF needs to know who the user is on each call.
The easiest solution would be to store the username/password in the ASP.NET session state. However, this is insecure because the password is stored in memory on the server.
I would rather not use a certificate to authenticate the ASP.NET "client" to the service because there's a possibility that this WCF could be consumed by another client in addition to ASP.NET.
The best suggestion I've seen so far is to use Windows Identity Foundation (WIF). It appears that this requires an STS. According to MSDN, Microsoft does not seem to recommend setting up an STS through Visual Studio. There's no guarantee that an STS would be available in the deployment environment as some environments may use Active Directory and other environments may have a custom user store. Is it possible to setup a custom STS to authenticate against a custom user store? I'm having trouble finding documentation on doing this.
Are there any other options besides using WIF? What about a custom WCF authentication service that returns a token that can be used for authenticating against a primary WCF service?
The standard way of doing this is by using WIF with Microsoft's STS viz. Active Directory Federation Services v2.0 (ADFS).
There are a number of custom STS available e.g. Identity Server. This use a SQL DB as an attribute store. It's open source so could be adapted to whatever you require.
You can create your own custom attribute store: AD FS 2.0 Attribute Store Overview.
TechNet WIF / WCF: WIF and WCF.

Impersonate user in WCF from multiple callers

I'm using WCF services ensuring that UserName/Password must be provided for each request. I need use same service from many clients, but I need impersonate the call to access the appropriate resources for each client. When I call the service directly from the client there is no problem, because I use for each client a pair UserName/Password defined in theirs web.config. The problem came when I need to call a second Web service from a call to the first-one using the same identity. This second Web service requires UserName/Password, but I only know who is the caller (UserName) but not the password.
How I can impersonate this second call without knowing the password for the corresponding username?
EDIT: The app (Web App and Services) is running in a shared hosting environment where I can't use Windows Authentication to configure Kerberos for Delegation. I have defined a UserNameValidator to process on each call the pair UserName/Password against a custom SQLServer database. Moreover, the intended customers of this app will use it from Internet, without requiring a windows account, that is because I need a more flexible, SQL-based, authentication schema.
You need to look at using Kerberos to handle the passing of authentication onwards to other services from your first WCF service.
Have you taken a look at the declarative security options? The linked article by Juval Lowy includes an internet application scenario as well.

Need recommendations and help with ASP.NET + WCF + Security

i'd like to recieve comments on the way i'm trying to build an asp.net web application which uses a WCF service that is hosted in another asp.net application. Both applications will live on the same machine, but the app with the WCF service will not be accessible from the outside. there will be two web servers sharing the load behind a load balancer.
The app pool of both applications will use the same local user account (web server is not part of a domain) and so i was thinking to use WsHttpBinding with windows security for communication between client and internal wcf service.
The fron-end asp.net app uses forms authentication through a custom membership/role provider to athenticate and authorize users. The user database is in a sql server database.
i need to somehow pass to the wcf service the user details (username + roles) so that in the wcf it will be possible to validate and authorize according to the roles of who is logged in the front-end. I read i need to use "support tokens", but i haven't figured out how to use this.
I read also something about claims and WIF, which seems interesting but have no idea how i could use these in my scenario.
is there anyone who can give me recommendations about the architecture and maybe also show me how to pass the username to the wcf service and also show me if possible to use claims based authorization?
First of all, if both servers are behind the corporate firewall on a corporate LAN, I would strongly suggest using netTcpBinding instead of any http based binding. NetTcpBinding is much faster due to encoding the message in a binary format.
As for username / password: your ASP.NET front-end server could set the client credentials for the user calling for the WCF service - after all, the ASP.NET servers do have access to the ASP.NET membership database, don't they?
Or if you cannot pass on the user's credentials, you could pass on some headers to your WCF service that would describe the user - actually, you probably only ever need the user's unique ID - since the WCF service could fish out the rest of the info from the ASP.NET user database again, if really needed.
As for claims - I don't think they'd be a good idea here - you don't really have to deal with a multitude of different authorization schemes, and you're not using any federation (e.g. allowing users from a different company or domain to use your services) - so those obvious benefits probably won't really be applicable to your case.

WCF Service - ASP.net hosting - single sign on, how to pass credentials

My scenario is this - I have two ASP.net websites. Both sites run on the same machine and I have implemented single sign on relatively simply using the default asp.net membership provider (Forms based authentication).
I have a new WCF service on one site, which will be called from the other site. A user will be logged into the site, but the call to the service will be made from the codebehind following a postback.
Can somebody point me in the right direction so that I can pass through the Forms based credentials of the logged in user to the WCF service on the other site? Presently it's passing the NETWORKSERVICE windows credentials.
Check out the WCF Security Guidance on CodePlex, and most notably:
How To – Use Username Authentication with the SQL Server Membership Provider and Message Security in WCF from Windows Forms
It shows quite nicely, step by step, what config you need on the server to make your WCF service use message security with user authentication against an ASP.NET membership store.
Also check out the article Fundamentals of WCF Security - page 3 shows the options about authentication and authorization - quite informative as well!
Hope this helps!
Sounds like you're after Impersonation, which would allow you to pass on the original caller's identity to the second service call.
See the CodePlex Link - Impersonation in WCF

Resources