Skip to content

Commit

Permalink
fix: 411 Length Required when POST live.com.
Browse files Browse the repository at this point in the history
  • Loading branch information
huanghongxun committed Sep 9, 2021
1 parent 336d7ba commit 108df22
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 26 deletions.
2 changes: 2 additions & 0 deletions HMCL/src/main/java/org/jackhuang/hmcl/setting/Accounts.java
Expand Up @@ -360,6 +360,8 @@ else if (remoteMessage.contains("Invalid username or password"))
long errorCode = ((MicrosoftService.XboxAuthorizationException) exception).getErrorCode();
if (errorCode == MicrosoftService.XboxAuthorizationException.ADD_FAMILY) {
return i18n("account.methods.microsoft.error.add_family");
} else if (errorCode == MicrosoftService.XboxAuthorizationException.COUNTRY_UNAVAILABLE) {
return i18n("account.methods.microsoft.error.country_unavailable");
} else if (errorCode == MicrosoftService.XboxAuthorizationException.MISSING_XBOX_ACCOUNT) {
return i18n("account.methods.microsoft.error.missing_xbox_account");
} else {
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Expand Up @@ -76,6 +76,7 @@ account.methods.authlib_injector=authlib-injector
account.methods.microsoft=Microsoft Account
account.methods.microsoft.close_page=Microsoft account authorization has been finished. There are some remaining logging-in steps to be finished later. You can close this page right now.
account.methods.microsoft.error.add_family=Since you are not yet 18 years old, an adult must add you to a family in order for you to play Minecraft.
account.methods.microsoft.error.country_unavailable=XBox Live is not available in your country/region.
account.methods.microsoft.error.missing_xbox_account=Your Microsoft account is not connected to an Xbox account. Please create one before continuing.
account.methods.microsoft.error.no_character=Account is missing a Minecraft Java profile. While the Microsoft account is valid, it does not own the game.
account.methods.microsoft.error.unknown=Failed to log in. Microsoft respond with error code %d.
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Expand Up @@ -69,6 +69,7 @@ account.methods.authlib_injector=authlib-injector 登入
account.methods.microsoft=微軟帳戶
account.methods.microsoft.close_page=已完成微軟帳號授權,接下來啟動器還需要完成剩餘登錄步驟。你已經可以關閉本頁面了。
account.methods.microsoft.error.add_family=由於你未滿 18 歲,你的帳號必須被加入到家庭中才能登錄遊戲。
account.methods.microsoft.error.country_unavailable=你所在的國家或地區不受 XBox Live 的支持。
account.methods.microsoft.error.missing_xbox_account=你的微軟帳號尚未關聯 XBox 帳號,你必須先創建 XBox 帳號,才能登錄遊戲。
account.methods.microsoft.error.no_character=該帳號沒有包含 Minecraft Java 版購買記錄
account.methods.microsoft.error.unknown=登錄失敗,錯誤碼:%d
Expand Down
3 changes: 2 additions & 1 deletion HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Expand Up @@ -74,7 +74,8 @@ account.methods=登录方式
account.methods.authlib_injector=外置登录 (authlib-injector)
account.methods.microsoft=微软账户
account.methods.microsoft.close_page=已完成微软账号授权,接下来启动器还需要完成剩余登录步骤。你已经可以关闭本页面了。
account.methods.microsoft.error.add_family=由于你未满 18 岁,你的账号必须被加入到家庭中才能登录游戏。
account.methods.microsoft.error.add_family=由於你的帳號登記年齡未滿 18 歲,你的帳號必須被加入到家庭中才能登錄遊戲。你可以更改你的帳號的出生日期設置,使年齡滿 18 歲以上以繼續登錄。
account.methods.microsoft.error.country_unavailable=你所在的国家或地区不受 XBox Live 的支持。
account.methods.microsoft.error.missing_xbox_account=你的微软账号尚未关联 XBox 账号,你必须先创建 XBox 账号,才能登录游戏。
account.methods.microsoft.error.no_character=该账号没有包含 Minecraft Java 版购买记录
account.methods.microsoft.error.unknown=登录失败,错误码:%d
Expand Down
Expand Up @@ -129,6 +129,25 @@ public MicrosoftSession refresh(MicrosoftSession oldSession) throws Authenticati
}
}

private String getUhs(XBoxLiveAuthenticationResponse response, String existingUhs) throws AuthenticationException {
if (response.errorCode != 0) {
throw new XboxAuthorizationException(response.errorCode, response.redirectUrl);
}

if (response.displayClaims == null || response.displayClaims.xui == null || response.displayClaims.xui.size() == 0 || !response.displayClaims.xui.get(0).containsKey("uhs")) {
LOG.log(Level.WARNING, "Unrecognized xbox authorization response " + GSON.toJson(response));
throw new ServerResponseMalformedException();
}

String uhs = (String) response.displayClaims.xui.get(0).get("uhs");
if (existingUhs != null) {
if (!Objects.equals(uhs, existingUhs)) {
throw new ServerResponseMalformedException("uhs mismatched");
}
}
return uhs;
}

