Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

Some forms return a data source error when Forms Based Authentication is enabled


View products that this article applies to.

Symptoms

Consider the following scenario. You have a SharePoint site that uses Forms Based Authentication. You build a browser-enabled InfoPath template that calls the GetUserProfileByName method of the SharePoint UserProfileService web service. You try to open the form in the browser. When the form makes a call to that data connection in this scenario, you receive one of the following error messages:
An error occurred querying a data source

An error occurred while trying to connect to a web service
An entry has been added to the Windows event log of the service LogID 5566

An error occurred accessing a data source

An error occurred while trying to connect to a web service
An entry has been added to the Windows event log of the service LogID 5566

↑ Back to the top


Cause

For a site to use Forms Based Authentication, anonymous access must be enabled at the web application level in Internet Information Services because unauthenticated users must be able to reach the logon page to sign in. However, if you allow anonymous access to the web application, this prevents the Forms Services from successfully querying the user profile web service.

For data security, the UserProfileService web service requires the caller to be authenticated before the service will return any data. This occurs because the UserProfileService web service returns personally identifiable information that is considered sensitive in most organizations. Anonymous access to this data is usually classified as a security breach. Because the UserProfileService web service has no user interface to request a user name and a password, the web service rejects an anonymous request.

In the scenario that is described in "Symptoms," this problem occurs when Forms Services tries to call the GetUserProfileByName method of the SharePoint UserProfileService. Forms Services makes the call anonymously, which is the convention for all web calls. If anonymous access is not allowed in the web application, the SharePoint server returns an authentication error (code 401). That response indicates which authentication methods the server supports. Forms Services then resends the request, including the requested authentication information.

When anonymous access is enabled for the web application, the anonymous request is accepted by the web application and is passed to the UserProfileService web service. The web service rejects the request because the request is not associated with a valid user. Forms Services then returns a server error (code 500), which indicates an internal failure. Forms Services cannot know that the failure occurred because of an authentication problem. Therefore, it cannot return a more specific error.

↑ Back to the top


Resolution

There is no configuration change that will resolve this problem while enabling you to maintain a Forms Based Authentication environment. However, you can write managed code that retrieves the user name or other user information, and you can use that managed code in your form template.

The easiest case is to retrieve the current user's logon name. You can retrieve this when the form loads by adding a call to the Application.User.LoginName property to the FormEvents_Loading event. Here is an example:

        public void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            XPathNavigator codeUserNameXPN = this.CreateNavigator().SelectSingleNode(
                "/my:myFields/my:CodeRetrievedUserName", this.NamespaceManager);
            codeUserNameXPN.SetValue(this.Application.User.LoginName);
        }
If you need more profile information, you must use managed code to pre-authenticate, and then call the user profile web service directly. This requires you to hard-code or prompt for the credentials of a user who has rights to view the requested user profile. In most cases, this user will be a site administrator. If you decide to hard-code the credentials, you should consider security and maintenance issues. The code will be run on the server, which can help you limit security exposure. But when the user name or the password changes, you will have to have update the code. Prompting for credentials does not present these issues but will only work if the user of the form has the rights to view the requested user profile.

Here is sample code that obtains the properties of the current user:

        public void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            //A place to write the results
            XPathNavigator codeUserNameXPN = this.CreateNavigator().SelectSingleNode(
                "/my:myFields/my:CodeRetrievedUserName", this.NamespaceManager);
            //codeUserNameXPN.SetValue(this.Application.User.LoginName);
 
            try
            {
                //TailSpinToysAuthentication is the web service reference to the 
                //https://tailspintoys:23456/_vti_bin/authentication.asmx web service
                GetUserName.TailSpinToysAuthentication.Authentication authenticationWS =
                    new GetUserName.TailSpinToysAuthentication.Authentication();
                
                //Call the web service's Login method and pass the username and password of a site
                //administrator so we have rights to read all user profiles
                authenticationWS.Url = "https://tailspintoys:23456/_vti_bin/authentication.asmx";
                authenticationWS.CookieContainer = new System.Net.CookieContainer();
                GetUserName.TailSpinToysAuthentication.LoginResult result = authenticationWS.Login(
                    "Admin", "Password");
 
                if (result.ErrorCode == GetUserName.TailSpinToysAuthentication.LoginErrorCode.NoError)
                {
                    //If we authenticated correctly, then set up a call to the user profile service
                    //TailSpinToysUserProfileService is the web service reference to the 
                    //https://tailspintoys:23456/_vti_bin/userprofileservice.asmx web service
                    GetUserName.TailSpinToysUserProfileService.UserProfileService userProfileWS =
                        new GetUserName.TailSpinToysUserProfileService.UserProfileService();
                    
                    //Pass the authentication cookies we got back from the authentication web service
                    userProfileWS.Url = "https://tailspintoys:23456/_vti_bin/userprofileservice.asmx";
                    userProfileWS.CookieContainer = authenticationWS.CookieContainer;
 
                    //Try to find the user profile information of the current
                    GetUserName.TailSpinToysUserProfileService.PropertyData[] resultData =
                        userProfileWS.GetUserProfileByName(this.Application.User.LoginName);
 
                    //Enumerate through the properties
                    foreach (GetUserName.TailSpinToysUserProfileService.PropertyData property in resultData)
                    {
                        //Pick out the "AccountName" property and display it
                        if (property.Name == "AccountName")
                            codeUserNameXPN.SetValue(property.Values[0].Value.ToString());
                    }
                }
                else
                {
                    //If we failed to authenticate properly, display the reason why
                    codeUserNameXPN.SetValue(result.ErrorCode.ToString());
                }
            }
            catch (System.Exception ex)
            {
                //If an exception occurred, report it.
                codeUserNameXPN.SetValue(ex.Message);
            }
        }

Note To use managed code in a form template, you must make the form template fully-trusted in the Security section of Form Options, and then publish the form template to SharePoint as an Administrator-Approved form template.

↑ Back to the top


Keywords: KB2619846

↑ Back to the top

Article Info
Article ID : 2619846
Revision : 2
Created on : 9/28/2011
Published on : 9/28/2011
Exists online : False
Views : 464