我目前正在开发一种方法,在Saba中使用"忘记密码"功能与SSO结合使用,但无需直接在Saba网站上。
我在尝试访问Saba web服务时遇到了一个问题,目前处于一个砖墙。
我得到的var_dump错误如下:
string(544) " ns1:Server.NoService The AXIS engine could not find a target service to invoke! targetService is InfoService/cspsRetrievePassword "
详情如下:
Saba的构建方式使我们不能在自定义web服务上使用REST,只能使用SOAP。我在表单提交上调用以下函数:
public function doPasswordRetrieval($pId, $pAction, $pNewPassword, $pOldPassword, $pIsOldPasswordHashed, $pSecretQ, $pSecretA, $pSendMail){
if($this->isAuthenticated()) {
$soapenv = 'http://schemas.xmlsoap.org/soap/envelope/';
$soapcommand = 'cspsRetrievePassword';
$soapurl = "https://mydomain/axis/services/InfoService";
$soapcert = $this->getCertificate();
$soapqryid = $pId;
$soapqryact = $pAction;
$soapqrynewp = $pNewPassword;
$soapqryoldp = $pOldPassword;
$soapqryphash = $pIsOldPasswordHashed;
$soapqrysecq = $pSecretQ;
$soapqryseca = $pSecretA;
$soapqrymail = $pSendMail;
$soapqry = '<?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="' . $soapenv . '">';
$soapqry .= '<SOAP-ENV:Body>';
$soapqry .= '<saba:' . $soapcommand . ' xmlns:saba="' . $soapurl . '">';
$soapqry .= '<certificate>' . $soapcert . '</certificate>';
$soapqry .= '<id>' . $soapqryid . '</id>';
$soapqry .= '<action>' . $soapqryact . '</action>';
$soapqry .= '<newPass>' . $soapqrynewp . '</newPass>';
$soapqry .= '<oldPass>' . $soapqryoldp . '</oldPass>';
$soapqry .= '<isOldPasswordHashed>' . $soapqryphash . '</isOldPasswordHashed>';
$soapqry .= '<secretQuestion>' . $soapqrysecq . '</secretQuestion>';
$soapqry .= '<secretAnswer>' . $soapqryseca . '</secretAnswer>';
$soapqry .= '<sendMail>' . $soapqrymail . '</sendMail>';
$soapqry .= '</saba:' . $soapcommand . '>';
$soapqry .= '</SOAP-ENV:Body>';
$soapqry .= '</SOAP-ENV:Envelope>';
$url = $soapurl . '/' . $soapcommand;
$headers = array(
"Content-type: text/xml;charset='"utf-8'"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: " . $url,
"Content-length: " . strlen($soapqry),
);
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 10000);
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $soapqry);
$response = curl_exec($handle);
curl_close($handle);
var_dump($response);
//return $response;
}
}
SOAP包装器和XML可以以不同的方式编写,而不是添加到字符串中,但我目前正在开发中,只是试图使其工作。
我的第一反应是web服务不存在,但它确实存在。
在saba中,web服务部分:
Name* cspsRetrievePassword
Java Class* csps.CspsRetrievePasswordCommand
如果需要,我可以粘贴我的自定义java类,但主要部分都是
public class CspsRetrievePasswordCommand extends SabaWebCommand
public CspsRetrievePasswordCommand()
throws SabaException
{
addInParam("id", String.class, " person id");
addInParam("action", String.class, "action value");
addInParam("newPass", String.class, " new password ");
addInParam("oldPass", String.class, " old password ");
addInParam("isOldPasswordHashed", String.class, " is old password in hashed format");
addInParam("secretQuestion", String.class, " secret question");
addInParam("secretAnswer", String.class, " secret answer");
addInParam("sendMail", String.class, " send Mail?");
}
public void doExecute(HttpServletRequest request, IXMLVisitor visitor)
我的第二个反应是$url语法不正确。
我尝试了以下操作,但没有成功:
- /轴/服务/InfoService/cspsRetrievePassword
- /轴/服务/InfoService吗?cspsRetrievePassword
- /轴/服务/InfoService
最后一个,调用web服务而没有在URL中包含命令,并且只在SOAP查询中,给了我一个不同的错误:
string(436) " (70034) Exception in executing info service: @001 java.lang.NullPointerException "
任何帮助都将是非常感激的。
谢谢!
我终于找到了解决问题的办法。
首先要做的就是向CURLOPT_POSTFIELDS
添加一个元素$soapqry应该如下所示:(注意<查询>)查询>
$soapqry = '<?xml version="1.0" encoding="utf-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="' . $soapenv . '">';
$soapqry .= '<SOAP-ENV:Body>';
$soapqry .= '<saba:' . $soapcommand . ' xmlns:saba="' . $soapurl . '">';
$soapqry .= '<certificate>' . $soapcert . '</certificate>';
$soapqry .= '<query>';
$soapqry .= '<id>' . $soapqryid . '</id>';
$soapqry .= '<action>' . $soapqryact . '</action>';
$soapqry .= '<newPass>' . $soapqrynewp . '</newPass>';
$soapqry .= '<oldPass>' . $soapqryoldp . '</oldPass>';
$soapqry .= '<isOldPasswordHashed>' . $soapqryphash . '</isOldPasswordHashed>';
$soapqry .= '<secretQuestion>' . $soapqrysecq . '</secretQuestion>';
$soapqry .= '<secretAnswer>' . $soapqryseca . '</secretAnswer>';
$soapqry .= '<sendMail>' . $soapqrymail . '</sendMail>';
$soapqry .= '</query>';
$soapqry .= '</saba:' . $soapcommand . '>';
$soapqry .= '</SOAP-ENV:Body>';
$soapqry .= '</SOAP-ENV:Envelope>';
第二步是确保CURLOPT_URL只是/infoservice url,没有命令
$url = "https://mydomain/axis/services/InfoService";
curl_setopt($handle, CURLOPT_URL, $url);
第三种方法是将CURLOPT_HTTPHEADER中的SOAPAction设置为命令本身,不带url
$headers = array(
"Content-type: text/xml;charset='"utf-8'"",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: " . $soapcommand,
"Content-length: " . strlen($soapqry)
);
希望这将帮助其他人如何使用SABA web服务与PHP