如何正确解码 Java 中的 SAML 请求(HTTP 重定向)?

Posted

技术标签:

【中文标题】如何正确解码 Java 中的 SAML 请求(HTTP 重定向)?【英文标题】:How can I properly decode a SAML request in Java (HTTP redirect)? 【发布时间】:2020-07-03 05:29:50 【问题描述】:

我正在使用 HTTP 重定向绑定处理 SAML 请求。 我在另一篇文章中读到,需要执行以下步骤才能检索 SAML 请求的原始内容(URL 中的 SAMLRequest 参数):

    网址解码 Base64 解码 夸大内容

虽然这些步骤对我来说很清楚,但我无法获得 XML 格式的 SAML 请求。我相信错误在第三步,也许有不止一种方法来膨胀字节?这是执行上述三个的 Java 函数,给定的参数是 URL 中 SAML 参数的值。

private String decodeMessage(String SAMLContent) 
        try 
            //URLDecode, Base64 and inflate data

            //URLDecode
            SAMLContent = URLDecoder.decode(SAMLContent, "UTF-8");

            //Base64 decoding
            SAMLContent = new String(Base64.getDecoder().decode(SAMLContent), "UTF-8");

            //Inflating data
            try 
                byte[] compressed = new byte[10 * SAMLContent.getBytes().length];
                Inflater i = new Inflater(true);
                i.setInput(SAMLContent.getBytes(), 0, SAMLContent.getBytes().length);
                int finalSize = i.inflate(compressed);
                //Exception is thrown here
                SAMLContent = new String(SAMLContent.getBytes(), 0, finalSize, "UTF-8");
                i.end();


             catch (DataFormatException ex) 
                JOptionPane.showMessageDialog(null, "DFE: " + ex.getMessage());
            

         catch (UnsupportedEncodingException ex) 
            JOptionPane.showMessageDialog(null, "UEE: " + ex.getMessage());
        

        return SAMLContent;

    

如果我复制并粘贴第一步的输出here,我可以在页面底部看到格式良好的 XML,因此至少 URL 解码可以按预期工作。 如果您有任何解决方案,请告诉我,谢谢。

【问题讨论】:

【参考方案1】:

这就是我的做法。流程是检测请求是 HTTP-Redirect,base64 解码请求然后膨胀它。以下链接指向在 github 中执行所有这些操作的代码。

Receive the request

Decode the request

Inflate the XML

如果你得到

标头检查不正确

检查这个answer

您可能需要将膨胀代码更改为:

return new String(inflatedData, 0, inflatedBytesLength, "UTF-8");

【讨论】:

您好,我检查了您提供的链接,尤其是最后一个。但是,膨胀代码返回“不正确的标头检查”。我更新了代码以显示当前版本,你知道吗?谢谢 @Stefano 我添加了关于充气时编码的注释。您可能需要添加它。 谢谢,但我无法解决问题。每次使用“new String”语句时,我已经指定了 UTF-8,并且我已经声明了偏移量和大小参数。我真的不知道,也找不到任何东西,所以如果您有其他提示,请告诉我。现在再次感谢 @Stefano 你可以看看这个***.com/questions/11399350/gzinflate-in-java/…,以防它是包装。代码假定为真。您可以尝试使用 false 而不是传入的 useWrap 的值。即 Inflater decompresser = new Inflater(false); 我会看看的。你能确认至少我遵循了正确的程序吗?复制 URL 中 SAMLRequest 参数的值后,我必须对其进行 urldecode,base64 解码,然后对其进行充气?

以上是关于如何正确解码 Java 中的 SAML 请求(HTTP 重定向)?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 正确准备“HTTP 重定向绑定”SAML 请求

HTTP 状态 401 - 身份验证失败:解码传入 SAML 消息时出错

使用 Java 创建“HTTP 重定向绑定”SAML 请求

Spring saml - 在SP上启动登录时如何记住请求参数,并在IdP响应后处理它们

Identity Server不验证SAML LogoutRequest签名

Spring SAML:如何将请求的 URL 作为 RELAY_STATE 推送到 SAML?