构造一个签名的 SAML2 注销请求 [英] Construct a signed SAML2 LogOut request

查看:203
本文介绍了构造一个签名的 SAML2 注销请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是实现单点注销协议.首先,我了解标准的工作原理以及如何将其适应我的场景:ADFS 2.0 作为 IdP,对我来说就像一个黑匣子"

我现在正在做的是下一个:

  1. 向我的 IdP 发送

  2. IdP 要求我提供凭据,我提供凭据并成功登录.

  3. 从 中获取 SessionIndex 值并构造一个

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/" IssueInstant="2008-06-03T12:59:57Z"><saml:颁发者>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://idphost/adfs/ls/">myemail@mydomain.com</NameID<samlp:SessionIndex>_0628125f-7f95-42cc-ad8e-fde86ae90bbe</samlp:SessionIndex></samlp:LogoutRequest>

  1. 采用上面的并用Base64

  2. 编码
  3. 构造下一个字符串:SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1

  4. 用上面的字符串生成签名

  5. 以 base64 编码签名

  6. 发送请求:https://"https://idphost/adfs/ls/?SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=base64EncodedSignature

但是 IdP 正在回答我:SAML 消息签名的验证失败.

为了签名,我使用我的私钥(2048 字节),并且为了验证它,假设 IdP 使用我的公钥(我在注册我的主机时发送的那个)

签署请求的代码如下所示:

//检索私钥KeyStore keyStore = KeyStore.getInstance("JKS", "SUN");FileInputStream 流;stream = new FileInputStream("/path/to/my/keystore.jks");keyStore.load(stream, "storepass".toCharArray());PrivateKey key = (PrivateKey) keyStore.getKey("keyAlias","keyPass".toCharArray());//创建签名签名签名 = Signature.getInstance("SHA1withRSA");签名.initSign(key);signature.update(SAMLRequest = jVJda8IwFH2e4H8ofW%2BbVmvboGWCDApusDn2sBdJm1sNtEmXmw7x1y92KDrY2Ov5uueEzJG1TUfXaqd68wIfPaBxDm0jkQ7Mwu21pIqhQCpZC0hNRTfLxzWNfEI7rYyqVONeWf52METQRijpOsVq4W7JoSzjJJnWAEAmwLMMpmRG0jCrYJICIcR13kCjdSxcG%2BA6K9tQSGYGZG9MhzQIGrUT0uPw6VegpV%2FtA8ZrDBq0ZxB7KCQaJo2NICT1yMwjk9cwonFG4%2BTdzceju%2FmpOx3EOu8qYThgGJ3j5sE1fZE%2F2X3FynlQumXm9%2BGhHw6I4F49SCm0TDRLzjWgrXiKee5ZI2oB%2BJ%2Bj8qYX6GvFtdj1cPRryzPJ4Xh%2F2%2Fe736VvRzf2nn24wmoP%2BZbMojSM4tpL6iz2plFVeYyn4NUc0hmDjJQlfCf9cI5HZ%2Fjm4%2BRf&安培;的RelayState = NULL&安培; SigAlg = HTTP%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1".getBytes());String signatureBase64encodedString = (new BASE64Encoder()).encodeBuffer(signature.sign());

解决方案

我终于找到了正确的配方:

  1. 生成 SAMLRequest 值
  2. 以 Base64 编码 SAMLRequest 值
  3. 对 SAMLRequest 值进行 URL 编码
  4. 对 SigAlg 值进行 URL 编码:http://www.w3.org/2000/09/xmldsig#rsa-sha1
  5. 将算法签名 (SHA1withRSA) 与SAMLRequest=value&SigAlg=value
  6. 对生成的签名进行 URL 编码

