EWS - Using the service account for impersonation - wcf

In our organization we are trying to use EWS Managed API to access mailboxes from a custom UI client on Exchange 2010. We have a .NET 4.0 WCF service running on IIS 7.5 calling the EWS methods on behalf of the UI client. Client and WCF service communicate over https, so does the WCF service and EWS. We now want to create service accounts (basically AD accounts with impersonation rights on certain email inboxes) and run the WCF service under these service accounts. However, when I run the WCF service under a particular AD user in IIS (Anonymous authentication enabled with Anonymous user identity set to the specific AD user), EWS throws a 401 Unauthorized exception. Upon examining the ExchangeService object, the Credentials object is null. If I hardcode the credentials, the service can access EWS. Below is the code that I am using to create the ExchangeService object.
var service = new ExchangeService(ExchangeVersion.Exchange2010)
{
Url = new Uri(ConfigurationManager.AppSettings["EWSUrl"]),
// If I uncomment the below line, the service can access EWS. However, I want the user under which the service is running to access EWS.
//Credentials = new NetworkCredential("ImpersonatingUser", "secretPwd", "TESTDOMAIN"),
ImpersonatedUserId = new ImpersonatedUserId { Id = emailAddress, IdType = ConnectingIdType.SmtpAddress },
};
I read somewhere that the System.ServiceModel.ServiceSecurityContext.Current.WindowsIdentity object will have the current user under which the service is running. However, the System.ServiceModel.ServiceSecurityContext.Current context is null in my case.
How do I get the service account's credentials (without hardcoding it in the code) and pass it to EWS? Please let me know if you need more details.
Edit: In IIS 7.5, I have created a separate app pool running under the impersonating AD user's identity, and configured my WCF service to run in this app pool. Still can't get the service credentials.
Thanks in advance.

Unless your WebService runs on the Exchange box, you'll need to configure Kerberos. NTLM does not allow credential delegation.
Another option is to switch to Basic authentication secured with SSL. But this means to loose single sign on in your client application.

Related

WCF Service windows authentication

a WCF Service in hosted in our internal server. an external client will consume it and, our Service will consume our SharePoint service in order to edit an item list.
The WCF Service will have the automatically earn the windows authentication to access to the SharePoint site so I do not have to provide a login and password not domain name.
I am not sure how I am supposed to code my service:
NetworkCredential credential = CredentialCache.DefaultNetworkCredentials;
will be enough?
Architecture
But if you do need to use a specific account you could go for the following:
NetworkCredential credentials = new System.Net.NetworkCredential("name", "password", "optional:domain");
IMO, it should be enough, if your wcf and SharePoint services in same (or trusted) domains, and you select appropriative security mode.
See for more details:
http://msdn.microsoft.com/en-us/library/ms733836.aspx

WCF Changing credentials

I have a web app that calls a WCF web application with several services, all using basicHttBinding, on different servers (web server, app server and database server). One of the services has to connect to a database that must be called using an active directory account. Coming in from the web site the user is anonymous.
I have been given credentials to set this user to but I cannot get it to work. I create my channel on the web server like this:
ChannelFactory<T> channelFactory = GetChannelFactoryFromPool<T>(enpointAddress);
channelFactory.Credentials.Windows.ClientCredential.UserName = username;
channelFactory.Credentials.Windows.ClientCredential.Password = password;
channelFactory.Credentials.Windows.ClientCredential.Domain = domain;
proxy = channelFactory.CreateChannel();
In the service on the app server I am trying to determine if the credentials are correct by doing this:
var ssc = ServiceSecurityContext.Current;
but ssc is always null. Can this be done with basicHttpBinding?
Thanks,
Paul
The basicHttpBinding does support Windows authentication as documented in this good MSDN article. You also need to ensure the service operations are configured to allow impersonation of the client credentials to have the security context populated as expected.

accessing wcf client identity on service

After couples of WCF tutorials, I could develop a WCF client/Server application, both service and client applications are Windows Forms Application. I can call service using each client by specifying UserName and password. My WCF service applications also shows all the connected clients with their username as well. But, When multiple clients send a request to service then I'm not being able to identity which user has called the method. This is important as my application tend to have its own session for each client processing, just as any regular ASP.NET application has. Each user have their own Identity and its own Application Domain.
Moreover, I want my service to send messages back to client, so I have implemented callback contract. In addition, I'm using netTcpBinding as my applications need to run on my intranet.
How can I implement this scenario in WCF client/server application ?
Any help please ??
Thanks
Thanks for your previous reply. Its really helpful to me.
Now, What If I want to use custom authentication using username and password.
Lets assume that I have 50 clients with valid username and password. How can I get an identity of a client (out of those 50) whose is invoking a service method at a particular point of time ?
Thanks
In your server side code, you should be able to retrieve the caller's identity from the security context - something like:
if(ServiceSecurityContext.Current != null &&
ServiceSecurityContext.Current.PrimaryIdentity != null)
{
string userName = ServiceSecurityContext.Current.PrimaryIdentity.Name;
}
If you're calling a service with Windows authentication (which might also work for you - if you're on a corporate LAN, as it would seem) - you should be able to access the security context's .WindowsIdentity instead (this will be null for any other authencation mechanism).

Can WCF do WindowsAuthentication with username password?

I'm building an wcf service that is meant to run in an intranet environment using Windows Authentication. I have been merrily working along with some kind of default settings on the local computer.
Problem now is that I need to test it installed to an off site demo computer. I just need to get it running with username password used against the wcf service computer's user accounts.
This is my client code:
using (ImportServiceClient client = new ImportServiceClient("ImportServiceSoap12", REMOTE_ADDRESS))
{
client.ClientCredentials.Windows.AllowNtlm = true;
client.ClientCredentials.Windows.ClientCredential =
new NetworkCredential(userName, password, computerName);
result = client.Sync(items.ToArray());
}
Is it possible to configure the wcf service such that it translates the credential to a windows account on it's machine?
I've been reading contradicting posts here and there, but I feel rather sure IIS shouldn't be part of the authentication. I'm unsure wether ASP.Net authentication node applies or if it's all binding configuration.
Ideally I'd like it to be an NTLM type authentication so that I wouldn't need to set up https.
Is it possible to configure the wcf service such that it translates the credential to a windows account on its machine?
No. Integrated Windows Authentication requires that both the server and the client are part of the same domain (or domains with a trust relationship, in any case). You can't usefully run IWA against local computer accounts on the server.
You will have to use some other (potentially custom) form of authentication and then impersonate to the user you want to run as in the server code.

wcf and windows authentication

I like to use wcf (windows communication foundation) with windows authentication.
Do I need Active directory for this purpose?
How the server knows about the identity of the client?
If someone can found out the pass of the client that is using the wcf services, can he create the same user name on different computer and use the password to access the wcf services ?
Yes, if you want to use Windows authentication, you need Active Directory as the source where the user gets validated.
The way this happens is by means of a user "token" - when your client logs into his PC with his Windows credentials, the login process will check with AD whether the user is legit and issue a "token". This token is then used in calls to a WCF service to determine who it is that is calling the service.