TransactionalStateSupport不保存变量

时间:2018-06-20 12:52:55

标签: java pingfederate

背景信息:

  • Pingfederate v8.4.1.0独立版(在开发中)
  • Pingfederate v8.4.1.0集群1个控制台; 4个引擎(正式推出)
  • ReferenceID适配器版本1.3.1
  • Ubuntu 16.04

我当前正在实现一个自定义的Idp适配器,该适配器基本上封装了ReferenceID适配器并添加了其他功能。 我正在使用TransactionalStateSupport使oauth-client-id(可在第一个HTTP请求期间作为查询参数使用)在整个事务中都可访问。 不幸的是,这对我来说不是很好。

该值似乎没有存储:

String resumePath = (String)inParameters.get("com.pingidentity.adapter.input.parameter.resume.path");
TransactionalStateSupport txStateSupport = new TransactionalStateSupport(resumePath);

String name="foo";
String value="bar";
txStateSupport.setAttribute(name, value, req, resp);
String value2 = (String) txStateSupport.getAttribute(name, req, resp);
System.out.println("Value directly after storing: " + value2);
if(!value.equals(value2))
  System.out.println("**** STORAGE FAILED ****");

输出:

B3E085C450 : Message{partnerRole=null, entityId='null', msg={partnerEntityID=testclient, scope=openid email profile, com.pingidentity.adapter.input.parameter.tracking.id=tid:cBAmXoOGkUCQXCSjRJ4quIlV5DE, response_type=code, redirect_uri=http://localhost.dev, sessionid=D5ZaljlkoPc6Bdv5l37IiyQikCK, client_id=testclient, com.pingidentity.plugin.instanceid=asd}}
2018-06-20 14:10:47,191 tid:4zBU2dUsYh8O-IRvXFjX3WOylLc DEBUG [org.sourceid.servlet.HttpServletRespProxy] adding lazy cookie Cookie{PF=hashedValue:yF4bj2jqUXu6jvMw0rBOVDuATWs; path=/; maxAge=-1; domain=null} replacing null
2018-06-20 14:10:47,191 tid:4zBU2dUsYh8O-IRvXFjX3WOylLc DEBUG [org.sourceid.saml20.service.impl.localmemory.InterReqStateMgmtMapImpl] setAttr(oldKey: null, newKey: yF4bj2jqUXu6jvMw0rBOVDuATWs, name: foo||h6tCJ)
2018-06-20 14:10:47,191 tid:4zBU2dUsYh8O-IRvXFjX3WOylLc DEBUG [org.sourceid.saml20.service.impl.localmemory.InterReqStateMgmtMapImpl] setAttr: new size of attribute map=3
2018-06-20 14:10:47,192 tid:4zBU2dUsYh8O-IRvXFjX3WOylLc INFO  [SystemOut] Value directly after storing: null
2018-06-20 14:10:47,192 tid:4zBU2dUsYh8O-IRvXFjX3WOylLc INFO  [SystemOut] **** STORAGE FAILED ****

有人对此有解决方案吗,还是有一个想法为什么这个过程失败?

提前谢谢

1 个答案:

答案 0 :(得分:1)

这个问题也困扰了我很长时间。它有时发生,有时不发生,并且并非总是可复制的。现在我终于找到了它:

如果您在写入HTTP响应之前以事务状态存储了某些内容,则可以使用。如果您首先写入HTTP响应,然后尝试以事务状态存储某些内容,则它将失败。如果您在写入HTTP响应之前将某些内容存储在事务状态中,则之后也可以写入事务状态。

观察

我观察到该问题与PF cookie的长度有关:它与长度为44个字符的PF cookie一起使用,但对于22个字符的PF cookie却失败了(请注意,cookie的长度是可配置的,但是有单长和双长的Cookie。

它也可以在没有任何PF请求cookie的情况下正常工作(这是我不同意@Hans Z.和@Andrew K。;-的罕见情况)。但是如果可行,PingFederate会在响应中设置一个44个字符的PF cookie。

剩下的问题是:PingFederate什么时候/为什么设置一个44个字符的PF cookie?

背景

PingFederate为每个请求维护一个内部sessionID。 sessionID对应于PF cookie的值。如果最初没有发送PF cookie,则会创建一个新的sessionID。因此,您在请求中不需要PF cookie 即可使用交易状态。

初始sessionID是一个简短的会话ID(22个字符),不适合在事务状态下存储值。如果您的sessionID较短,并且尝试以事务状态存储某些内容,则PingFederate 会将扩展为44个字符。因此,如果有效,您将看到一个44个字符的PF响应cookie。

如果响应已经提交,则扩展sessionID的过程将失败。如果您对response.getWriter()response.sendRedirect()之类的响应进行任何操作,PingFederate都会“刷新Cookie”。这意味着它实际上将缓存的“惰性” cookie添加到HTTP响应对象,如以下日志条目所示:

DEBUG [org.sourceid.servlet.HttpServletRespProxy] flush cookies: adding Cookie{PF=hashedValue:dkxuW0rImM-votyz33kWkGGbj30; path=/; maxAge=-1; domain=null}

现在已写入cookie,不能再扩展sessionID(否则它将与浏览器接收的内容不同步),并且事务状态不起作用。

恕我直言,这是PingFederate SDK中的错误。至少应该记录一下限制。

解决方法

在写入HTTP响应之前,将代码重构为使用事务状态。如果不可能,只需在写入HTTP响应之前插入一行以在事务状态下存储虚拟属性即可。

我已经使用独立的PF 9.3.0实例对此进行了测试。

旁注

关于原始问题:

  

...使整个交易中都可以访问oauth-client-id(可在第一个HTTP请求期间用作查询参数)。

自PF 9.2起,您可以使用“跟踪的HTTP参数”使请求参数在整个事务中都可用。有关更多详细信息,请参见release notesSDK documentation