Passport Unique ID (PUID)
.NET Passport Unique ID
For the purpose of unique identification in a site's internal, private database, Microsoft® .NET Passport users should be referenced by their .NET Passport Unique ID (PUID), which is a combination of two .NET Passport profile attributes, MemberIDHigh and MemberIDLow, and is reflected as a 16-character string in the HexPUID property of the PassportIdentity class.
The PUID is used for three reasons: security, uniqueness, and the lack of support for 64-bit unsigned integers in commonly used development languages.
Although the user's sign-in name does uniquely identify users for the purpose of signing in to .NET Passport, for security reasons, the sign-in name is not stored anywhere in a .NET Passport profile, and is therefore unavailable for method calls. The sign-in name is verified, but not distributed to participating sites. Allowing sign-in names themselves to be stored in any database other than the .NET Passport central database introduces the risk of misuse or theft of users' personal data.
The PUID is also the only .NET Passport profile element that is guaranteed to be unique. The MemberName attribute, for example, lacks such a guarantee, as many people have the same name, and so is inappropriate for this purpose. The PreferredEmail is not a required attribute, so it cannot be used as a unique identifier. Furthermore, sign-in names may potentially be recycled or even reassigned, but the network-side unique identifiers (and thus the resulting PUID) are never reused.
The PUID is generated in two parts for the user's profile due to more common support for 32-bit than for 64-bit data types. Although this requires that the two values be combined, it avoids forcing developers to write applications only in languages with 64-bit support. It is strongly recommended that participating sites use a common derivation algorithm throughout an application for constructing a PUID.
The use of a common algorithm for deriving PUIDs from the MemberIDHigh and MemberIDLow values is particularly important if several participating sites share a common private database but do not necessarily share a complete code base. There are several derivations that will produce a unique PUID value when combining the two 32-bit values. For implementations in C# and for databases, the best alternative is usually to store the PUID as a native 64-bit data type. That is, the string value returned by the HexPUID property of the PassportIdentity object should be converted into an unsigned long integer, as in the following example:
<% PassportIdentity id = (PassportIdentity)Context.User.Identity; //assumes user is already signed in ulong PUID = Convert.ToUInt64(id.HexPUID); %>
Microsoft® Visual Basic® and Visual Basic Scripting Edition (VBScript) do not support an unsigned integer data type or a true INT type of 64-bit size. This complicates the task of implementing a derivation if both C# and script are used to read and write PUIDs to a common database. The preferred solution is to represent the PUID not as a true numeric value, but as a string representing the concatenation of the hexadecimal character representation of the two 32-bit values. This is why the HexPUID property is of type string rather than type ulong. Members 0-7 of the resulting vector are always the MemberIDHigh component and members 8-15 of the string vector are the MemberIDLow component.
See Also
MemberIDHigh | MemberIDLow | PassportIdentity.HexPUID | .NET Passport Profile