Creating a Custom Federated Search Web Part with a Credentials UI
Using Microsoft Search Server 2008 to create federated locations, you can include items from content repositories that are not indexed by the search server's crawler. When you create a federated location, you must also specify its authentication type.
Specifying an Authentication Type
The authentication type for a federated location you create can be one of the following:
**Anonymous **No credentials are required to connect to the federated location.
Common Each connection uses the same set of credentials to connect to the federated location.
**Per-user **The credentials of the user who submitted the search query are used to connect to the federated location.
For the common and per-user authentication types, you must also specify one of the following authentication protocols:
Basic
Digest
NTLM Application Pool identity (common authentication type only)
NTLM
Kerberos (per-user authentication type only)
Forms
Cookie
Using the Federated Search Web Part to Access User Credentials
In scenarios where the federated location is an OpenSearch location and the location is configured for per-user authentication, the user's credentials are automatically passed if Kerberos authentication is being used. However the credentials are not passed automatically for other authentication protocols. For authentication to work in these scenarios, you must create custom versions of the federated search Web Parts to request the user's credentials, so that the credentials can be passed in the request to the federated location.
This topic discusses the requirements for and provides some guidance about creating a custom version of a federated search Web Part with a credentials user interface (UI) for Search Server 2008.
First, we examine the new federated search Web Parts—Federated Results and Top Federated Results—in Search Server 2008, and the classes related to them in the Microsoft.Office.Server.Search.WebControls namespace.
Note
The Search Server 2008 Query object model (located in the Microsoft.Office.Server.Search.Query namespace) does not provide access to federated search results. To customize the federated search UI, you must implement a class that inherits from one of the new federated search Web Parts.
Federated Results Web Part
The Federated Results Web Part displays the results from a specified federated location. You can specify only one federated location in a Federated Results Web Part. By default, Search Server 2008 provides two Federated Results Web Parts, one that displays related searches from Live Search, and the other that displays Live Search results.
You implement the Federated Results Web Part in the Microsoft.Office.Server.Search.WebControls.FederatedResultsWebPart class.
Top Federated Results Web Part
The Top Federated Results Web Part displays the results from the first federated location to return search results. You can configure multiple locations for the Web Part, in priority order. By default, no locations are configured for this Web Part.
You can implement the Top Federated Results Web Part in the Microsoft.Office.Server.Search.WebControls.TopFederatedResultsWebPart class.
SearchResultsBaseWebPart Base Class
Both the FederatedResultsWebPart class and TopFederatedResultsWebPart class inherit from the same base class: Microsoft.Office.Server.Search.WebControls.SearchResultsBaseWebPart.
Creating the Web Part Project
You can use Microsoft Office SharePoint Designer 2007 to import Web Parts to Web pages, but not to create new Web Parts. To develop a custom Web Part assembly, you must use a development tool such as Microsoft Visual Studio 2005.
For additional information about creating custom Web Parts by using Visual Studio 2005, see the following:
Adding Project References
You can also get started with the custom Web Part solution by creating a project in Visual Studio 2005 by using the Class Library or Web Control Library project templates. After you create the project, you must add the following references to your project:
Microsoft Search component (Microsoft.Office.Server.Search.dll)
Windows SharePoint Services (Microsoft.SharePoint.dll)
Adding the Web Part Class
You must add a class to the Web Part project, and specify that it inherits from one of the federated search Web Part classes. Following are class declaration examples for the custom Web Part.
Code listing 1. Inheriting from the SearchResultsBaseWebPart class
public class CustomFederatedSearchWebPart : Microsoft.Office.Server.Search.WebControls.SearchResultsBaseWebPart
Code listing 2. Inheriting from the FederatedResultsWebPart class
public class CustomFederatedSearchWebPart : Microsoft.Office.Server.Search.WebControls.FederatedResultsWebPart
Code listing 3. Inheriting from the TopFederatedResultsWebPart class
public class CustomFederatedSearchWebPart : Microsoft.Office.Server.Search.WebControls.TopFederatedResultsWebPart
Implementing the Custom Web Part Class
To implement the custom Web Part to support per-user authentication scenarios where the federated location is on a remote server, you perform three steps:
Request the credentials from the user.
Create an ICredentials object with the user's credentials.
Pass the ICredentials object to the search request to the federated location.
Security Considerations
We strongly recommend that you use a secure connection when collecting credentials from users.
Requesting the Credentials from the User
Your custom Web Part solution UI must provide the user with a way to enter their credentials. You show this UI only if the Web Part does not have the user's credentials.
You can override one of the following methods to display the credentials UI:
Render
CreateChildControls
In either method, you should include code to check if you already have the user's credentials, and if so, do not render the credentials UI. You must also call base.Render() or base.CreateChildControls() after your code to display the credentials UI.
Note
After you add your custom Web Part to a search results page, you must configure a federated location for the Web part in the tool pane before the Web Part will be displayed on the page.
Creating the ICredentials Object
You create an ICredentials object to pass the user credentials that the user entered.
If you are creating one Web Part for this solution (so the credentials UI is displayed in the same Web Part as the custom federated search results), then you can override the Web Part's OnLoad method to capture the credentials. You can check if the page was posted back to determine whether you should check for credentials entered by the user, as shown in the following code example.
protected override void OnLoad(EventArgs e)
{
if (this.Page.IsPostBack)
{
/*
uCredentials is a class level variable for an ICredentials object.
domainName is a string variable containing the domain
userName and passWord are examples of text box controls added in the previous step.
*/
uCredentials = new NetworkCredential(userName.Text, passWord.Text, domainName);
}
base.OnLoad(e);
}
If the credentials UI is contained in a Web Part different from the federated search results, you should override the Web Part's Init method instead.
Passing the Credentials to the Federated Location
After you obtain the credentials from the user, you can pass them first to the search request and then to the federated location. You do this by setting the UserCredentials property of the data source object that is associated with the Web Part.
Each federated search Web Part class has an associated data source class, as listed in the following table.
Web Part class | Data Source class |
---|---|
SearchResultsBaseWebPart |
SearchResultsBaseDatasource |
FederatedResultsWebPart |
FederatedResultsDatasource |
TopFederatedResultsWebPart |
TopFederatedResultsDatasource |
To configure the Web Part's federated location data source properties, you must override the ConfigureDataSourceProperties method and call the data source's UserCredentials.Add method, as shown in the following example.
protected override void ConfigureDataSourceProperties()
{
base.ConfigureDataSourceProperties();
SearchResultsBaseDatasource ds = this.DataSource as SearchResultsBaseDatasource;
ds.UserCredentials.Add("LocationInternalName", uCredentials);
}