private MicrosoftSession authenticateViaLiveAccessToken(String liveAccessToken, String liveRefreshToken) throws IOException, JsonParseException, AuthenticationException {
// Authenticate with XBox Live
XBoxLiveAuthenticationResponse xboxResponse = HttpRequest
Expand All @@ -140,11 +159,7 @@ private MicrosoftSession authenticateViaLiveAccessToken(String liveAccessToken,
pair("RelyingParty", "http://auth.xboxlive.com"), pair("TokenType", "JWT")))
.accept("application/json").getJson(XBoxLiveAuthenticationResponse.class);

if (xboxResponse.errorCode != 0) {
throw new XboxAuthorizationException(xboxResponse.errorCode);
}

String uhs = (String) xboxResponse.displayClaims.xui.get(0).get("uhs");
String uhs = getUhs(xboxResponse, null);

// Authenticate Minecraft with XSTS
XBoxLiveAuthenticationResponse minecraftXstsResponse = HttpRequest
Expand All @@ -156,14 +171,7 @@ private MicrosoftSession authenticateViaLiveAccessToken(String liveAccessToken,
pair("RelyingParty", "rp://api.minecraftservices.com/"), pair("TokenType", "JWT")))
.getJson(XBoxLiveAuthenticationResponse.class);

if (xboxResponse.errorCode != 0) {
throw new XboxAuthorizationException(xboxResponse.errorCode);
}

String minecraftXstsUhs = (String) minecraftXstsResponse.displayClaims.xui.get(0).get("uhs");
if (!Objects.equals(uhs, minecraftXstsUhs)) {
throw new ServerResponseMalformedException("uhs mismatched");
}
getUhs(minecraftXstsResponse, uhs);

// Authenticate XBox with XSTS
XBoxLiveAuthenticationResponse xboxXstsResponse = HttpRequest
Expand All @@ -175,14 +183,7 @@ private MicrosoftSession authenticateViaLiveAccessToken(String liveAccessToken,
pair("RelyingParty", "http://xboxlive.com"), pair("TokenType", "JWT")))
.getJson(XBoxLiveAuthenticationResponse.class);

if (xboxXstsResponse.errorCode != 0) {
throw new XboxAuthorizationException(xboxXstsResponse.errorCode);
}

String xboxXstsUhs = (String) xboxXstsResponse.displayClaims.xui.get(0).get("uhs");
if (!Objects.equals(uhs, xboxXstsUhs)) {
throw new ServerResponseMalformedException("uhs mismatched");
}
getUhs(xboxXstsResponse, uhs);

getXBoxProfile(uhs, xboxXstsResponse.token);

Expand Down Expand Up @@ -307,16 +308,23 @@ private static <T> T fromJson(String text, Class<T> typeOfT) throws ServerRespon

public static class XboxAuthorizationException extends AuthenticationException {
private final long errorCode;
private final String redirect;

public XboxAuthorizationException(long errorCode) {
public XboxAuthorizationException(long errorCode, String redirect) {
this.errorCode = errorCode;
this.redirect = redirect;
}

public long getErrorCode() {
return errorCode;
}

public String getRedirect() {
return redirect;
}

public static final long MISSING_XBOX_ACCOUNT = 2148916233L;
public static final long COUNTRY_UNAVAILABLE = 2148916235L;
public static final long ADD_FAMILY = 2148916238L;
}

Expand Down
Expand Up @@ -149,6 +149,10 @@ public String getString() throws IOException {
HttpURLConnection con = createConnection();
con.setDoOutput(true);

try (OutputStream os = con.getOutputStream()) {
os.write(bytes);
}

if (responseCodeTester != null) {
responseCodeTester.accept(new URL(url), con.getResponseCode());
} else {
Expand All @@ -157,9 +161,6 @@ public String getString() throws IOException {
}
}

try (OutputStream os = con.getOutputStream()) {
os.write(bytes);
}
return NetworkUtils.readData(con);
}
}
Expand Down
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -56,3 +56,5 @@ Make sure you have Java installed with JavaFX 8 at least. Liberica full JDK 8 or
|`-Dhmcl.update_source.override=<url>`|Override the update source.|
|`-Dhmcl.authlibinjector.location=<path>`|Use specified authlib-injector (instead of downloading one).|
|`-Dhmcl.openjfx.repo=<maven repository url>`|Add custom maven repository for download OpenJFX.|
|`-Dhmcl.microsoft.auth.id=<App ID>`|Override Microsoft OAuth App ID.|
|`-Dhmcl.microsoft.auth.secret=<App Secret>`|Override Microsoft OAuth App secret.|

0 comments on commit 108df22

Please sign in to comment.