SP2010: InfoPath, UserProfileService and 401 Unauthorized
The last few days I was working on a problem reported by a user using InfoPath Service. A browser based form had to connect to the UserProfileService.asmx webservice in order to read some profile data to populate a form. This was working untill the web application was switched to claims based authentication. After that change, the webservice stopped working and (401) Unauthorized errors occurred in the logs.
It took me quite some time to find a stable solution, and you need to check for several things. I though I’d share this solution for others to use.
First, this is how our environment is configured:
- InfoPath Services run browser based forms (problem does not occur client side).
- The WebApplication is a claims based app.
- Kerberos is configured as authentication mechanism.
Now here’s what you got to do to get this to work:
- First, configure a Secure Store entry. If you don’t have a Secure Store setup, you need to get one, there’s enough info out there on how to do that.
- Configure the entry as type Group with a Windows username and Windows password.
- Set the credentials for the entry, make sure your user group has access to the entry. The account you configure will need rights to the user profile service application, so you’ll probably want to use a (dedicated) service account.
- The account you specified needs rights to be able to actually use the webservice. This might be confusing, because all authenticated accounts have enough rights to open the WSDL. But that’s not enough when you want to use the service.
- To set the correct rights, go to your Service Application management page, click the User Profile Service instance and choose ‘Administrators’ in the ribbon. Add the previously configured account. I chose to give it full rights, but you could fiddle a bit with which rights you actually need to perform the tasks requested.
- Now create your data source in InfoPath and point it to the UserProfileService.asmx webservice (/_vti_bin/UserProfileService.asmx?WSDL). In our case, the GetUserProfileByName method was used to get the users’ details.
- Because the service will be called as the SSO user, you need to delay loading because you need to set the username as a parameter. So don’t check the checkbox which asks if the data should be loaded as soon as the form loads.
- Instead, go to the Data ribbon tab and click “Form Load”. Now configure two new actions, first “Set a field’s value”. Choose the username parameter for the webservice method and set userName() as the value (this is a function found under the User function category.
- As second action, set “Query using a data connection” and set the form to query the webservice.
- Return to your form and click “Manage Data Connections” in the Fields toolpane.
- Convert your datasource to a data connection file. This file needs to be stored in SharePoint in a Data Connection Library. If you don’t have one yet, create it as you would create a normal document library (but choose the data connection library type instead, obviously).
- The file will be created as a UDCX. The last step is to open up that file and look for this line:
<!--udc:Authentication><udc:SSO AppId='' CredentialType=''/></udc:Authentication-->
Without authentication set, InfoPath will perform the call as an anonymous user, which results in the (401) Unauthorized exception.
- Replace the above line with:
<udc:Authentication><udc:SSO AppId='YourSSOAppId' CredentialType='NTLM'/></udc:Authentication>
Now you’re telling InfoPath it needs to query the configured SSO service application, retrieve the credentials stored for application ‘YourSSOAppId’ and use them to query the webservice. And because you’ve configured an account which you added to the User Profile Service Application, this account will have enough rights to perform the request.
- When you don’t use claims and you want to use Kerberos to delegate your user credentials, you need to check two more things. First, make sure you’ve configured local loopback checking and disabled it (either completely, or per URL).
- Secondly, avoid double-hop issues by making sure the web front-end servers point to themselves. Do this by editing the hosts file and add records for 127.0.0.1 (hence the local loopback check) for the DNS addresses you use.
- And to be complete; of course you need a valid Kerberos setup in that case. But you won’t be able to access your web application at all when you don’t, so that’s a different topic alltogether.
That’s it! With these steps you should be able to use the built in UserProfileService.asmx webservice in a claims (or classic) based web application from within InfoPath forms. Good luck!