我们可以使用 SAML 2.0 Debugger 执行第 2 步和第 3 步(https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php).而对于URL 编码使用经典的 w3schools(http://www.w3schools.com/tags/ref_urlencode.asp)>

警告!确保 ADFS2 中您的信赖方的算法设置为 SHA1!

最好的问候,

路易斯

ps:现在我必须写一点代码......

pps:你可以在这里找到代码:https://github.com/cerndb/wls-cern-sso/tree/master/saml2slo

My aim is to implement the Single Log Out Protocol. First I am understanding how the standar works and how I can fit it in my scenario: ADFS 2.0 as IdP, for me is like a "black box"

What I am doing at the moment is the next:

  1. Send an <AuthnRequest> to my IdP

  2. IdP asks me for credentials, I provide them and get succesfully login.

  3. Get the SessionIndex value form the and constructs a <LogoutRequest>

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/" IssueInstant="2008-06-03T12:59:57Z"><saml:Issuer>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://idphost/adfs/ls/">myemail@mydomain.com</NameID<samlp:SessionIndex>_0628125f-7f95-42cc-ad8e-fde86ae90bbe</samlp:SessionIndex></samlp:LogoutRequest>

  1. Take the above <LogoutRequest> and encode it in Base64

  2. Contructs the next string: SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1

  3. With the above string generates the signature

  4. Encode the signature in base64

  5. Send the request: https://"https://idphost/adfs/ls/?SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=base64EncodedSignature

But the IdP is answering me: The verification of the SAML message signature failed.

For signing I am using my private key (2048 bytes), and for verifying it is supposed that the IdP is using my public key (the one that I sent it when I registered my host)

The code for signing the request looks like:

// Retrieve the private key
KeyStore keyStore = KeyStore.getInstance("JKS", "SUN");
FileInputStream stream;
stream = new FileInputStream("/path/to/my/keystore.jks");
keyStore.load(stream, "storepass".toCharArray());
PrivateKey key = (PrivateKey) keyStore.getKey("keyAlias","keyPass".toCharArray());

// Create the signature
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(key);
signature.update("SAMLRequest=jVJda8IwFH2e4H8ofW%2BbVmvboGWCDApusDn2sBdJm1sNtEmXmw7x1y92KDrY2Ov5uueEzJG1TUfXaqd68wIfPaBxDm0jkQ7Mwu21pIqhQCpZC0hNRTfLxzWNfEI7rYyqVONeWf52METQRijpOsVq4W7JoSzjJJnWAEAmwLMMpmRG0jCrYJICIcR13kCjdSxcG%2BA6K9tQSGYGZG9MhzQIGrUT0uPw6VegpV%2FtA8ZrDBq0ZxB7KCQaJo2NICT1yMwjk9cwonFG4%2BTdzceju%2FmpOx3EOu8qYThgGJ3j5sE1fZE%2F2X3FynlQumXm9%2BGhHw6I4F49SCm0TDRLzjWgrXiKee5ZI2oB%2Bj%2Bj8qYX6GvFtdj1cPRryzPJ4Xh%2F2%2Fe736VvRzf2nn24wmoP%2BZbMojSM4tpL6iz2plFVeYyn4NUc0hmDjJQlfCf9cI5HZ%2Fjm4%2BRf&RelayState=null&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1".getBytes());

String signatureBase64encodedString = (new BASE64Encoder()).encodeBuffer(signature.sign());

解决方案

Finally I got the right recipe:

  1. Generate the SAMLRequest value
  2. Encode the SAMLRequest value in Base64
  3. URL-encode the SAMLRequest value
  4. URL-encode the SigAlg value: http://www.w3.org/2000/09/xmldsig#rsa-sha1
  5. Feed the algorithm signature (SHA1withRSA) with the SAMLRequest=value&SigAlg=value
  6. URL-encode the generated signature

We can perform the steps 2 and 3 with the SAML 2.0 Debugger (https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php). And for the URL-encoding use the classic w3schools (http://www.w3schools.com/tags/ref_urlencode.asp)

Warning! Ensure that the algorithm for your relying party, in the ADFS2, is setup to SHA1!

Best regards,

Luis

ps: now I have to code a little bit...

pps: You can find the code here: https://github.com/cerndb/wls-cern-sso/tree/master/saml2slo

这篇关于构造一个签名的 SAML2 注销请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