Saml身份验证请求协议ID

时间:2011-02-22 10:02:35

标签: security authentication request protocols saml

使用SAML2.0协议进行Http Redirect绑定时,我应该发送到Identity Provider结构,如下所示:

<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>

我的问题是:ID的价值是如何产生的?

ID="{82AB4AE6-919C-5FE6-C843-8342E6F9AB61}" Version="2.0"

生成它的规则是什么?

5 个答案:

答案 0 :(得分:13)

未明确定义生成SAML ID的确切方法 - 它必须仅符合XML ID的标准。 XML ID是xsd:NCName,它是从xsd:Name派生的,它不能以数字开头或包含空格,并且应该有160位&#34;随机性&#34;。

Java中最简单的符合该标准的ID生成器是:

String id() {
  return "a" + UUID.randomUUID();
}

此外,OpenSAML还附带SecureRandomIdentifierGenerator:

// You will need to catch the NoSuchAlgorithmException during construction.
IdentifierGenerator idGenerator = new SecureRandomIdentifierGenerator();

String id() {
  return idGenerator.generateIdentifier();
}

实际生成代码如下所示:

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)));
}

另一个替代方案来自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);
}

来自Oasis文档:

  

xs:ID简单类型用于声明断言,请求和响应的SAML标识符。声明为xs:ID的值在此规范中必须满足以下属性以及xs:ID类型本身的定义所强加的属性:

     

•任何分配标识符的一方必须确保该方或任何其他方不小心将相同的标识符分配给不同的数据对象的可能性微乎其微。   •如果数据对象声明它具有特定的标识符,那么必须只有一个这样的声明。

     

SAML系统实体确保标识符唯一的机制留给实现。在采用随机或伪随机技术的情况下,两个随机选择的标识符相同的概率必须小于或等于2 ^ -128并且应该小于或等于2 ^ -160。可以通过编码长度为128到160位的随机选择值来满足此要求。编码必须符合定义xs:ID数据类型的规则。伪随机生成器必须使用唯一材料播种,以确保不同系统之间所需的唯一性属性。

     

xs:NCName简单类型在SAML中用于引用xs:ID类型的标识符,因为xs:IDREF不能用于此目的。在SAML中,SAML标识符引用引用的元素实际上可能在与使用标识符引用的文档中分开的文档中定义。使用xs:IDREF会违反其值与同一XML文档中某个元素的ID属性值匹配的要求。

答案 1 :(得分:2)

你如何生成它基本上取决于你。唯一需要注意的是,它必须是有效的XML ID类型值(这意味着它不能以数字开头或包含任何空格)。您需要将其保留在某处,以便您可以将其与IdP发送的响应进行匹配。

答案 2 :(得分:2)

id是xsd:NCName,它源自xsd:Name,不能以数字开头

Java中最简单的id:

String id = new UID().toString().replaceAll(":", "-");

并且永远不会将该ID与任何其他AuthnRequest一起使用,否则如果IdP可以检测到

,您将获得重播攻击错误

答案 3 :(得分:1)

SAML 2.0 Core文件的第1.3.4节“ID和ID参考值”。

答案 4 :(得分:-1)

好吧它可能会迟到但我认为寻找答案的人可以获益...

你可以参考SAMLUTIL,它有许多标准的util方法。 要生成id,可以参考此util。中的createID()方法。