Name Identifiers in SAML assertions

In this post I will show how to setup your Relying Party Trust issuance policy to create name identifier in assertion. For AD FS 2.0 the name identifier is yet another claim but you may want to generate name identifiers if you plan to:

· Use SAML 2.0 protocol (particularly name identifier is necessary if you plan to take advantage of SAML logout protocol),

· Federate with non-AD FS 2.0 deployment.

I will show name identifier configuration on two privacy sensitive scenarios: persistent identifier, transient identifier. Persistent identifier is meant to obfuscate the real user identity, so it’s not possible to link user activities across different relying parties. At the same time the STS guarantees that persistent id will remain the same each time same the user logs in again. In SAML 2.0 assertion, it may look similar to:

<Assertion ID=”_90bd669e-4a85-412d-9969-90e43e031fac” IssueInstant=”2010-01-07T02:50:48.719Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">




    <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">zbonsm0Yn9Gnw14uQEEPr6AO7d+IvxwCQN3t+o24jYs=</NameID>






Transient identifier has similar properties but it’s only valid for single login session (i.e. it will be different each time the user authenticates again, but will stay the same as long as the user is authenticated).


Before I start I assume you already configured sample Relying Party Trust with basic policy. In case you don’t, here is some recommended reading:

· Configuring Relying Parties

· AD FS 2.0 policy language

Persistent name identifier

Step 1. Choose your Relying Party Trust and make a custom issuance transform rule to create unique user identifier claim

For the first rule we have to create advanced rule that will use custom built-in store for generating opaque identifiers. Sample rule below will use Windows Account Name Claim as a seed to generate unique identifier that will persist across all sessions.

c:[type == "" ]

=> add(

  store = "_OpaqueIdStore",

  types = ("https://mycompany/internal/persistentId"),

  query = "{0};{1};{2}",

  param = "ppid",

  param = c.Value,

  param = c.OriginalIssuer);


Note about technical detail: the rule that we are using is attribute extraction rule from one of the built-in attribute stores. The store takes 3 parameters: mode (“ppid”) and 2 parameters that are used as a seed for generating pseudo-random identifier. The result is also mixed with AD FS installation specific secret entropy.


Step 2. Transform persistent identifier claim into Name Identifier claim


We can use built-in rule to transform the persistent identifier claim created in Step 1 into name identifier claim (see screenshot below).


Transient name identifier

Step 1. Create custom rule to create per session identifier

For identifier we will use second mode of opaque store where it takes extra entropy to mix into result. In addition to Windows Account Name, we will also use authentication instant to generate identifier that will persist only for current login session.

c1:[Type == ""] &&

c2:[Type == ""]

 => add(

       store = "_OpaqueIdStore",

       types = ("https://mycompany/internal/sessionid"),

       query = "{0};{1};{2};{3};{4}",

       param = "useEntropy",

       param = c1.Value,

       param = c1.OriginalIssuer,

       param = "",

       param = c2.Value);

Note about technical detail: this time we also extract values from built-in store. This time the mode is “useEntropy” – which basically means that we will use 2 extra parameters (3rd and 4th) to additionally mix into returned identifier. Parameter 3 – is site specific entropy (empty means use relying party identifier). Parameter 4 is any other entropy - we use authentication instant.

Step 2. Transform temporary claim into Name Identifier claim

We will use similar rule as for persistent name identifier. This time we will change the format of the claim to indicate that Name Identifier will be transient.

Mieszko Matkowski

SDET, AD FS 2.0 Protocols