https://wiki.vg/api.php?action=feedcontributions&user=JakobDev&feedformat=atomwiki.vg - User contributions [en]2024-03-29T11:04:37ZUser contributionsMediaWiki 1.34.4https://wiki.vg/index.php?title=User:JakobDev&diff=18276User:JakobDev2023-06-15T17:50:08Z<p>JakobDev: Created page with "Author of [https://codeberg.org/JakobDev/minecraft-launcher-lib minecraft-launcher-lib]"</p>
<hr />
<div>Author of [https://codeberg.org/JakobDev/minecraft-launcher-lib minecraft-launcher-lib]</div>JakobDevhttps://wiki.vg/index.php?title=Microsoft_Authentication_Scheme&diff=18275Microsoft Authentication Scheme2023-06-15T17:48:57Z<p>JakobDev: Mention that you now need to apply for Permission to use the Azure App with the Minecraft API</p>
<hr />
<div>Minecraft is moving to Microsoft accounts. Starting December 2020, all new Accounts already use the new system, old accounts will be migrated later, see [https://www.minecraft.net/en-us/article/java-edition-moving-house this blog post]<br />
<br />
There are multiple steps and different tokens required, but in the end, you get a normal Minecraft token back. Launching the game itself hasn't changed.<br />
<br />
== Microsoft OAuth2 Flow ==<br />
<br />
Prior to any of these steps, you will first need to obtain an OAuth 2.0 client ID by [https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app creating a Microsoft Azure application]. You will ''not'' need to obtain a client secret.<br />
<br />
You can then use the [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow OAuth2 authorization code flow] to obtain an access token. You'll need to present the user with a login page that, once completed, will redirect to a specified URL with the token in the query parameters. In non-web applications this typically involves spinning up a temporary HTTP server to handle the redirect. If you'd rather not do that, consider using the (slightly less automatic) [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-device-code device code flow] instead.<br />
<br />
In any case, you'll need to include <code>XboxLive.signin</code> in the <code>scope</code> parameter of the authorization request; otherwise the next endpoint will complain, and not in a helpful way.<br />
<br />
According to [https://help.minecraft.net/hc/en-us/articles/16254801392141p this support Article], new created Azure Apps must apply for the Permission to use the Minecraft API using [https://aka.ms/mce-reviewappid this form]. If your App don't have the Permission <code>api.minecraftservices.com</code> will return a 403.<br />
<br />
<i>Note: You <b>must</b> use the <code>consumers</code> AAD tenant to sign in with the <code>XboxLive.signin</code> scope. Using an Azure AD tenant ID or the <code>common</code> scope will just give errors. This also means you cannot sign in with users that are in the AAD tenant, only with consumer Microsoft accounts.</i><br />
<br />
== Authenticate with Xbox Live ==<br />
<br />
Now that we are authenticated with Microsoft, we can authenticate with Xbox Live.<br />
<br />
To do that, we send<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://user.auth.xboxlive.com/user/authenticate<br />
{<br />
"Properties": {<br />
"AuthMethod": "RPS",<br />
"SiteName": "user.auth.xboxlive.com",<br />
"RpsTicket": "d=<access token>" // your access token from the previous step here<br />
},<br />
"RelyingParty": "http://auth.xboxlive.com",<br />
"TokenType": "JWT"<br />
}<br />
</syntaxhighlight><br />
<br />
Again, it will complain if you don't set <code>Content-Type: application/json</code> and <code>Accept: application/json</code>.<br />
It will also complain if your SSL implementation does not support SSL renegotiations.<br />
<br />
The response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"IssueInstant":"2020-12-07T19:52:08.4463796Z",<br />
"NotAfter":"2020-12-21T19:52:08.4463796Z",<br />
"Token":"token", // save this, this is your xbl token<br />
"DisplayClaims":{<br />
"xui":[<br />
{<br />
"uhs":"userhash" // save this<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== Obtain XSTS token for Minecraft ==<br />
<br />
Now that we are authenticated with XBL, we need to get a XSTS token, we can use to login to Minecraft.<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://xsts.auth.xboxlive.com/xsts/authorize<br />
{<br />
"Properties": {<br />
"SandboxId": "RETAIL",<br />
"UserTokens": [<br />
"xbl_token" // from above<br />
]<br />
},<br />
"RelyingParty": "rp://api.minecraftservices.com/",<br />
"TokenType": "JWT"<br />
}<br />
</syntaxhighlight><br />
<br />
Again, set content type and accept to json and ensure SSL renegotiation is supported by your client.<br />
<br />
<blockquote><br />
''Note:'' When trying to get the XSTS token for the '''[[Bedrock_Realms|bedrock realms]] API''', you need to change the following: <br />
<syntaxhighlight lang="json">"RelyingParty": "https://pocket.realms.minecraft.net/"</syntaxhighlight><br />
<br />
also you can stop at this point, as the [[Bedrock_Realms|bedrock realms]] API uses the XSTS token directly instead of a seperate auth scheme.<br />
</blockquote><br />
<br />
Response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"IssueInstant":"2020-12-07T19:52:09.2345095Z",<br />
"NotAfter":"2020-12-08T11:52:09.2345095Z",<br />
"Token":"token", // save this, this is your xsts token<br />
"DisplayClaims":{<br />
"xui":[<br />
{<br />
"uhs":"userhash" // same as last request<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
The endpoint can return a 401 error with the below response:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"Identity":"0",<br />
"XErr":2148916238,<br />
"Message":"",<br />
"Redirect":"https://start.ui.xboxlive.com/AddChildToFamily"<br />
}<br />
</syntaxhighlight><br />
<br />
The Redirect parameter usually will not resolve or go anywhere in a browser, likely they're targeting Xbox consoles.<br />
<br />
Noted XErr codes and their meanings:<br />
<br />
* '''2148916233''': The account doesn't have an Xbox account. Once they sign up for one (or login through minecraft.net to create one) then they can proceed with the login. This shouldn't happen with accounts that have purchased Minecraft with a Microsoft account, as they would've already gone through that Xbox signup process.<br />
* '''2148916235''': The account is from a country where Xbox Live is not available/banned<br />
* '''2148916236''': The account needs adult verification on Xbox page. (South Korea)<br />
* '''2148916237''': The account needs adult verification on Xbox page. (South Korea)<br />
* '''2148916238''': The account is a child (under 18) and cannot proceed unless the account is added to a Family by an adult. This only seems to occur when using a custom Microsoft Azure application. When using the Minecraft launchers client id, this doesn't trigger.<br />
<br />
== Authenticate with Minecraft ==<br />
<br />
Now we can finally start talking to Minecraft. The XSTS token from the last request allows us to authenticate with Minecraft using<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://api.minecraftservices.com/authentication/login_with_xbox<br />
{<br />
"identityToken": "XBL3.0 x=<userhash>;<xsts_token>"<br />
}<br />
</syntaxhighlight><br />
<br />
Response:<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"username" : "some uuid", // this is not the uuid of the account<br />
"roles" : [ ],<br />
"access_token" : "minecraft access token", // jwt, your good old minecraft access token<br />
"token_type" : "Bearer",<br />
"expires_in" : 86400<br />
}<br />
</syntaxhighlight><br />
<br />
This access token allows us to launch the game, but, we haven't actually checked if the account owns the game. Everything until here works with a normal Microsoft account!<br />
<br />
== Checking Game Ownership ==<br />
<br />
So let's use our mc access token to check if a product licence is attached to the account.<br />
GET https://api.minecraftservices.com/entitlements/mcstore<br />
<br />
The access token goes into the auth header: <code>Authorization: Bearer <Minecraft Access Token></code>. (Keep in mind that <code>Bearer </code> is actually the prefix you must include!)<br />
<br />
If the account owns the game, the response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"items" : [ {<br />
"name" : "product_minecraft",<br />
"signature" : "jwt sig"<br />
}, {<br />
"name" : "game_minecraft",<br />
"signature" : "jwt sig"<br />
} ],<br />
"signature" : "jwt sig",<br />
"keyId" : "1"<br />
}<br />
</syntaxhighlight><br />
<br />
The first jwts contain the values:<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"typ": "JWT",<br />
"alg": "RS256",<br />
"kid": "1"<br />
}.{<br />
"signerId": "2535416586892404",<br />
"name": "product_minecraft"<br />
}.[Signature]<br />
</syntaxhighlight><br />
<br />
the last jwt looks like this decoded:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"typ": "JWT",<br />
"alg": "RS256",<br />
"kid": "1"<br />
}.{<br />
"entitlements": [<br />
{<br />
"name": "product_minecraft"<br />
},<br />
{<br />
"name": "game_minecraft"<br />
}<br />
],<br />
"signerId": "2535416586892404"<br />
}.[Signature]<br />
</syntaxhighlight><br />
If the account doesn't own the game, the items array will be empty.<br />
<br />
Note that Xbox Game Pass users don't technically own the game, and therefore will not show any ownership here, but will indeed have a Minecraft profile attached to their account.<br />
<br />
Note that the signature should always be checked with the public key from Mojang to verify that it is a legitimate response from the official servers:<br />
<syntaxhighlight><br />
-----BEGIN PUBLIC KEY-----<br />
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtz7jy4jRH3psj5AbVS6W<br />
NHjniqlr/f5JDly2M8OKGK81nPEq765tJuSILOWrC3KQRvHJIhf84+ekMGH7iGlO<br />
4DPGDVb6hBGoMMBhCq2jkBjuJ7fVi3oOxy5EsA/IQqa69e55ugM+GJKUndLyHeNn<br />
X6RzRzDT4tX/i68WJikwL8rR8Jq49aVJlIEFT6F+1rDQdU2qcpfT04CBYLM5gMxE<br />
fWRl6u1PNQixz8vSOv8pA6hB2DU8Y08VvbK7X2ls+BiS3wqqj3nyVWqoxrwVKiXR<br />
kIqIyIAedYDFSaIq5vbmnVtIonWQPeug4/0spLQoWnTUpXRZe2/+uAKN1RY9mmaB<br />
pRFV/Osz3PDOoICGb5AZ0asLFf/qEvGJ+di6Ltt8/aaoBuVw+7fnTw2BhkhSq1S/<br />
va6LxHZGXE9wsLj4CN8mZXHfwVD9QG0VNQTUgEGZ4ngf7+0u30p7mPt5sYy3H+Fm<br />
sWXqFZn55pecmrgNLqtETPWMNpWc2fJu/qqnxE9o2tBGy/MqJiw3iLYxf7U+4le4<br />
jM49AUKrO16bD1rdFwyVuNaTefObKjEMTX9gyVUF6o7oDEItp5NHxFm3CqnQRmch<br />
HsMs+NxEnN4E9a8PDB23b4yjKOQ9VHDxBxuaZJU60GBCIOF9tslb7OAkheSJx5Xy<br />
EYblHbogFGPRFU++NrSQRX0CAwEAAQ==<br />
-----END PUBLIC KEY-----<br />
</syntaxhighlight><br />
See the JWT standard[https://auth0.com/docs/tokens/json-web-tokens/validate-json-web-tokens] for more details.<br />
<br />
In case the public key ever changes, it can be extracted from the launcher library:<br />
<br />
<syntaxhighlight lang="bash"><br />
strings ~/.minecraft/launcher/liblauncher.so > launcher-strings.txt<br />
</syntaxhighlight><br />
<br />
The created file <code>launcher-strings.txt</code> will include 2 strings which begin with <code>-----BEGIN PUBLIC KEY-----</code> and end with <code>-----END PUBLIC KEY-----</code>.<br />
The first key seems to be the one used for the JWT tokens, use of the second key is unknown.<br />
<br />
== Getting the profile ==<br />
<br />
Now that we know that the account owns the game, we can get their profile in order to fetch the UUID:<br />
GET https://api.minecraftservices.com/minecraft/profile<br />
<br />
Again, the access token goes into the auth header: <code>Authorization: Bearer token</code><br />
<br />
The response will look like this, if the account owns the game:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"id" : "986dec87b7ec47ff89ff033fdb95c4b5", // the real uuid of the account, woo<br />
"name" : "HowDoesAuthWork", // the mc user name of the account<br />
"skins" : [ {<br />
"id" : "6a6e65e5-76dd-4c3c-a625-162924514568",<br />
"state" : "ACTIVE",<br />
"url" : "http://textures.minecraft.net/texture/1a4af718455d4aab528e7a61f86fa25e6a369d1768dcb13f7df319a713eb810b",<br />
"variant" : "CLASSIC",<br />
"alias" : "STEVE"<br />
} ],<br />
"capes" : [ ]<br />
}<br />
</syntaxhighlight><br />
<br />
Else it will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"path" : "/minecraft/profile",<br />
"errorType" : "NOT_FOUND",<br />
"error" : "NOT_FOUND",<br />
"errorMessage" : "The server has not found anything matching the request URI",<br />
"developerMessage" : "The server has not found anything matching the request URI"<br />
}<br />
</syntaxhighlight><br />
<br />
Note that Xbox Game Pass users who haven't logged into the new Minecraft Launcher at least once will not return a profile, and will need to login once after activating Xbox Game Pass to setup their Minecraft username.<br />
<br />
You should now have all necessary data (the mc access token, the username and the uuid) to launch the game. Well done!<br />
<br />
== Sample Implementations ==<br />
<br />
A fully working kotlin implementation can be found [https://gitlab.bixilon.de/bixilon/minosoft/-/blob/master/src/main/java/de/bixilon/minosoft/util/account/microsoft/MicrosoftOAuthUtils.kt] here using device tokens.<br />
<br />
A fully working cli wrapper in Java using device tokens [https://github.com/covers1624/DevLogin here] <br />
<br />
A rough sample implementation in Java (using javafx and its webview) [https://github.com/MiniDigger/MiniLauncher/blob/master/launcher/src/main/java/me/minidigger/minecraftlauncher/launcher/gui/MsaFragmentController.java here].<br />
<br />
An implementation in Go [https://gist.github.com/rbrick/be8ed86864fc5d77aa6c979053cfc892 here]. <br />
<br />
An implementation in JS can be found [https://github.com/PrismarineJS/node-minecraft-protocol/blob/master/src/client/microsoftAuth.js here] and one using JS/TS [https://gist.github.com/Plagiatus/ce5f18bc010395fc45d8553905e10f55 here]<br />
<br />
An implementation in Python can be found [https://codeberg.org/JakobDev/minecraft-launcher-lib/src/branch/master/minecraft_launcher_lib/microsoft_account.py here]<br />
<br />
An implementation in Rust can be found [https://gist.github.com/OverHash/a71b32846612ba09d8f79c9d775bfadf here].<br />
<br />
A Kotlin library (JVM + JS) can be found [https://github.com/TheNullicorn/ms-to-mca here].<br />
<br />
A C# library using webview and [https://github.com/AzureAD/microsoft-authentication-library-for-dotnet MSAL.NET] can be found [https://github.com/CmlLib/CmlLib.Core.Auth.Microsoft here].<br />
<br />
A Rust library can be found [https://crates.io/crates/minecraft-msa-auth here].<br />
<br />
A PHP library can be found [https://github.com/Aberdeener/minecraft-oauth/ here].</div>JakobDevhttps://wiki.vg/index.php?title=Microsoft_Authentication_Scheme&diff=16983Microsoft Authentication Scheme2021-09-04T20:05:16Z<p>JakobDev: Add Python implementation</p>
<hr />
<div>Minecraft is moving to Microsoft accounts. Starting December 2020, all new Accounts already use the new system, old accounts will be migrated later, see [https://www.minecraft.net/en-us/article/java-edition-moving-house this blog post]<br />
<br />
There are multiple steps and different tokens required, but in the end, you get a normal Minecraft token back. Launching the game itself hasn't changed.<br />
<br />
== Microsoft OAuth Flow ==<br />
[[File:minecraft_login.png|frame|Example of the login page]]<br />
<br />
Prior to any of these steps, you will first need to obtain an [https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow OAuth 2.0] Client ID & secret by creating a [https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app Microsoft Azure application].<br />
<br />
In the first step, we are logging into the Microsoft account. This has to be done in a browser/webview!<br />
<br />
The URL generated, either manually, or through an OAuth2 library, would look something like this:<br />
<br />
https://login.live.com/oauth20_authorize.srf<br />
?client_id=<your Azure client ID><br />
&response_type=code<br />
&redirect_uri=<your redirect uri><br />
&scope=XboxLive.signin%20offline_access //without offline_access you won't get an refresh_token<br />
&state=<optional; used to prevent CSRF & restoring previous application states><br />
<br />
<i>Note: You may also use the Azure Active Directory endpoints which would look like https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize but this just redirects to the live.com URL.</i><br />
<br />
<i>Note: If using the MSAL library to handle OAuth for you, you <b>must</b> use the <code>consumers</code> AAD tenant to sign in with the <code>XboxLive.signin</code> scope. Using an Azure AD tenant ID or the <code>common</code> scope will just give errors. This also means you cannot sign in with users that are in the AAD tenant, only with consumer Microsoft accounts.</i><br />
<br />
The user will be prompted to enter a username (E-Mail, Skype ID, Phone number, whatever) and their password. If those are valid, the user will be redirected. The user doesn't need to own MC, that check comes way later!<br />
<br />
The redirect will look something like this<br />
https://<your redirect URL>?code=codegoeshere&state=<optional; only if provided><br />
<br />
You have to extract the code param, it's your Microsoft Authorization Code.<br />
<br />
== Authorization Code -> Authorization Token ==<br />
<br />
The next step is to get an access token from the auth code. This isn't done in the browser for security reasons.<br />
<br />
<i>This exchange should be done on the server-side as it requires the use of your client secret which, as the name implies, should be kept secret.</i><br />
<br />
POST https://login.live.com/oauth20_token.srf<br />
client_id=<your client id><br />
&client_secret=<your client secret><br />
&code=<auth code / the code from step 1><br />
&grant_type=authorization_code<br />
&redirect_uri=<your redirect uri><br />
<br />
Don't forget to set <code>Content-Type: application/x-www-form-urlencoded</code><br />
<br />
The response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"token_type":"bearer",<br />
"expires_in":86400,<br />
"scope":"XboxLive.signin",<br />
"access_token":"token here",<br />
"refresh_token":"M.R3_BAY.token here",<br />
"user_id":"889ed4a3d844f672",<br />
"foci":"1"<br />
}<br />
</syntaxhighlight><br />
<br />
We care about the access_token here. <br />
<br />
== Refreshing Tokens ==<br />
You can use the refresh_token you got in the previous request to acquire a new access_token. Just call the same endpoint as before, switching out code for the refresh token and grant type <code>authorization_code</code> for <code>refresh_token</code><br />
<br />
POST https://login.live.com/oauth20_token.srf<br />
client_id=<your client id><br />
&client_secret=<your client secret><br />
&refresh_token=<refresh token from previous step><br />
&grant_type=refresh_token<br />
&redirect_uri=<your redirect uri><br />
<br />
(the response is the same as for requesting tokens with a code)<br />
<br />
== Authenticate with XBL ==<br />
<br />
Now that we are authenticated with Microsoft, we can authenticate to Xbox Live.<br />
<br />
To do that, we send<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://user.auth.xboxlive.com/user/authenticate<br />
{<br />
"Properties": {<br />
"AuthMethod": "RPS",<br />
"SiteName": "user.auth.xboxlive.com",<br />
"RpsTicket": "d=<access token>" // your access token from step 2 here<br />
},<br />
"RelyingParty": "http://auth.xboxlive.com",<br />
"TokenType": "JWT"<br />
}<br />
</syntaxhighlight><br />
<br />
Again, it will complain if you don't set <code>Content-Type: application/json</code> and <code>Accept: application/json</code><br />
<br />
The response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"IssueInstant":"2020-12-07T19:52:08.4463796Z",<br />
"NotAfter":"2020-12-21T19:52:08.4463796Z",<br />
"Token":"token", // save this, this is your xbl token<br />
"DisplayClaims":{<br />
"xui":[<br />
{<br />
"uhs":"userhash" // save this<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
We need to save token and userhash.<br />
<br />
== Authenticate with XSTS ==<br />
<br />
Now that we are authenticated with XBL, we need to get a XSTS token, we can use to login to Minecraft.<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://xsts.auth.xboxlive.com/xsts/authorize<br />
{<br />
"Properties": {<br />
"SandboxId": "RETAIL",<br />
"UserTokens": [<br />
"xbl_token" // from above<br />
]<br />
},<br />
"RelyingParty": "rp://api.minecraftservices.com/",<br />
"TokenType": "JWT"<br />
}<br />
</syntaxhighlight><br />
<br />
Again, set content type and accept to json.<br />
<br />
Response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"IssueInstant":"2020-12-07T19:52:09.2345095Z",<br />
"NotAfter":"2020-12-08T11:52:09.2345095Z",<br />
"Token":"token", // save this, this is your xsts token<br />
"DisplayClaims":{<br />
"xui":[<br />
{<br />
"uhs":"userhash" // same as last request<br />
}<br />
]<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
The endpoint can return a 401 error with the below response:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"Identity":"0",<br />
"XErr":2148916238,<br />
"Message":"",<br />
"Redirect":"https://start.ui.xboxlive.com/AddChildToFamily"<br />
}<br />
</syntaxhighlight><br />
<br />
The Redirect parameter usually will not resolve or go anywhere in a browser, likely they're targeting Xbox consoles.<br />
<br />
Noted XErr codes and their meanings:<br />
<br />
* '''2148916233''': The account doesn't have an Xbox account. Once they sign up for one (or login through minecraft.net to create one) then they can proceed with the login. This shouldn't happen with accounts that have purchased Minecraft with a Microsoft account, as they would've already gone through that Xbox signup process.<br />
* '''2148916235''': The account is from a country where Xbox Live is not available/banned<br />
* '''2148916238''': The account is a child (under 18) and cannot proceed unless the account is added to a Family by an adult. This only seems to occur when using a custom Microsoft Azure application. When using the Minecraft launchers client id, this doesn't trigger.<br />
<br />
== Authenticate with Minecraft ==<br />
<br />
Now we can finally start talking to Minecraft. The XSTS token from the last request allows us to authenticate to Minecraft using<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
POST https://api.minecraftservices.com/authentication/login_with_xbox<br />
{<br />
"identityToken": "XBL3.0 x=<userhash>;<xsts_token>"<br />
}<br />
</syntaxhighlight><br />
<br />
Response:<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"username" : "some uuid", // this is not the uuid of the account<br />
"roles" : [ ],<br />
"access_token" : "minecraft access token", // jwt, your good old minecraft access token<br />
"token_type" : "Bearer",<br />
"expires_in" : 86400<br />
}<br />
</syntaxhighlight><br />
<br />
This access token allows us to launch the game, but, we haven't actually checked if the account owns the game. Everything until here works with a normal Microsoft account!<br />
<br />
== Checking Game Ownership ==<br />
<br />
So let's use our mc access token to check if a product licence is attached to the account.<br />
GET https://api.minecraftservices.com/entitlements/mcstore<br />
<br />
The access token goes into the auth header: <code>Authorization: Bearer <Minecraft Access Token></code>. (Keep in mind that <code>Bearer </code> is actually the prefix you must include!)<br />
<br />
If the account owns the game, the response will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"items" : [ {<br />
"name" : "product_minecraft",<br />
"signature" : "jwt sig"<br />
}, {<br />
"name" : "game_minecraft",<br />
"signature" : "jwt sig"<br />
} ],<br />
"signature" : "jwt sig",<br />
"keyId" : "1"<br />
}<br />
</syntaxhighlight><br />
<br />
The first jwts contain the values:<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"typ": "JWT",<br />
"alg": "RS256",<br />
"kid": "1"<br />
}.{<br />
"signerId": "2535416586892404",<br />
"name": "product_minecraft"<br />
}.[Signature]<br />
</syntaxhighlight><br />
<br />
the last jwt looks like this decoded:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"typ": "JWT",<br />
"alg": "RS256",<br />
"kid": "1"<br />
}.{<br />
"entitlements": [<br />
{<br />
"name": "product_minecraft"<br />
},<br />
{<br />
"name": "game_minecraft"<br />
}<br />
],<br />
"signerId": "2535416586892404"<br />
}.[Signature]<br />
</syntaxhighlight><br />
If the account doesn't own the game, the items array will be empty.<br />
<br />
Note that the signature should always be checked with the public key from Mojang to verify that it is a legitimate response from the official servers:<br />
<syntaxhighlight><br />
-----BEGIN PUBLIC KEY-----<br />
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtz7jy4jRH3psj5AbVS6W<br />
NHjniqlr/f5JDly2M8OKGK81nPEq765tJuSILOWrC3KQRvHJIhf84+ekMGH7iGlO<br />
4DPGDVb6hBGoMMBhCq2jkBjuJ7fVi3oOxy5EsA/IQqa69e55ugM+GJKUndLyHeNn<br />
X6RzRzDT4tX/i68WJikwL8rR8Jq49aVJlIEFT6F+1rDQdU2qcpfT04CBYLM5gMxE<br />
fWRl6u1PNQixz8vSOv8pA6hB2DU8Y08VvbK7X2ls+BiS3wqqj3nyVWqoxrwVKiXR<br />
kIqIyIAedYDFSaIq5vbmnVtIonWQPeug4/0spLQoWnTUpXRZe2/+uAKN1RY9mmaB<br />
pRFV/Osz3PDOoICGb5AZ0asLFf/qEvGJ+di6Ltt8/aaoBuVw+7fnTw2BhkhSq1S/<br />
va6LxHZGXE9wsLj4CN8mZXHfwVD9QG0VNQTUgEGZ4ngf7+0u30p7mPt5sYy3H+Fm<br />
sWXqFZn55pecmrgNLqtETPWMNpWc2fJu/qqnxE9o2tBGy/MqJiw3iLYxf7U+4le4<br />
jM49AUKrO16bD1rdFwyVuNaTefObKjEMTX9gyVUF6o7oDEItp5NHxFm3CqnQRmch<br />
HsMs+NxEnN4E9a8PDB23b4yjKOQ9VHDxBxuaZJU60GBCIOF9tslb7OAkheSJx5Xy<br />
EYblHbogFGPRFU++NrSQRX0CAwEAAQ==<br />
-----END PUBLIC KEY-----<br />
</syntaxhighlight><br />
See the JWT standard[https://auth0.com/docs/tokens/json-web-tokens/validate-json-web-tokens] for more details.<br />
<br />
In case the public key ever changes, it can be extracted from the launcher library:<br />
<br />
<syntaxhighlight lang="bash"><br />
strings ~/.minecraft/launcher/liblauncher.so > launcher-strings.txt<br />
</syntaxhighlight><br />
<br />
The created file <code>launcher-strings.txt</code> will include 2 strings which begin with <code>-----BEGIN PUBLIC KEY-----</code> and end with <code>-----END PUBLIC KEY-----</code>.<br />
The first key seems to be the one used for the JWT tokens, use of the second key is unknown.<br />
<br />
== Get the profile ==<br />
<br />
Now that we know that the account owns the game, we can get their profile in order to fetch the UUID:<br />
GET https://api.minecraftservices.com/minecraft/profile<br />
<br />
Again, the access token goes into the auth header: <code>Authorization: Bearer token</code><br />
<br />
The response will look like this, if the account owns the game:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"id" : "986dec87b7ec47ff89ff033fdb95c4b5", // the real uuid of the account, woo<br />
"name" : "HowDoesAuthWork", // the mc user name of the account<br />
"skins" : [ {<br />
"id" : "6a6e65e5-76dd-4c3c-a625-162924514568",<br />
"state" : "ACTIVE",<br />
"url" : "http://textures.minecraft.net/texture/1a4af718455d4aab528e7a61f86fa25e6a369d1768dcb13f7df319a713eb810b",<br />
"variant" : "CLASSIC",<br />
"alias" : "STEVE"<br />
} ],<br />
"capes" : [ ]<br />
}<br />
</syntaxhighlight><br />
<br />
Else it will look like this:<br />
<br />
<syntaxhighlight lang="json" line='line'><br />
{<br />
"path" : "/minecraft/profile",<br />
"errorType" : "NOT_FOUND",<br />
"error" : "NOT_FOUND",<br />
"errorMessage" : "The server has not found anything matching the request URI",<br />
"developerMessage" : "The server has not found anything matching the request URI"<br />
}<br />
</syntaxhighlight><br />
<br />
You should know have all necessary data (the mc access token, the username and the uuid) to launch the game. Well done!<br />
<br />
== Sample Implementations ==<br />
<br />
There is a rough sample implementation in Java (using javafx and its webview) [https://github.com/MiniDigger/MiniLauncher/blob/master/launcher/src/main/java/me/minidigger/minecraftlauncher/launcher/gui/MsaFragmentController.java here], and in Go [https://gist.github.com/rbrick/be8ed86864fc5d77aa6c979053cfc892 here].<br />
[https://github.com/PrismarineJS/node-minecraft-protocol/blob/master/src/client/microsoftAuth.js Js implementation]<br />
<br />
A implementation in Kotlin (with JavaFX) can be found here: [https://gitlab.bixilon.de/bixilon/minosoft/-/blob/development/src/main/java/de/bixilon/minosoft/gui/main/dialogs/login/MicrosoftLoginController.java here] and [https://gitlab.bixilon.de/bixilon/minosoft/-/blob/development/src/main/java/de/bixilon/minosoft/util/microsoft/MicrosoftOAuthUtils.kt here]<br />
<br />
A implementation in Python can be found [https://gitlab.com/JakobDev/minecraft-launcher-lib/-/blob/master/minecraft_launcher_lib/microsoft_account.py here]</div>JakobDevhttps://wiki.vg/index.php?title=Library_List&diff=15147Library List2019-12-05T16:34:57Z<p>JakobDev: Add minecraft-launcher-lib</p>
<hr />
<div>{{ToolsNavbox}}<br />
This is a rather incomplete list of Minecraft related libraries finished or currently in development.<br />
{| class="wikitable sortable" style="width: auto; text-align: center;"<br />
|-style="background:#eee"<br />
!Name<br />
!class="unsortable"|Description<br />
!Author(s)<br />
!Language<br />
!License<br />
!Last Version Supported<br />
|-<br />
! [https://github.com/apotter96/GemBlocks GemBlocks]<br />
| C# library that easily saves/loads/generates worlds. Currently only has flatgrass. More to come. Based on [https://github.com/MorbZ/J2Blocks MorbZ's J2Blocks] (translated from java to C#).<br />
| [https://github.com/apotter96 apotter96]<br />
| {{C sharp}}<br />
| MIT<br />
| {{yes|All}}<br />
|-<br />
|-<br />
! [https://github.com/AlphaBs/MinecraftLauncherLibrary CmlLib]<br />
| C# Game launcher library. Launch all version including forge, Download game, Yggdrasil Authentication<br />
| [https://github.com/AlphaBs AlphaBs]<br />
| {{C sharp}}<br />
| [https://creativecommons.org/licenses/by-nc/4.0/ BY-NC 4.0]<br />
| {{yes|All}}<br />
|-<br />
! [https://github.com/Tnze/go-mc go-mc]<br />
| Go library of network protocol, NBT, Yggdrasil, mca file and RCON and so on.<br />
| [https://github.com/Tnze Tnze]<br />
| [https://golang.org/ Go]<br />
| {{MIT}}<br />
| {{yes|1.14.4}}<br />
|-<br />
! [https://github.com/Toranktto/CraftProtocol CraftProtocol]<br />
| Open source partial implementation of Minecraft network protocol and NBT in Python 2.7.<br />
| [https://github.com/Toranktto Toranktto]<br />
| {{Python}}<br />
| {{MIT}}<br />
| {{yes|1.8.x, 1.10.x, 1.12.2}}<br />
|-<br />
! [https://github.com/JoshuaDoes/go-yggdrasil go-yggdrasil]<br />
| Allows usage of Mojang's Yggdrasil authentication system in Go<br />
| [https://joshuadoes.com JoshuaDoes]<br />
| [https://golang.org/ Go]<br />
| {{MIT}}<br />
| n/a<br />
|-<br />
! [https://github.com/McEx/McProtocol McProtocol]<br />
| Packets, NBT, Login, Proxy<br />
| hansihe<br />
| [http://elixir-lang.org/ Elixir]<br />
| {{MIT}}<br />
| {{yes|1.9.2}}<br />
|-<br />
! [https://github.com/samcarsonx/yggdrasil-py yggdrasil-py]<br />
| Open-source Python 3.6+ wrapper for the Mojang Yggdrasil authentication service.<br />
| [https://github.com/samcarsonx Sam Carson (samcarsonx)]<br />
| {{Python}}<br />
| {{MIT}}<br />
| n/a<br />
|-<br />
! [https://github.com/hawezo/MojangSharp MojangSharp]<br />
| .NET wrapper for Mojang API<br />
| [https://github.com/hawezo Enzo Innocenzi (Hawezo)]<br />
| {{C sharp}}<br />
| {{Apache}}<br />
| {{yes|All}}<br />
|-<br />
! [https://github.com/SirCmpwn/Craft.Net Craft.Net]<br />
| .NET Minecraft client, server, and data manipulation library<br />
| [https://github.com/SirCmpwn Drew DeVault (SirCmpwn)]<br />
| {{C sharp}}<br />
| {{MIT}}<br />
| {{yes|1.7.5}}<br />
|-<br />
! [https://github.com/dividuum/fastmc fastmc]<br />
| Python packet parser/writer & utility library<br />
| [http://dividuum.de Florian Wesch (dividuum)]<br />
| {{Python}}<br />
| {{MIT}}<br />
| {{yes|1.7/1.8}}<br />
|-<br />
! [https://github.com/PrismarineJS/node-minecraft-protocol node-minecraft-protocol]<br />
| npm install minecraft-protocol<br />
| [https://github.com/andrewrk andrewrk]<br />
| [http://nodejs.org/ node.js]<br />
| {{BSD}}<br />
| {{yes|1.7-1.12}}<br />
|-<br />
! [https://github.com/plushmonkey/mclib mclib]<br />
| C++ library for creating clients<br />
| [https://github.com/plushmonkey plushmonkey]<br />
| {{C++}}<br />
| {{MIT}}<br />
| {{yes|1.10-1.12.1}}<br />
|-<br />
! [https://github.com/timmyrs/Phpcraft Phpcraft]<br />
| A PHP library for all things Minecraft.<br />
| [https://github.com/timmyrs timmyRS]<br />
| {{PHP}}<br />
| {{MIT}}<br />
| {{yes|1.14.4}}<br />
|-<br />
! [https://github.com/ammaraskar/pyCraft pyCraft]<br />
| Python minecraft client library<br />
| [http://ammaraskar.com/ Ammar Askar (ammaraskar)], [https://github.com/dkkline Jeppe Klitgaard (Dkkline)]<br />
| {{Python}}<br />
| {{Apache}}<br />
| {{yes|1.8-1.14.3}}<br />
|-<br />
! [http://github.com/Steveice10/MCProtocolLib MCProtocolLib]<br />
| Java implementation of the Minecraft protocol.<br />
| Steveice10<br />
| {{Java}}<br />
| {{MIT}}<br />
| {{yes|1.14.3}}<br />
|-<br />
! [https://github.com/C4K3/Ozelot Ozelot]<br />
| Rust implementation of MCMODERN networking<br />
| C4K3<br />
| {{Rust}}<br />
| Public domain<br />
| {{yes|1.13.2}}<br />
|-<br />
! [https://github.com/ags131/SharpMinecraftLibrary SharpMinecraftLibrary]<br />
|<br />
| ags131, electronicboy<br />
| {{C sharp}}<br />
| {{unknown}}<br />
| {{no|1.6.2 (Partial)}}<br />
|-<br />
! [https://github.com/pdelvo/Pdelvo.Minecraft Pdelvos Protocol Implementation]<br />
| .NET client/server protocol library with support for several versions.<br />
| pdelvo<br />
| {{C sharp}}<br />
| {{MIT}}<br />
| {{no|1.5.2}}<br />
|-<br />
! [https://github.com/shoghicp/Minecraft-PHP-Client-2 Minecraft PHP Client 2]<br />
| PHP client and protocol library. With events, actions and API<br />
| [https://twitter.com/shoghicp shoghicp]<br />
| {{PHP}}<br />
| {{WTFPL}}<br />
| {{no|1.5.1}}<br />
|-<br />
! [https://github.com/deoxxa/libmcnet libmcnet]<br />
| Event based, zero-copy, portable Minecraft network protocol parser<br />
| deoxxa<br />
| {{C}}<br />
| {{BSD}}<br />
| {{no|1.4}}<br />
|-<br />
! [https://github.com/deoxxa/node-mcnet node-mcnet]<br />
| Node.JS bindings to [https://github.com/deoxxa/libmcnet libmcnet]<br />
| deoxxa<br />
| {{JavaScript}}, [http://nodejs.org/ node.js]<br />
| {{BSD}}<br />
| {{no|1.3.2}}<br />
|-<br />
! [https://github.com/Maincraft/MCPackets MCPackets]<br />
| Java Minecraft protocol library<br />
| main()<br />
| {{Java}}<br />
| {{unknown}}<br />
| {{no|1.2.5}}<br />
|-<br />
! [https://github.com/axus/libmc--c libmc--c]<br />
| World representation data structures and OpenGL drawing functions.<br />
| axus<br />
| {{C++}}, {{OpenGL}}<br />
| {{GPLv3}}<br />
| {{no|1.1}}<br />
|-<br />
! [https://github.com/mave/mcproxy mcproxy]<br />
| Minecraft Proxy (and bot) framework in C++<br />
| mave<br />
| {{C++}}<br />
| {{GPLv3}}<br />
| {{no|1.1}}<br />
|-<br />
! [https://github.com/fragmer/fNbt fNbt]<br />
| Reading, writing, and manipulating NBT files and streams, for .NET<br />
| [http://matvei.org/ Matvei Stefarov (fragmer)]<br />
| {{C sharp}}<br />
| {{BSD}}<br />
| n/a<br />
|-<br />
! [https://gist.github.com/Jckf/7872337 Yggdrasil.php]<br />
| Interfacing with Mojang's Yggdrasil authentication system.<br />
| [http://www.jckf.no/ Jim C K Flaten (Jckf)]<br />
| {{PHP}}<br />
| {{unknown}}<br />
| n/a<br />
|-<br />
! [https://github.com/umby24/libMC.NET libMC.Net]<br />
| .NET Minecraft interaction library<br />
| [http://umby.d3s.co/ umby24]<br />
| {{C sharp}}<br />
| {{MIT}}<br />
| {{yes|1.7.4}}<br />
|-<br />
! [https://github.com/MineLib/MineLib.Network MineLib.Network]<br />
| .NET Minecraft network client interaction library.<br />
| [https://github.com/Aragas Aragas (Aragasas)]<br />
| {{C sharp}}<br />
| {{MIT}}<br />
| {{yes|1.8}}<br />
|-<br />
! [https://github.com/Evil-Co/NBT-Lib NBT-Lib]<br />
| Allows reading, writing and modification of NBT files and streams.<br />
| [http://www.evil-co.org Evil-Co]<br />
| {{Java}}<br />
| {{Apache}}<br />
| n/a<br />
|-<br />
! [https://github.com/DarkStorm652/DarkBot DarkBot]<br />
| Minecraft client, automation (AI) platform, and modular protocol library<br />
| [https://github.com/DarkStorm652 DarkStorm]<br />
| {{Java}}<br />
| {{BSD}}<br />
| {{yes|1.5.2-1.7.9}}<br />
|-<br />
! [https://bitbucket.org/socolin/nbtfield/ NBTField]<br />
| Another NBT library in C++<br />
| [https://bitbucket.org/socolin/ Socolin]<br />
| {{C++}}<br />
| {{MIT}}<br />
| n/a<br />
|-<br />
! [https://github.com/Kronos666/mclaunch-util-lib mclaunch-util-lib]<br />
| Yggdrasil library in Java, has handy features for launchers.<br />
| [https://github.com/Kronos666 Kronos]<br />
| {{Java}}<br />
| {{MIT}}<br />
| n/a<br />
|-<br />
! [https://github.com/Litarvan/OpenLauncherLib/ OpenLauncherLib]<br />
| Minecraft launching library written from scratch<br />
| [https://github.com/Litarvan/ Adrien "Litarvan" Navratil]<br />
| {{Java}}<br />
| {{LGPL}}<br />
| {{yes|1.0.0-1.9.2}}<br />
|-<br />
! [https://github.com/Litarvan/S-Update/ S-Update]<br />
| Powerful and simple Java update system, with Minecraft support. Works with a PHP Server<br />
| [https://github.com/Litarvan/ Adrien "Litarvan" Navratil]<br />
| {{Java}}<br />
| {{LGPL}}<br />
| {{yes|1.0.0-1.9.2}}<br />
|-<br />
! [https://github.com/Litarvan/OpenAuth/ OpenAuth]<br />
| Yggdrasil library, with possibility to give an other authentication server, it also has its own auth server.<br />
| [https://github.com/Litarvan/ Adrien "Litarvan" Navratil, Valentin "Vavaballz"]<br />
| {{Java}}<br />
| {{LGPL}}<br />
| {{yes|1.0.0-1.9.2}}<br />
|-<br />
! [https://github.com/jamiemansfield/text text]<br />
| An open-source MIT-licensed library for working with text from Minecraft.<br />
| [https://www.jamierocks.uk/ Jamie Mansfield]<br />
| {{Java}}<br />
| {{MIT}}<br />
| {{yes|1.11.2}}<br />
|-<br />
! [https://github.com/to2mbn/JMCCC JMCCC]<br />
| A powerful open-source library for launching and downloading Minecraft.<br />
| [https://github.com/to2mbn/ to2mbn]<br />
| {{Java}}<br />
| {{MIT}}<br />
| {{yes|All}}<br />
|-<br />
! [https://github.com/barneygale/quarry Quarry]<br />
| Quarry is a Python library that implements the Minecraft protocol.<br />
| [http://github.com/barneygale barneygale]<br />
| {{Python}}<br />
| {{MIT}}<br />
| {{yes|1.14.2}}<br />
|-<br />
|-<br />
! [https://pypi.org/project/minecraft-launcher-lib minecraft-launcher-lib]<br />
| A library for installing and lauching Minecraft. It also have functions for Yggdrasil. <br />
| [https://gitlab.com/JakobDev JakobDev]<br />
| {{Python}}<br />
| {{BSD}}<br />
| {{yes|All}}<br />
|-<br />
|}<br />
<br />
[[Category:Minecraft Modern]]</div>JakobDev