As explained at MSDN site, an InfoPath form can access external data sources through connection files. Behind the scene, the InfoPath runtime will get the credential to impersonate through SSO API and invoke LogOnUser function with the credential if Windows authentication is used.
You may run into the following exception while running an InfoPath form with SSO connections:
LogonUser failed for user 'domain\username' (1385) System.ComponentModel.Win32Exception: Logon failure: the user has not been granted the requested logon type at this computer
If you Google the exception for solution, you may find the advice to give the delegated user “Allow Log on locally” windows right. But, it won’t help. Even if you add the user to the local administrator group, it still doesn’t work. To solve this issue, we need to understand how InfoPath Service runtime impersonates with the credential configured in SSO. Writing a web part using SSO API and LogOnUser will help us to understand what is happening inside the InfoPath runtime.
The following code segment explains the three steps to use SSO in a web part:
- Retrieve the credential used to connect to the external database through SSO API;
- Impersonate the credential using LogonUser;
- Create a ADO connection to the database using Integrated Security;
//*******************************************************************//Step 1: Get the account for connecting to database from SSO APIstring[] strCredentialData = null;
//Credentials.Get Credentials is a SharePoint SSO APICredentials.GetCredentials(1, "eex", ref strCredentialData);
string strUserName = strCredentialData[0];string[] domainUserName = strUserName.Split('\\');string strPassword = strCredentialData[1];//***********************************************************************//Step 2: Use LogOnUser to impersonate with the accountbool result = LogonUser(domainUserName[1], domainUserName[0],strPassword,
LogonSessionType.Batch,
LogonProvider.Default,
out token);WindowsIdentity id = new WindowsIdentity(token);impersonatedUser = id.Impersonate();
//************************************************************************//Step 3:Use ADO.NET with Integrated Security to retrieve data from the external database.string resultFromDb = null;
using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Initial Catalog=external_test;Data Source=sqlserver"))
{connection.Open();
SqlCommand command = new SqlCommand("select * from simple", connection);
using (SqlDataReader reader = command.ExecuteReader()){reader.Read();
resultFromDb = (string)reader[0];}
connection.Close();
}
The code above explains how, behind the scene, SharePoint Form Service is using LogOnUser to impersonate an account. So the reason we got the "LogonUser failed for user 'domain\username' (1385) System.ComponentModel.Win32Exception: Logon failure: the user has not been granted the requested logon type at this computer" is that SharePoint Form Service invokes LogonUser with Batch logon session type (the fourth parameter to LogonUser). Therefore, you need to configure the the security policy of your Web Front End to give the delegated user “Log on as Batch” right. The following screen shot demonstrates the configuration.
No comments:
Post a Comment