When doing Http Redirect Binding with SAML2.0 protocol I should send to the Identity Provider structure like this:
<q1:AuthnRequest
ID="{82AB4AE6-919C-5FE6-C843-8342E6F9AB61}" Version="2.0"
IssueInstant="2011-02-22T09:19:48+0100"
Destination="https://test.server.com/Service.jsf"
IsPassive="false"
AssertionConsumerServiceURL="http://myservice.com/sso/"
xmlns:q1="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">test.server.com</Issuer>
</q1:AuthnRequest>
My question is: how is the value of ID
generated?
ID="{82AB4AE6-919C-5FE6-C843-8342E6F9AB61}" Version="2.0"
What are the rules to generate it?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With