EWS SOAP Requests failing
我正在使用 PERL 和 SOAP::Lite 对 MS Exchange Web 服务进行肥皂调用。我已经弄清楚了身份验证并正在使用 Oauth 令牌进行调用。我正在尝试调用此处记录的 GetInboxRules。
基本上调用应该是这样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2010_SP1" /> </soap:Header> <soap:Body> <m:GetInboxRules> <m:MailboxSmtpAddress>[email protected]</m:MailboxSmtpAddress> </m:GetInboxRules> </soap:Body> </soap:Envelope> |
我的第一次尝试使用了以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | my $client = SOAP::Lite->service('file://home/auth/work/src/ben/services.wsdl')->proxy('https://outlook.office365.com/EWS/Exchange.asmx'); $client->readable(1)->autotype(0)->outputxml('true'); $client->ns('http://schemas.microsoft.com/exchange/services/2006/messages', 'm'); my $ua = $client->schema->useragent; $ua->default_header('Authorization' => $auth_header); $ua->default_header('Content-Type' => 'application/xml'); $client->schema->useragent($ua); $client->transport->http_request->headers->push_header('Authorization'=> $auth_header); # WITH URI my $som = $client->call('GetInboxRules', SOAP::Data->name('MailboxSmtpAddress')->value('[email protected]')->uri('http://schemas.microsoft.com/exchange/services/2006/messages')); |
这产生了以下 XML 以及 500 内部服务器错误声明:
"请求未通过架构验证:命名空间 \\'http://schemas.microsoft.com/exchange/services/2006/messages\\' 中的元素 \\'GetInboxRules\\' 具有无效的子元素 \\'MailboxSmtpAddress\\' . 预期的可能元素列表:\\'MailboxSmtpAddress\\' 在命名空间 \\'http://schemas.microsoft.com/exchange/services/2006/messages\\'"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <m:GetInboxRules> <MailboxSmtpAddress>[email protected]</MailboxSmtpAddress> </m:GetInboxRules> </soap:Body> </soap:Envelope> |
我已经在设置名称空间,但为了尝试解决这个问题,我通过向 MailboxSmtpAddress 元素添加 uri 规范来指定名称空间
产生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:namesp3="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <m:GetInboxRules> <namesp3:MailboxSmtpAddress xmlns:namesp3="http://schemas.microsoft.com/exchange/services/2006/messages">[email protected]</namesp3:MailboxSmtpAddress> </m:GetInboxRules> </soap:Body> </soap:Envelope> |
随后是 400 Bad Request 响应。我猜测错误的请求响应是因为 MailboxSmtpAddress 标记中包含 url,但我不知道如何指定命名空间。
这是我第一次使用 SOAP,因此非常感谢任何建议。
一位圣人救了我,并给了我以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | my $client = SOAP::Lite ->readable(1) ->proxy('https://outlook.office365.com/EWS/Exchange.asmx') ->ns( 'http://schemas.microsoft.com/exchange/services/2006/types', 'typ') ->ns( 'http://schemas.microsoft.com/exchange/services/2006/messages', 'mes') ->envprefix('soapenv') ->autotype(0); $client->serializer->{'_attr'}{'{http://schemas.xmlsoap.org/soap/envelope/}encodingStyle'} = undef; $client->transport->default_header('Authorization' => $auth_header); $client->transport->default_header('X-AnchorMailbox' => '[email protected]'); $client->transport->default_header('X-OWA-ExplicitLogonUser' => '[email protected]'); my @header = ( SOAP::Header->name('typ:RequestServerVersion')->attr({'Version' => 'Exchange2015'}), SOAP::Header->name('typ:ExchangeImpersonation')->value(\\SOAP::Header->name('typ:ConnectingSID') ->value(\\SOAP::Header->name('typ:SmtpAddress')->value('[email protected]'))) ); my @param; my $method; @param = ( SOAP::Data->name('mes:MailboxSmtpAddress', '[email protected]'), ); $method = SOAP::Data->name('mes:GetInboxRules'); my $response = $client->call($method => (@param, @header)); print Dumper($response); |
这导致命名空间标记被放置在传递给方法调用的元素上,并且还纠正了我在标题格式方面遇到的一些问题。
以下是来自该代码的 XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <soapenv:Envelope xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <typ:RequestServerVersion Version="Exchange2015" /> <typ:ExchangeImpersonation> <typ:ConnectingSID> <typ:SmtpAddress>[email protected]</typ:SmtpAddress> </typ:ConnectingSID> </typ:ExchangeImpersonation> </soapenv:Header> <soapenv:Body> <mes:GetInboxRules> <mes:MailboxSmtpAddress>[email protected]</mes:MailboxSmtpAddress> </mes:GetInboxRules> </soapenv:Body> </soapenv:Envelope> |
这引起了 Microsoft 的成功响应。