Attribute Stores

Applies To: Active Directory Federation Services (AD FS) 2.0

An attribute store is a pluggable module that the policy process for Active Directory Federation Services (AD FS) 2.0 can query to retrieve claim values. For a list of attribute stores that AD FS 2.0 supports, see The Role of Attribute Stores (https://go.microsoft.com/fwlink/?LinkId=182464) in the AD FS 2.0 Design Guide.

Working with attribute stores

The following sections provide details about working with and connecting to the different types of attribute stores that you can configure for use with AD FS 2.0.

Working with Active Directory or AD DS as an attribute store

When you work with Active Directory or Active Directory Domain Services (AD DS) as an attribute store, no connection string is required. When AD FS 2.0 is installed and configured on a domain-joined computer, the Active Directory user account store for that domain is made available as a selectable attribute store. For more information, see Add an Attribute Store.

Working with AD LDS or other LDAP-based attribute stores

When you work with other Lightweight Directory Access Protocol (LDAP)-based attribute stores such as Active Directory Lightweight Directory Services (AD LDS) stores, you must connect to an LDAP-capable server that supports Windows Integrated Authentication. The LDAP connection string must also be written in the format of an LDAP URL, as described in RFC 2255. The following is an example of an LDAP URL:

ldap://localhost:56000/cn=AdfsUsers,o=Microsoft,c=US

This string specifies that an LDAP search is being made against an LDAP server named "localhost" over port 56000, and the search is to start from the AdfsUsers base object ("cn=AdfsUsers,o=Microsoft,c=US").

Setting ACL permissions for AD LDS attribute stores

When working with AD LDS attribute stores, configure ACL settings to provide read permissions to the AD FS 2.0 Windows service to ensure that attribute lookup operations are enabled correctly. To accomplish this task, you can use the Dsacls.exe tool with the following command-line syntax.

dsacls.exe \\<hostname>: <port>\ <AD LDS container DN>/I:T /G <user/group/role> DN: <permission>

For example, if your AD LDS instance is on the same server as your Federation Service (for example, "ContosoSrv1"), and the identity your AD FS 2.0Windows service uses to log on and run under is the Network service account, use the following Dsacls.exe command-line to provide read rights on your AD LDS instance in the container ("Test") for your attribute store.

dsacls.exe \\contososrv1:389\CN=Test /I:T /G "NT Authority\Network Service":GR

If your AD LDS instance is remotely on a different computer (for example, "ContosoSrv2") located apart from your Federation Service, then use Dsacls.exe to give the remote computer account where AD LDS is running read rights on your AD FS 2.0 instance.

dsacls.exe \\contososrv01:389\CN=Test /I:T /G contosrv2.contoso.com:GR

Similarly, if you are using another domain user account as the service identity for your AD FS 2.0 installation, modify this procedure accordingly to give that account access to its configured AD LDS attribute store.

Authoring custom rules for Active Directory and LDAP attribute stores

The claims rule language provides a conditional method, referred to as the LDAP query format, that you can use to help author custom rules. These rules look up multiple attributes in Lightweight Directory Access Protocol (LDAP) and Active Directory attribute stores and return the attribute values as claim values. Note that, for the sake of simplicity, we use the term LDAP server in this section to refer to any LDAP server, including Active Directory Domain Controllers (AD DS), depending on the type of attribute store that is used (LDAP or Active Directory).

For example, you can write a custom rule that takes an incoming claim value and uses that value to query only those accounts in an LDAP attribute store that have an attribute value that matches the incoming claim value. Another rule in the same rule set can then be created to issue claims to only those users whose attributes have a matching value.

Before you begin writing rules that will allow this functionality, you must first understand how the query string is passed. An Active Directory attribute store validates and evaluates the query string that is passed to it by using the QUERY keyword. This attribute store recognizes the following format for the QUERY:

QUERY = <QUERY_FILTER>;<ATTRIBUTES>;<DOMAIN_NAME>\<USERNAME>

Therefore, the QUERY has three parts, which are separated by two semicolons:

  • QUERY_FILTER — This is the query string that is executed against the directory to narrow down the directory objects. This is any valid LDAP query involving attribute names and values, for example, cn=bob.

  • ATTRIBUTES — This is the comma-separated name of the attributes to be returned from the filtered directory objects. QUERY_FILTER, ATTRIBUTES, DOMAIN_NAME, and USERNAME can have parameter replacement placeholders, such as {0}, {1} and so on, which are filled with query parameter values that are passed to it from the program with the PARAM keyword. The order of substitution of PARAM values is in the order in which the values appear in the original attribute store query that is passed to the attribute store. That is, the first PARAM value that is mentioned in the query is substituted for placeholder {0}, the second PARAM value is substituted for placeholder {1}, and so on. After all the parameter substitutions (if applicable), the format of the resulting QUERY_FILTER is used to run the query against the directory.

  • DOMAIN_NAME\USERNAME — This part of the query identifies and locates the domain controller to connect to for execution of the LDAP query, for example, contoso\bob. This part of the query must be specified only when you use the Active Directory attribute store. This part of the query is not used for LDAP attribute stores. Also note that USERNAME is ignored, even for Active Directory attribute stores. The attribute store executes an LDAP query using QUERY_FILTER as the query that is targeted at the LDAP server, and it requests the return attributes whose names are available in the ATTRIBUTES string. QUERY_FILTER is substituted as the value of filter in the LDAP search request message. ATTRIBUTES is substituted as the value of attributes in the LDAP search request message.

    The LDAP server returns an LDAP Search Result message with attribute values. The attribute store then creates a two-dimensional array of strings from the values of the attributes that are returned from the server. The number of rows in the array is the same as the number of directory objects that were filtered using the QUERY_FILTER. There are as many columns in each row as the number of attributes that were requested. In other words, each column in the row corresponds to one attribute value, as requested in the return attribute list. This two-dimensional array of strings is ultimately returned as the result of query execution from the Active Directory attribute store.

Note

For the Active Directory attribute store, if you do not specify the QUERY_FILTER, the default filter of samAccountName={0} is used. In this case, you must provide at least one parameter to the query (using the PARAM keyword) to substitute for the samAccountName value.

Working with SQL-based attribute stores

When you work with Structured Query Language (SQL)-based attribute stores, you also must configure a connection string. The SQL connection string is written in the standard format for Microsoft SQL Server connection strings, for example:

Server=CONTOSOSRV01;Database=UserAttributes;Integrated Security = True

This string specifies that a SQL server named "CONTOSOSRV01" has a database named "UserAttributes" that is used as the attribute store and that it uses Windows Integrated Authentication for SQL Server security. You can use any valid connection string that works with SQL Server. For more information about connection string rules for SQL, search the developer documentation on the Microsoft Developer Network (MSDN) site for the following SQL client property: System.Data.SqlClient.SqlConnection.ConnectionString.

Note

We recommend that Windows Integrated Authentication be used for connecting to a SQL Server database. If SQL Server authentication is used, the applicable SQL user name and its related password information will be stored as clear text in the AD FS 2.0 configuration database.

Transact-SQL query syntax modifications and restrictions

Some syntax changes are necessary when you use the AD FS 2.0 claims language to work with Transact-SQL (T-SQL) queries. The primary consideration is how you must specify parameters when passing them through AD FS 2.0 claims rules to the SQL command interpreter.

The claims rule language of AD FS 2.0 requires the String.Format method, and its placeholder syntax (for example, {0}, {1}, and so on), to be used inside the SQL query for parameter substitution. For example, instead of having a SQL Server query such as the following T-SQL statement:

SELECT Email FROM UserAttributes WHERE UserName = @userName

you would have to modify this query as follows to indicate the correct parameterization:

SELECT Email FROM UserAttributes WHERE UserName = {0}

Similar changes apply when you use stored procedures instead of direct SQL queries. For example, instead of having the following T-SQL execution statement:

EXEC spr_GetUserAttributes @userName = @argument

you would have to execute this stored procedure call as expressed in the following syntax:

EXEC spr_GetUserAttributes @userName = {0}

Other than the modified requirements for using placeholders to pass T-SQL parameters, you can use all other aspects of the T-SQL language as they are provided for and supported in SQL Server.

Important

No single quotation character should be used around the placeholders. For example, even though the parameter value is a string, any additional single quotation characters that are added to the previous T-SQL query example would cause it to fail in AD FS 2.0 claims rules language:

SELECT Email FROM UserAttributes WHERE UserName = '{0}'

In addition to these modifications, the following additional restrictions apply to T-SQL use in AD FS 2.0 claims rules language.

  • The only parameters that can be passed to the T-SQL query can be of type string. This restriction follows from the fact that claim values (which form parameters to the query) are strings.

  • The T-SQL query can only return values that are of SQL string types (varchar, nvarchar, char, nchar, text, ntext, varchar(max), nvarchar(max)). This restriction exists because any SQL values that are returned are used as a source of the values of claims, which are always strings. This restriction can require some additional overhead in the T-SQL query path because even simple numeric types, such as integer or bit values, must be converted to valid string types inside the SQL Server query process.

  • The T-SQL query can return only one SQL table and not a dataset. This restriction is based on how the T-SQL query result is transformed into claims.

For more information about how custom rules are written to use SQL attribute stores, see The Claim Rule Language.

Working with custom attribute stores

When you work with a custom attribute store, you may also have to configure a connection string. In this situation, you can enter any custom code you like that enables a connection to your custom attribute store. The connection string in this situation is a set of name/value pairs that are interpreted as implemented by the custom attribute store developer.