views:

655

answers:

3

I have 2 web applications: one is an ASP.Net web app and the other is an ASP.Net WCF web services application. I want to the web app to the WFC web app's consume services. Eventually, these 2 apps will be communicating over a firewall.

I want the user to log on to the client web app using forms authentication, authenticated by the wcf service, and then to be able to access service resources based on his roles.

So far I have managed to log on using System.Web.ApplicationServices.AuthenticationService although I haven't been able to get the IsLoggedIn service method to return true. However, the client web app does recognise that the user has logged in.

Further, I have been able to create a dummy service that recognises the user in OperationContext.Current.ServiceSecurityContext.PrimaryIdentity and I thought that it was the logged in user that it was recognising but it turns out that it is actually the ServiceClient.ClientCredentials.UserName that it recognises. How can I pass through the details of the logged in user to the WCF service?

I could set the ClientCredentials.UserName to the logged on user but I can't think of a way to get the password.

Am I using completely the wrong approach here or is there something that I am missing? Any advice would be appreciated.

This is my binding configuration:

  <wsHttpBinding>
    <binding name="wsHttp">  
      <security mode="Message">  
        <message clientCredentialType="UserName"  
          negotiateServiceCredential="false"  
          establishSecurityContext="false"/>  
      </security> 
    </binding> 
  </wsHttpBinding>

Thanks, Iain

A: 

Hi Iain,

if I understood correctly, you need to pass your ASP.NET logged user credential to WCF service, right? Try this approach:


using (YourServiceClient client = new YourServiceClient())
{
     client.ClientCredentials.Windows.AllowedImpersonationLevel = 
          System.Security.Principal.TokenImpersonationLevel.Impersonation;
     client.ChannelFactory.Credentials.Windows.ClientCredential = 
          CredentialCache.DefaultNetworkCredentials;
     client.YourMethodHere();
}
Rubens Farias
Hi Rubens, thanks for your response.I'm afraid that doesn't work though because it is passing through the windows credentials rather than the forms authentication credentials.Thanks,Iain
Iain
A: 

You can definitely retrieve the currently logged on user in ASP.NET using the HttpContext.Current.User.Identity.Name property - trouble is, typically you don't have any way to retrieve the user's password to use for calling the WCF service.

It really depends on how you do your forms authentication. Do you have your own store? Does that store have user password's in it in a form that can be used, e.g. are the user's password stored in plain text (bad idea!) or in a reversible encryption schema?

Marc

marc_s
We are using the default sql server store so the passwords are one-way hashed so there is no way of retrieving them. We could store the password as the user initially logs on but that's something that we would definitely like to avoid. I think it would be preferable to hard-code a single user for all calls and pass through the logged-on user name as a parameter.
Iain
I was afraid of that :-) In this case, I don't really see how you could do this, unfortunately. What you could consider doing is having a certificate between your ASP.Net site and WCF service to authenticate, and send the "logged in" username as a message header for informational purposes. If your user is already authenticated against the ASP.NET web site, everything should be fine, right?
marc_s
A: 

I've been trying to do something similar in SharePoint. The best solution I've been able to come up with is:

 using (ChannelFactory<IMyContract> requestChannelFactory = new ChannelFactory<IMyContract>(binding, new EndpointAddress(endPointURL)))
 {
     provider = requestChannelFactory.CreateChannel();
     using (HostingEnvironment.Impersonate())
     {
         remoteData = provider.GetData();
     }
 }

This tries to authenticate me as DOMAIN\SERVER$ but unfortunately I haven't found a way to pull the client credentials out of HttpContext and shoehorn them into requestChannelFactory.Credentials.Windows.ClientCredential. I'm pretty sure it can't be done. The alternative seems to be hardcoding the username/password or using certificate authentication. That or allowing anonymous authentication which is not an option for me.

Repo Man