The exact method of generating SAML IDs is not explicitly defined—it must merely conform to the standards of an XML ID. An XML ID is an xsd:NCName, which is derived from xsd:Name, which can't start with a number or contain spaces, and should have 160 bits of "randomness".
The simplest ID generator in Java that will satisfy that criteria is:
String id() {
return "a" + UUID.randomUUID();
}
In addition, OpenSAML ships with SecureRandomIdentifierGenerator as well:
// You will need to catch the NoSuchAlgorithmException during construction.
IdentifierGenerator idGenerator = new SecureRandomIdentifierGenerator();
String id() {
return idGenerator.generateIdentifier();
}
The actual generation code looks like this:
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
String generateIdentifier() {
return generateIdentifier(16);
}
String generateIdentifier(int size) {
byte[] buf = new byte[size];
random.nextBytes(buf);
return "_".concat(new String(Hex.encode(buf)));
}
Yet another alternative pulled from SAMLSSOUtil:
char[] charMapping = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' };
Random random = new Random();
String createID() {
byte[] bytes = new byte[20]; // 160 bits
random.nextBytes(bytes);
char[] chars = new char[40];
for (int i = 0; i < bytes.length; i++) {
int left = (bytes[i] >> 4) & 0x0f;
int right = bytes[i] & 0x0f;
chars[i * 2] = charMapping[left];
chars[i * 2 + 1] = charMapping[right];
}
return String.valueOf(chars);
}
From the Oasis docs:
The xs:ID simple type is used to declare SAML identifiers for assertions, requests, and responses. Values declared to be of type xs:ID in this specification MUST satisfy the following properties in addition to those imposed by the definition of the xs:ID type itself:
• Any party that assigns an identifier MUST ensure that there is negligible probability that that party or any other party will accidentally assign the same identifier to a different data object.
• Where a data object declares that it has a particular identifier, there MUST be exactly one such declaration.
The mechanism by which a SAML system entity ensures that the identifier is unique is left to the implementation. In the case that a random or pseudorandom technique is employed, the probability of two randomly chosen identifiers being identical MUST be less than or equal to 2^-128 and SHOULD be less than or equal to 2^-160. This requirement MAY be met by encoding a randomly chosen value between 128 and 160 bits in length. The encoding must conform to the rules defining the xs:ID datatype. A pseudorandom generator MUST be seeded with unique material in order to ensure the desired uniqueness properties between different systems.
The xs:NCName simple type is used in SAML to reference identifiers of type xs:ID since xs:IDREF cannot be used for this purpose. In SAML, the element referred to by a SAML identifier reference might actually be defined in a document separate from that in which the identifier reference is used. Using xs:IDREF would violate the requirement that its value match the value of an ID attribute on some element in the same XML document.