Reputation: 327
I have an MVC4 Web Application on Web Server A that is consuming the Dynamics CRM Web Service using the OrganizationServiceProxy, which is on Web Server B. The MVC4 application is setup with ASP .NET Impersonation and Windows Authentication enabled. When I call the WhoAmI I get an error:
'The caller was not authenticated by the service.'
Now if I move the MVC4 Application to Web Server B (same as CRM) with the same Authentication as it had on Web Server A it calls WhoAmI without an exception.
Here is the code being used to connect to the server.
string serviceURL = ConfigurationManager.AppSettings["CRMROOTURL"].ToString() + "XRMServices/2011/Organization.svc";
this.CRMService = GetCRMService(serviceURL);
private OrganizationServiceProxy GetCRMService(string serviceURL)
{
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
OrganizationServiceProxy client
= new OrganizationServiceProxy(new Uri(serviceURL), null, credentials, null);
return client;
}
Here is a screenshot of the authentication on the IIS Web Site.
Per the correct answer I just wanted to provide some snippets to help anyone else.
string loggedUser = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = new NetworkCredential(username, password, domain);
OrganizationServiceProxy client
= new OrganizationServiceProxy(new Uri(serviceURL), null, credentials, null);
client.ClientCredentials.Windows.ClientCredential = credentials.Windows.ClientCredential;
// -- Retrieve the user.
QueryExpression expression = new QueryExpression
{
EntityName = "systemuser",
ColumnSet = new ColumnSet("systemuserid")
};
expression.Criteria.AddCondition("domainname", ConditionOperator.Equal, loggedUser);
EntityCollection ec = client.RetrieveMultiple(expression);
if (ec.Entities.Count > 0)
{
// -- Impersonate the logged in user.
client.CallerId = ec.Entities[0].Id;
}
Thanks!
Upvotes: 3
Views: 10435
Reputation: 5914
Something stupid - be careful you aren't escaping your user name!
creds.Windows.ClientCredential = new NetworkCredential("domain\user", "PASSWORD");
Notice that the \u is an escape sequence - you need to type "domain\user".
Upvotes: 0
Reputation: 18895
Unless you explicitly state otherwise (and without any code to see how you are creating your OrganizationServiceProxy), on premise OrganizationServiceProxies will use the current AD account (of the service account, not the user's specific account) to connect to CRM. I'm guessing that the App pool you're running on Server A isn't a CRM user, and the one on Server B is. If so, either change Server A's user to be the same user as Server B, or make the Server A's user a user in CRM.
You're using the default network credentials to connect to CRM. This mean that no matter what IIS authentication you are using, you will connect to CRM as the App Pool User Account. This works as long as the App Pool user is a CRM user, but is probably not what you want.
You can set the network credential manually using this method:
creds.Windows.ClientCredential = new System.Net.NetworkCredential("UserId", "Password", "DomainName");
Then get the ASP.Net User's domain name and use impersonation to connect to CRM to ensure that all of the security for that individual is correctly applied.
Upvotes: 3