網路上有現成的 class 可以使用,請參閱:phpmsnclass V1.11,這是他的 Google Code。現成的類別很方便使用,所以在這裡就不多說關於類別的事情,我這邊從 protocol 開始,也許有人會覺得繁瑣,不過,就當作是我自己筆記用的好了,關於 MSN protocol 可以參考這裡:http://msnpiki.msnfanatic.com/index.php/Main_Page
首先,我們先從 SSO(Single Sign-On) 說起。我們利用 PHP 的 Curl 函式,將我們所要做的認證送給 MSN 伺服器。
關於 SSO 所需要傳送的 XML 規格,可以參考這裡:http://msnpiki.msnfanatic.com/index.php/MSNP15:SSO 由 SSO 的狀況我們可以知道,總共有 RST0 ~ RST7 等八種狀態的 Ticket Token,分別是:
- RST0:Passport.net 認證。
- RST1:Messenger Live 認證。
- RST2:MSN Messenger 認證。
- RST3:MSN 聯絡人清單認證。
- RST4:Messenger Live OIM 離線訊息認證。
- RST5:Live Spaces 認證。
- RST6:Live 聯絡人清單認證。
- RST7:Live Storage 認證。
以上這個順序是依照 SSO 的清單所列出來的,這些順序資料跟現成的 Class 並不太相同,當然,順序是可以自己修改的,所以也不一定是這種序列,這裡只是提出來說明,關於 SSO 可以傳送並取得的 token 有這些。至於傳送的方式,我用第一個 Passport.net 認證舉例,他是這麼寫的:
<?php
$userid = ''; // 你的帳號
$password = ''; // 你的密碼
$XML = '<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext"
xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:wssc="http://schemas.xmlsoap.org/ws/2004/04/sc"
xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust">
<Header>
<ps:AuthInfo xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="PPAuthInfo">
<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>
<ps:BinaryVersion>4</ps:BinaryVersion>
<ps:UIVersion>1</ps:UIVersion>
<ps:Cookies></ps:Cookies>
<ps:RequestParams>AQAAAAIAAABsYwQAAAAxMDMz</ps:RequestParams>
</ps:AuthInfo>
<wsse:Security>
<wsse:UsernameToken Id="user">
<wsse:Username>'.$userid.'</wsse:Username>
<wsse:Password>'.$password.'</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</Header>
<Body>
<ps:RequestMultipleSecurityTokens xmlns:ps="http://schemas.microsoft.com/Passport/SoapServices/PPCRL" Id="RSTS">
<wst:RequestSecurityToken Id="RST0">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>
<wsp:AppliesTo>
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
</wst:RequestSecurityToken>
</ps:RequestMultipleSecurityTokens>
</Body>
</Envelope>';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://login.live.com/RST.srf');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $XML);
$data = curl_exec($curl);
curl_close($curl);
$fp = fopen('./test.log', 'a+');
if ($fp) {
fputs($fp, $data);
fclose($fp);
}
直接運行之後,他會產生一個叫做 test.log
的檔案,那個檔案就是 MSN 伺服器所返回的資料。至於他會返回些甚麼呢?我這邊舉兩個例子,一個是返回認證失敗的內容,另一個則是返回認證成功的內容。
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:authstate>0x80048800</psf:authstate>
<psf:reqstatus>0x80048820</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="2009-07-02T02:28:07Z">BAYIDSLGN1K12 2009.05.08.01.28.02</psf:serverInfo>
<psf:cookies/>
<psf:response/>
</psf:pp>
</S:Header>
<S:Fault>
<faultcode>S:Client</faultcode>
<faultstring>Invalid Request</faultstring>
</S:Fault>
</S:Envelope>
這是返回失敗的例子,注意到他有 <faultcode>
的返回項目,代表著你傳送的資料有錯誤。
<?xml version="1.0" encoding="utf-8" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<psf:pp xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<psf:serverVersion>1</psf:serverVersion>
<psf:PUID>0003BFFD93BB0005</psf:PUID>
<psf:configVersion>6.0.11409.0</psf:configVersion>
<psf:uiVersion>3.100.2179.0</psf:uiVersion>
<psf:authstate>0x48803</psf:authstate>
<psf:reqstatus>0x0</psf:reqstatus>
<psf:serverInfo Path="Live1" RollingUpgradeState="ExclusiveNew" LocVersion="0" ServerTime="2009-07-02T02:28:51Z">BAYIDSLGN1S18 2009.05.08.01.28.02</psf:serverInfo>
<psf:cookies/>
<psf:browserCookies>
<psf:browserCookie Name="MH" URL="http://www.msn.com">MH=MSFT; path=/; domain=.msn.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.msn.com">MHW=; path=/; domain=.msn.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MH" URL="http://www.live.com">MH=MSFT; path=/; domain=.live.com; expires=Wed, 30-Dec-2037 16:00:00 GMT</psf:browserCookie>
<psf:browserCookie Name="MHW" URL="http://www.live.com">MHW=; path=/; domain=.live.com; expires=Thu, 30-Oct-1980 16:00:00 GMT</psf:browserCookie>
</psf:browserCookies>
<psf:credProperties>
<psf:credProperty Name="MainBrandID">MSFT</psf:credProperty>
<psf:credProperty Name="BrandIDList">
</psf:credProperty>
<psf:credProperty Name="IsWinLiveUser">false</psf:credProperty>
<psf:credProperty Name="CID">e75f7fe32aea2838</psf:credProperty>
<psf:credProperty Name="AuthMembername">[email protected]</psf:credProperty>
</psf:credProperties>
<psf:extProperties>
<psf:extProperty Name="ANON" Expiry="Mon, 18-Jan-2010 10:28:51 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">A=AC09B2815155B5C33BA3E160FFFFFFFF&E=88d&W=1</psf:extProperty>
<psf:extProperty Name="NAP" Expiry="Sat, 10-Oct-2009 09:28:51 GMT" Domains="bing.com;atdmt.com" IgnoreRememberMe="false">V=1.9&E=833&C=iruWWhJxoXnSMAY9Xbla_KEevr9BKN2iBGAXwaBzpLkBfOohtiiAYg&W=1</psf:extProperty>
<psf:extProperty Name="LastUsedCredType">1</psf:extProperty>
</psf:extProperties>
<psf:response/>
</psf:pp>
</S:Header>
<S:Body>
<wst:RequestSecurityTokenResponseCollection xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wst="http://schemas.xmlsoap.org/ws/2004/04/trust" xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" xmlns:psf="http://schemas.microsoft.com/Passport/SoapServices/SOAPFault">
<wst:RequestSecurityTokenResponse>
<wst:TokenType>urn:passport:legacy</wst:TokenType>
<wsp:AppliesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
<wsa:EndpointReference>
<wsa:Address>http://Passport.NET/tb</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<wst:LifeTime>
<wsu:Created>2009-07-02T02:28:51Z</wsu:Created>
<wsu:Expires>2009-07-03T02:28:51Z</wsu:Expires>
</wst:LifeTime>
<wst:RequestedSecurityToken>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#" Id="BinaryDAToken0" Type="http://www.w3.org/2001/04/xmlenc#Element">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc">
</EncryptionMethod>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>http://Passport.NET/STS</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>ATcwZCPTlRTD4abiB7sCiS/9oQTlN+Zd3Z1X/Umfr42gJ6PPSiDP7CBqvDMIB+rfUeENFM2ksp03CojxKV2HH1UrLpqhA1D5rgnEFhNZWQxRpoWlFUo21FMzP2j01w12aFPrvvIJrex7E+BKdWoKEymOeGctKYS0xf6bd6JzCDvtBtEeUd5GQatYCRXrhRU7214/udW0yw+y+Mx6VnRdAYoPAm+jap8HsMbTEQB7u3X6Odcz2wuZB6/8GByvbqLaOwR0jcYNyOiMvUeXZYa6A3b19xFHfQGsNYARVuYkSp748NVwMloBsnWElRW3ynvujzWMTeBPRsCxW+oYCfrCrslR+t9d/Di8vmW5AbAnmLQni0reLW/qmPZwY8u5FuvWmIedIUA7Hs7Yf3Z6dNOHjypPBl5Ml7AJxjCqDbZraUqEaUMiemjw+JQ/W/4JpMsZ3pPhYcQDJRv9sjDaZFcFwQbZYmnoCKebpmiZetkJthAmaTahOezHBl13NHsz</CipherValue>
</CipherData>
</EncryptedData>
</wst:RequestedSecurityToken>
<wst:RequestedTokenReference>
<wsse:KeyIdentifier ValueType="urn:passport">
</wsse:KeyIdentifier>
<wsse:Reference URI="#BinaryDAToken0">
</wsse:Reference>
</wst:RequestedTokenReference>
<wst:RequestedProofToken>
<wst:BinarySecret>mnJ+1QLiTC4SLDgLZI5bz+J6qZbwTBlr</wst:BinarySecret>
</wst:RequestedProofToken>
</wst:RequestSecurityTokenResponse>
</wst:RequestSecurityTokenResponseCollection>
</S:Body>
</S:Envelope>
這是返回成功的例子,留意,它返回了 wst:BinarySecret>
的部分,就是我們所需要的 Token 資料。另外,並不是每一種返回都會是 <wst:BinarySecret>
,而是 Passport 比較特別,其餘的 Protocol 都是返回 <wsse:BinarySecurityToken ...>
這種形式,所以在取用上會略有不同。
所以當我們依照上述的順序來傳送所有的資料,並取回 token 的時候,利用正規表示式將這些 Token 分別取出來,那麼他們的順序如下:
- Passport.net / MSN Messanger 認證。
- Passport.net / MSN Messanger 認證(Binary Secret)。
- MSN Messanger 認證。
- Messanger 聯絡人認證。
- MSN Messanger OIM 離線訊息認證。
- Live Spaces 認證。
- Live 聯絡人清單認證。
- Live Storage 認證。
以上,是對於 SSO 的簡單介紹。下一篇我將簡單介紹一下如何與 MSN 伺服器做連線溝通。
附註:還有更強大的 .net 套件,請拜:http://code.google.com/p/msnp-sharp/