From c76b0121e4ff9879904dd6fd243f72291abb15db Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Wed, 1 Nov 2023 19:05:33 +0100 Subject: [PATCH 1/2] fix: microsoft credentials auth flow --- .../auth/service/MsaAuthenticationService.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java b/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java index 1251a92..ac125ac 100644 --- a/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java +++ b/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java @@ -21,9 +21,10 @@ import java.util.regex.Pattern; public class MsaAuthenticationService extends AuthenticationService { + private static final String LIVE_OAUTH20_CLIENT_ID = "00000000402b5328"; private static final URI MS_CODE_ENDPOINT = URI.create("https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"); private static final URI MS_CODE_TOKEN_ENDPOINT = URI.create("https://login.microsoftonline.com/consumers/oauth2/v2.0/token"); - private static final URI MS_LOGIN_ENDPOINT = URI.create("https://login.live.com/oauth20_authorize.srf?redirect_uri=https://login.live.com/oauth20_desktop.srf&scope=service::user.auth.xboxlive.com::MBI_SSL&display=touch&response_type=code&locale=en&client_id=00000000402b5328"); + private static final URI MS_LOGIN_ENDPOINT = URI.create("https://login.live.com/oauth20_authorize.srf?redirect_uri=https://login.live.com/oauth20_desktop.srf&scope=service::user.auth.xboxlive.com::MBI_SSL&display=touch&response_type=code&locale=en&client_id=" + LIVE_OAUTH20_CLIENT_ID); private static final URI MS_TOKEN_ENDPOINT = URI.create("https://login.live.com/oauth20_token.srf"); private static final URI XBL_AUTH_ENDPOINT = URI.create("https://user.auth.xboxlive.com/user/authenticate"); private static final URI XSTS_AUTH_ENDPOINT = URI.create("https://xsts.auth.xboxlive.com/xsts/authorize"); @@ -114,10 +115,10 @@ private McLoginResponse getLoginResponseFromCode() throws RequestException { return getLoginResponseFromToken("d=" + response.access_token); } - private McLoginResponse getLoginResponseFromCreds(String username, String password) throws RequestException { + private McLoginResponse getLoginResponseFromCreds() throws RequestException { // TODO: Migrate alot of this to {@link HTTP} - String cookie = ""; + String cookies = ""; String PPFT = ""; String urlPost = ""; @@ -125,7 +126,7 @@ private McLoginResponse getLoginResponseFromCreds(String username, String passwo HttpURLConnection connection = HTTP.createUrlConnection(this.getProxy(), MS_LOGIN_ENDPOINT); connection.setDoInput(true); try (InputStream in = connection.getResponseCode() == 200 ? connection.getInputStream() : connection.getErrorStream()) { - cookie = connection.getHeaderField("set-cookie"); + cookies = String.join("; ", connection.getHeaderFields().get("Set-Cookie")); String body = inputStreamToString(in); Matcher m = PPFT_PATTERN.matcher(body); if (m.find()) { @@ -145,7 +146,7 @@ private McLoginResponse getLoginResponseFromCreds(String username, String passwo throw new ServiceUnavailableException("Could not make request to '" + MS_LOGIN_ENDPOINT + "'.", e); } - if (cookie.isEmpty() || PPFT.isEmpty() || urlPost.isEmpty()) { + if (cookies.isEmpty() || PPFT.isEmpty() || urlPost.isEmpty()) { throw new RequestException("Invalid response from '" + MS_LOGIN_ENDPOINT + "' missing one or more of cookie, PPFT or urlPost"); } @@ -165,7 +166,7 @@ private McLoginResponse getLoginResponseFromCreds(String username, String passwo HttpURLConnection connection = HTTP.createUrlConnection(this.getProxy(), URI.create(urlPost)); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); connection.setRequestProperty("Content-Length", String.valueOf(bytes.length)); - connection.setRequestProperty("Cookie", cookie); + connection.setRequestProperty("Cookie", cookies); connection.setDoInput(true); connection.setDoOutput(true); @@ -190,7 +191,7 @@ private McLoginResponse getLoginResponseFromCreds(String username, String passwo throw new ServiceUnavailableException("Could not make request to '" + urlPost + "'.", e); } - MsTokenRequest request = new MsTokenRequest(clientId, code); + MsTokenRequest request = new MsTokenRequest(LIVE_OAUTH20_CLIENT_ID, code); MsTokenResponse response = HTTP.makeRequestForm(this.getProxy(), MS_TOKEN_ENDPOINT, request.toMap(), MsTokenResponse.class); this.refreshToken = response.refresh_token; return getLoginResponseFromToken(response.access_token); @@ -297,7 +298,7 @@ public void login() throws RequestException { McLoginResponse response = null; if(password) { - response = getLoginResponseFromCreds(this.username, this.password); + response = getLoginResponseFromCreds(); } else if (refresh) { response = getLoginResponseFromRefreshToken(); } else if(!device) { From 631fd91cefb43599e4f76ff23eef29ab658ded84 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Wed, 1 Nov 2023 19:12:59 +0100 Subject: [PATCH 2/2] fix/chore: catch unhandled exception If the request to the login route fails (due to whatever reason), the header is missing and calling String.join would invoke List#get on a null-list. Just fallback to an empty list. --- .../steveice10/mc/auth/service/MsaAuthenticationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java b/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java index ac125ac..4eabeb2 100644 --- a/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java +++ b/src/main/java/com/github/steveice10/mc/auth/service/MsaAuthenticationService.java @@ -126,7 +126,7 @@ private McLoginResponse getLoginResponseFromCreds() throws RequestException { HttpURLConnection connection = HTTP.createUrlConnection(this.getProxy(), MS_LOGIN_ENDPOINT); connection.setDoInput(true); try (InputStream in = connection.getResponseCode() == 200 ? connection.getInputStream() : connection.getErrorStream()) { - cookies = String.join("; ", connection.getHeaderFields().get("Set-Cookie")); + cookies = String.join("; ", connection.getHeaderFields().getOrDefault("Set-Cookie", Collections.emptyList())); String body = inputStreamToString(in); Matcher m = PPFT_PATTERN.matcher(body); if (m.find()) {