-
Notifications
You must be signed in to change notification settings - Fork 5
Authentication
There's lots of ways to authenticate.
Microsoft accounts are the ones that look like email addresses, previously known as "passport", and have many similarities with previous MSN login methods.
This method works for HTTPS longpolling connections, using http headers and cookies, and is the outlook.com web client uses.
This is based on the method that the skype clients use for microsoft account, but just getting the resulting cookies.
Open a browser to
https://login.live.com/oauth20_authorize.srf?client_id=00000000480BC46C&scope=service%3A%3Alw.skype.com%3A%3AMBI_SSL&response_type=token&redirect_uri=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf&state=999&locale=en
Allow the user to log in as normal. When they're done, the browser will be redirected to https://login.live.com/oauth20_desktop.srf
with an enormous fragment. The fragment might be useful, but what the webclient requires is the three cookies MSPAuth
, MSPProf
, WLSSC
.
note that this client ID is the only one with access to the service::skype.com::MBI_SSL
scope (as far as we know), previously created oauth2 clients ids (such as those needed for the now-defunct MSN XMPP gateway) won't work here.
Similarly, the redirect_uri
parameter can't be changed to something more useful, returning this error in the fragment:
The provided value for the input parameter
redirect_uri
is not valid. The expected value ishttps://login.live.com/oauth20_desktop.srf
or a URL which matches the redirect URI registered for this client application.
See also:
Request the same URL as the previous section. Keep the MSPOK cookie.
Buried in the Javascript is a HTML <input>
element, with name="PPFT"
. Keep the value
attribute of this element.
Using the same query string as the first request, POST to https://login.live.com/ppsecure/post.srf
, with the MSPOK
cookie and a body consisting of url-encoded parameters:
Parameter | Notes |
---|---|
PPFT | The PPFT value you got from the first request |
login | Microsoft account name |
passwd | Password for that account |
If all goes well, you are redirected to the same place as the previous section. If not, look for sErrTxt:
followed by a Javascript string, the string including an error message.
When sending HTTPS requests to the gateway, include the X-MSN-Auth: Use-Cookie
header and the MSPAuth
, MSPProf
, WLSSC
cookies from above
Then, when sending the ATH command, use <user><web-compact-ticket /></user>
as the whole payload.
ATH 2 CON\USER 37
<user><web-compact-ticket /></user>
The outlook.com web client seems to request a UIC too from https://skypewebexperience.live.com/v1/User/Initialization
(with cookies + the trouterurl
and connectionid
POST parameters). If requested correctly, the UIC is in the MappingContainer field of the json response.
The Location: HTTP-Header field in the 302 redirect from post.srf above contains a redirect-URL of oauth20_desktop.srf which contains an access_token and a refresh_token which you should extract (note that it's URLencoded, of course!):
Location: https://login.live.com/oauth20_desktop.srf?lc=1031#access_token=....very long base64 string here....&token_type=bearer&expires_in=86400&scope=service::lw.skype.com::MBI_SSL&refresh_token=....another base64 string....&state=999&user_id=...some hex int64...
There is also expires_in parameter in seconds that specifies the number of seconds from now on when the acquired token expires. Currently this is always 1 day.
Using the refresh_token, POST to https://login.live.com/oauth20_token.srf
with parameters
client_id=00000000480BC46C&scope={requested scope}&grant_type=refresh_token&refresh_token={refresh_token}
as described in the OAuth docs by Microsoft. The requested scope can be one of the following:
Scope | Description |
---|---|
service::login.skype.com::MBI_SSL | Required for Login on real Skype Login-Server using i.e. skylogin. This is the way Skype does it. |
service::ssl.live.com::MBI_SSL | To be used as <ssl-compact-ticket> on ATH CON\USER on Skype login |
service::chatservice.live.com::MBI_SSL | To be used as <ssl-compact-ticket> on ATH CON\USER on MSN login |
service::contacts.msn.com::MBI_SSL | Used for Contact list handling already known from MSNP18 |
service::m.hotmail.com::MBI_SSL | ActiveSync contactlist auth token, if you want (and can) use it. |
service::lw.skype.com::MBI_SSL | Used i.e. to get skype_token for cloud based APIs |
You get back a bunch of JSON data to parse including the same parameters as in the OAuth Location: response above. You need to extract the access_token from there:
{ "access_token":"....some base64 encoded token you need...", "expires_in":86400, "refresh_token":"...base64 encoded refresh token, not needed...", "scope":"...the scope that you requested...", "token_type":"bearer", "user_id":"...your user_id..." }
This method can be used to authenticate with the help of our SkyLogin library and the Skype login-Servers.
Just fetch the service::ssl.live.com::MBI_SSL token via the method mentioned above.
The UIC is required to successfully logon. First, fetch a service::login.skype.com::MBI_SSL token via the method mentioned above. Call SkyLogin_PerformLoginOAuth() with that token as a parameter. Then call SkyLogin_GetCredentialsUIC() with an output buffer of 1024 bytes to fill in UIC.
If it was successful, do login with:
ATH 2 CON\USER 110
<user>
<ssl-compact-ticket>t={service::ssl.live.com::MBI_SSL token}</ssl-compact-ticket>
<uic>{UIC acquired from Skylogin}</uic>
<id>{Your MSN username}</id>
<alias>{Username of Skype Partner account}</alias>
</user>
If you don't have the username of the Skype Partner account, you can get it from Skylogin with SkyLogin_GetUser().
This method can be used to authenticate with just plain Web-Calls without the need to use our Skylogin-Library. This is not working anymore, as skypewebexperience host went down. Use skylogin library
If you want to use the cloud based APIs, i.e. for Sharing images with other contacts via the Microsoft servers (don't expecty any privacy by using MSN protocol anyway, everything is stored and logged on Microsoft's servers), you need another token, the skype_token. Here is how to get it:
- Fetch service::lw.skype.com::MBI_SSL OAuth token
Get the service::lw.skype.com::MBI_SSL
OAuth token like described in Authenticating with oauth.
- Request skypetoken
POST https://api.skype.com/rps/skypetoken
with the following POST fields:
scopes: client
clientVersion: 0/7.4.85.102/259/
access_token: {skype.com oauth token}
partner: 999
and you will receive the token as json:
{
"expiresIn": 86400,
"skypetoken": "....base64 skype token..."
}
Logging in with skype usernames requires using a bunch of cryptography to generate the UIC as well.
There's a python implementation of skype username login here: https://github.com/uunicorn/pyskype We wrote our own C implementation (the already mentioned SkyLogin library) that you can use as a library for your client: https://github.com/msndevs/skylogin
The login flow with a Skype username is easer than all the OAuth stuff required for MSN accounts mentioned above. On CNT call, you get a nonce:
CNT 5 CON 126
<connect-response>
<ver>2</ver>
<qostest>false</qostest>
<nonce>3d97e3ac-4df8-3d88-c35f-e96242d1efcd</nonce>
</connect-response>
User Skylogin SkyLogin_PerformLogin() with username and password to login to Skype server. Then generate the UIC with SkyLogin_CreateUICString() using the given nonce and you get back a UIC if login succeeds. Then just login with that UIC:
ATH 2 CON\USER 110
<user><uic>{your UIC}</uic><id>{Your Skype Username}</id></user>
If you want to use the cloud based APIs, i.e. for Sharing images with other contacts via the Microsoft servers (don't expecty any privacy by using MSN protocol anyway, everything is stored and logged on Microsoft's servers), you need another token, the skype_token. Here is how to get it:
- Calculate passwordHash The passwordHash is the base64-encoded form of the well known MD5-Hash from Skype login:
{username}\nskyper\n{password}
(without curly braces, I just use them to indicate a variable, \n is a newline as known from printf).
- Request skypetoken
POST https://api.skype.com/login/skypetoken
with the following POST fields:
scopes: client
clientVersion: 0/7.4.85.102/259/
username: {username}
passwordHash: {pw hash calculated in 1.}
and you will receive the token as json:
{
"expiresIn": 86400,
"skypetoken": "....base64 skype token..."
}
#After ATH After you sent your ATH and login succeeded, you receive an auth-response:
ATH 6 CON 131
<auth-response>
<new-thread-allowed>false</new-thread-allowed>
<p2p-migration-allowed>false</p2p-migration-allowed>
</auth-response>
Following that, you need to introduce your client to the server by sending the BND CON\MSGR command to the server:
BND 7 CON\MSGR 180
<msgr>
<ver>2</ver>
<altVersions><ver>1</ver></altVersions>
<client>
<name>Skype</name>
<ver>0/6.16.0.105/259/</ver>
</client>
<epid>EB80C4E5-10DC-11D2-8C04-00A0C94C5D75</epid>
</msgr>
epid
is an UUID identifying your machine. This is already known from
earlier MSN versions.
ver
specifies the protocol version you support. In Version 2, you can register
for status notifications and get and must send Registration: MIME-Headers.
The server replies with a BND answer and a nonce that you need to auth with:
BND 7 CON 660
UtcTime: 1431516231
Set-Registration: ....long base64 string....
Registration-Token-Expiry: 1431602631
Context: 1B8D4AA7AD8F8D02
<msgr-response>
<ver>2</ver>
<utctime>1431514361</utctime>
<nonce>1489346893432768563572687681</nonce>
<sample-window>0</sample-window>
</msgr-response>
You need to calculate a challenge from the Nonce to authenticate yourself as official client. The algorithm is the same as with earlier CHL-Answers in protocol. This involves calculation based on Protocol Challenge and Product ID. You can use:
Key | Value |
---|---|
productKey | YMM8C_H7KCQ2S_KL |
productId | PROD0090YUAUV{2B |
After calculating the challenge from it, issue a PUT MSGR\CHALLENGE with that in order to login:
PUT 8 MSGR\CHALLENGE 531
Registration: ....long base64 string you received from Set-Registration answer....
<challenge>
<appId>PROD0090YUAUV{2B</appId>
<response>c99982d67ac970226e97c23b686d06cc</response>
</challenge>
appId
is the productKey to be sent.
As an answer you receive another ATH CON reply:
ATH 0 CON 158
Context: 1B8D4AA7AD8F8D02
<auth-response>
<new-thread-allowed>false</new-thread-allowed>
<p2p-migration-allowed>false</p2p-migration-allowed>
</auth-response>
Now you are successfully logged in and can propagate your online status
with PUT MSGR\PRESENCE
etc.
In order to not drop off the network, you need to resend ATH CON\USER
command every 23 hours.
If you are using i.e. OAuth Tokens, be sure to refresh them before so that they aren't expired.
You receive the above mentioned reply, but you don't need to do anything further like sending BND
, ATH
is enough to refresh the connection.
If you do not refresh connection, you are receiving error 922 after expiration (usually 24 hours) on next action.