CRM 2011 on premise custom ASPX page integration
-
Monday, April 30, 2012 4:25 PM
Good Morning,
We are running CRM 2011 on premise, within a single domain environment.
I've taken a very basic C# app from this blog --> http://blogs.msdn.com/b/crminthefield/archive/2011/05/18/how-to-create-a-simple-webpage-leveraging-the-crm-2011-iorganizationservice-web-service.aspx and got it working in Cassini - just adds a contact based on some text fields. I published this app to IIS and have it set to utilize Windows Authentication. I tried to access it as a test user with an associated CRM user account, and received the following error:
The request for security token could not be satisfied because authentication failed.
This leads me to 2 questions.
1. For internal access on a single domain with custom aspx applications interfacing with our CRM deployment - do I need to install federated services?
2. If not, is there a post that describes the correct way to set up a custom ASPX page and associated IIS Pool to allow windows authentication to work without getting the error stated above?
Any help provided would be appreciated
Thanks,
Paul
All Replies
-
Monday, April 30, 2012 4:42 PMAnswerer
Hi PaBocc,
For an OnPrem deployment that is always being accessed via the local intranet, you don't need to use Claims Authentication.
I suspect you issue is that code is assuming that the IIS App Pool is running as a Crm User - or a user that is part of the PrivUserGroup {xxx} group.
A quick test would be to use something like:
credentials.Windows.ClientCredential = new System.Net.NetworkCredential(userName, password, domain)You can store your password securely in your web.config.
hth,
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Monday, April 30, 2012 5:42 PM
Scott,
Thanks for the follow up. I'm not trying to hard code the credentials, what I would like to be able to do is take the credentials of the user accessing the custom web page, and use those for CRUD functions against the CRM 2011 application. My suspicion is that the app pool credentials from the web server are causing my headaches, and what I'm looking for is the correct way to maneuver around this issue.
Thanks again.
Paul
-
Monday, April 30, 2012 6:27 PMAnswerer
Hi Paul,
What you need to do is get the current principle user logon name (http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal.aspx) and use that to lookup against CRM to get the userid. Then when you call the SDK webservices you can specify the CallerID (http://technet.microsoft.com/en-us/library/microsoft.xrm.sdk.client.organizationserviceproxy.callerid.aspx) - provided the App Pool (or what ever user you provide as the credentials) as act on behalf of another user rights or is in the PrivUserGroup, you can perform an action as the current logged on user.
hth,
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Monday, April 30, 2012 8:25 PM
Hi Scott,
I started going down the path of pulling the current prinicipal, however, how do I do a lookup against CRM without actually calling a web service - this is where I'm failing on the IIS server. The App Pool can't talk to the CRM service this is where the security errors are occurring. I've set the App Pool identity to run as a user that both has access to the CRM 2011 application, as well as belongs to the PrivUserGroup. Was this the correct interpretation of your message?
Thanks,
Paul
-
Monday, April 30, 2012 8:30 PM
Configure the Web Application within IIS for Windows Authentication AND Impersonation. When the user is authenticated, your code will then run under the credentials of that logged in user.
Impersonation can be configured via the IIS Management console or your web.config.
--pogo (pat) @ pogo69.wordpress.com
-
Monday, April 30, 2012 8:34 PMAnswerer
Hi Pogo,
Good point - but I tend not to recommend this approach because of the double hop kerberos issue - it works if you've got the ASPX page in the same App Pool on the same server - but if you don't have kerberos configured to accept impersonation across machine boundaries it effectively tries to authenticate as the anonymous user.
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Monday, April 30, 2012 8:37 PMAnswerer
Hi Paul,
Ah - I see - you need to be able to call the webservices as a privileged user - passing some credentials that are accepted.
Your website should *not* be using impersonation. Could you try passing a domainname, username and password explicitly to check that it is working - then we know it must be something to do with the App Pool identitiy.
hth,
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"- Edited by Scott DurowMicrosoft Community Contributor, Editor Monday, April 30, 2012 8:37 PM
-
Monday, April 30, 2012 8:38 PM
Hi Pogo,
The web application is set to use Windows Auth and is set for impersonation (with the application pool set to classic for the managed pipeline mode). I still get the same error -->
Server Error in '/' Application.
--------------------------------------------------------------------------------The request for security token could not be satisfied because authentication failed.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.Exception Details: System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[FaultException: The request for security token could not be satisfied because authentication failed.]
System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target) +5574446
System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState) +49[SecurityNegotiationException: The caller was not authenticated by the service.]
System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) +9460671
System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) +345
Microsoft.Xrm.Sdk.IOrganizationService.Create(Entity entity) +0
Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.CreateCore(Entity entity) +281
Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Create(Entity entity) +13
_Default.Button1_Click(Object sender, EventArgs e) +655
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272 -
Monday, April 30, 2012 8:41 PMAnswererYou should *not* be using impersonation!
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Monday, April 30, 2012 8:43 PMAnswerer
Try writing out the following using ASP.NET Response.Write:
IPrincipal threadPrincipal = Thread.CurrentPrincipal; Response.Write(String.Format("Name: {0}\nIsAuthenticated: {1}" + "\nAuthenticationType: {2}", threadPrincipal.Identity.Name, threadPrincipal.Identity.IsAuthenticated, threadPrincipal.Identity.AuthenticationType));
What do you get? It should the CRM User that you've configured in the AppPool.
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Monday, April 30, 2012 9:04 PM
Hi Scott,
The code above specifies the current user accessing the test site, not the AppPool user.
Paul
-
Monday, April 30, 2012 9:24 PMAnswerer
If you use default credentials it will use the apppool, but I suggest using specific credentials to check things are working before you start using the apppool user.
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Tuesday, May 01, 2012 10:12 AMAnswererHow did you get on?
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Tuesday, May 01, 2012 3:01 PM
Hi Scott,
Thank you for sticking with me here. Reviewing the stream last evening, I caught your 'do not use impersonation' message. I disabled this last evening, and received a different message.
Principal user (Id=22241d9d-d692-e111-bbb3-00155d042416, type=8) is missing prvCreateContact privilege
I traced the guid down to the user - and it is the user who's credentials I used in the AppPool. I checked the permissions - and found that I had accidently created this user with Administrator privs, not read-write. I changed this, and now the application is working!!!
My next step is to try to use the delegate permissions to make sure the records are created under the correctly logged in user - and not the AppPool user.
I'll update this post with how it works, and maybe a full run down of what I needed to do to get this all working.
Thanks again
Paul
-
Tuesday, May 01, 2012 3:17 PMAnswerer
Hi Paul,
That's great - thanks for posting the update.
Scott
Scott Durow
Read my blog: www.develop1.net/public
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" -
Wednesday, May 02, 2012 9:25 PM
Ok - For folks who are trying to do something similar there are two seperate issues that I ran into.
The first was setting up my test application to be able to utilize Windows authentication on premise without having to install federated services. To do this it's important to:
- set the web.config correctly (thanks Scott for the help here).
- Make sure that IIS is set up correctly (http://www.iis.net/ConfigReference/system.webServer/security/authentication/windowsAuthentication)
- The next item was key to getting this to work - under IIS, for the app pool for your site - set the app pool identity to a user that has the access necessary against the information you are querying in your web application.
The second issue was to configure the the app pool user within CRM with the "act on behalf of another user" in the security profiles.
Once this is set, I used the sample here --> http://msdn.microsoft.com/en-us/library/gg309629.aspx - as a reference. Note - When using this sample, it doesn't tell you how to actually set the reference classes up. So I found and used this website for that piece of the project --> http://msdn.microsoft.com/en-us/library/gg695790.aspx
That's my story and I'm sticking with it.
Paul
- Marked As Answer by PaBocc Wednesday, May 02, 2012 9:25 PM