1
0
mirror of https://github.com/SKCraft/Launcher.git synced 2025-02-19 02:11:37 +01:00

Report Xbox authentication errors

This commit is contained in:
Henry Le Grys 2021-02-11 17:40:59 +00:00
parent b18c29a5ec
commit 1d4e46214b
6 changed files with 80 additions and 12 deletions

View File

@ -64,17 +64,16 @@ public class MicrosoftLoginService implements LoginService {
form.add("client_id", clientId); form.add("client_id", clientId);
formConsumer.accept(form); formConsumer.accept(form);
HttpRequest request = HttpRequest.post(MS_TOKEN_URL) return HttpRequest.post(MS_TOKEN_URL)
.bodyForm(form) .bodyForm(form)
.execute(); .execute()
.expectResponseCodeOr(200, (req) -> {
TokenError error = req.returnContent().asJson(TokenError.class);
if (request.getResponseCode() == 200) { return new AuthenticationException(error.errorDescription);
return request.returnContent().asJson(TokenResponse.class); })
} else { .returnContent()
TokenError error = request.returnContent().asJson(TokenError.class); .asJson(TokenResponse.class);
throw new AuthenticationException(error.errorDescription);
}
} }
private Profile performLogin(String microsoftToken, SavedSession previous) private Profile performLogin(String microsoftToken, SavedSession previous)

View File

@ -1,7 +1,9 @@
package com.skcraft.launcher.auth.microsoft; package com.skcraft.launcher.auth.microsoft;
import com.skcraft.launcher.auth.AuthenticationException;
import com.skcraft.launcher.auth.microsoft.model.*; import com.skcraft.launcher.auth.microsoft.model.*;
import com.skcraft.launcher.util.HttpRequest; import com.skcraft.launcher.util.HttpRequest;
import com.skcraft.launcher.util.SharedLocale;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
@ -12,7 +14,8 @@ public class XboxTokenAuthorizer {
private static final URL XBL_AUTHENTICATE_URL = url("https://user.auth.xboxlive.com/user/authenticate"); private static final URL XBL_AUTHENTICATE_URL = url("https://user.auth.xboxlive.com/user/authenticate");
private static final URL XSTS_AUTHENTICATE_URL = url("https://xsts.auth.xboxlive.com/xsts/authorize"); private static final URL XSTS_AUTHENTICATE_URL = url("https://xsts.auth.xboxlive.com/xsts/authorize");
public static XboxAuthorization authorizeWithXbox(String accessToken) throws IOException, InterruptedException { public static XboxAuthorization authorizeWithXbox(String accessToken)
throws IOException, InterruptedException, AuthenticationException {
XboxAuthRequest<XblAuthProperties> xblPayload = XboxAuthRequest<XblAuthProperties> xblPayload =
new XboxAuthRequest<>(new XblAuthProperties("d=" + accessToken)); new XboxAuthRequest<>(new XblAuthProperties("d=" + accessToken));
@ -20,7 +23,9 @@ public class XboxTokenAuthorizer {
.bodyJson(xblPayload) .bodyJson(xblPayload)
.header("Accept", "application/json") .header("Accept", "application/json")
.execute() .execute()
.expectResponseCode(200) .expectResponseCodeOr(200, (req) ->
new AuthenticationException("Error authenticating with Xbox Live",
SharedLocale.tr("login.xbox.generic")))
.returnContent() .returnContent()
.asJson(XboxAuthResponse.class); .asJson(XboxAuthResponse.class);
@ -32,10 +37,25 @@ public class XboxTokenAuthorizer {
.bodyJson(xstsPayload) .bodyJson(xstsPayload)
.header("Accept", "application/json") .header("Accept", "application/json")
.execute() .execute()
.expectResponseCode(200) .expectResponseCodeOr(200, (req) -> {
XstsError xstsError = req.returnContent().asJson(XstsError.class);
return new AuthenticationException(xstsError.getMessage(), getErrorMessage(xstsError.getXErr()));
})
.returnContent() .returnContent()
.asJson(XboxAuthResponse.class); .asJson(XboxAuthResponse.class);
return new XboxAuthorization(xstsResponse.getToken(), xstsResponse.getUhs()); return new XboxAuthorization(xstsResponse.getToken(), xstsResponse.getUhs());
} }
private static String getErrorMessage(long xboxErrorCode) {
if (xboxErrorCode == 2148916233L) {
return SharedLocale.tr("login.xbox.noXboxAccount");
}
if (xboxErrorCode == 2148916238L) {
return SharedLocale.tr("login.xbox.isChild");
}
return SharedLocale.tr("login.xbox.unknown", xboxErrorCode);
}
} }

View File

@ -0,0 +1,15 @@
package com.skcraft.launcher.auth.microsoft.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;
@Data
@JsonNaming(PropertyNamingStrategy.PascalCaseStrategy.class)
@JsonIgnoreProperties(ignoreUnknown = true)
public class XstsError {
private long xErr;
private String message;
private String redirect;
}

View File

@ -0,0 +1,8 @@
package com.skcraft.launcher.util;
import java.io.IOException;
@FunctionalInterface
public interface HttpFunction<T, V> {
V call(T arg) throws IOException, InterruptedException;
}

View File

@ -202,6 +202,27 @@ public class HttpRequest implements Closeable, ProgressObservable {
throw new IOException("Did not get expected response code, got " + responseCode + " for " + url); throw new IOException("Did not get expected response code, got " + responseCode + " for " + url);
} }
/**
* Continue if the response code matches, otherwise call the provided function
* to generate an exception.
*
* @param code HTTP status code to continue on.
* @param onError Function invoked when the code does not match, should return an error that will be thrown.
* @return this object if successful
* @throws Exception either an {@link IOException} on I/O error or a user-defined {@link Exception} subclass
* if the code does not match.
*/
public <E extends Exception> HttpRequest expectResponseCodeOr(int code, HttpFunction<HttpRequest, E> onError)
throws E, IOException, InterruptedException {
int responseCode = getResponseCode();
if (code == responseCode) return this;
E exc = onError.call(this);
close();
throw exc;
}
/** /**
* Get the response code. * Get the response code.
* *

View File

@ -110,6 +110,11 @@ login.noLoginError=Please enter your account details.
login.noLoginTitle=Missing Account login.noLoginTitle=Missing Account
login.minecraftNotOwnedError=Sorry, Minecraft is not owned on that account. login.minecraftNotOwnedError=Sorry, Minecraft is not owned on that account.
login.xbox.generic=Failed to authenticate with Xbox Live.
login.xbox.noXboxAccount=That account does not have an Xbox account associated!
login.xbox.isChild=The account is a child (under 18) and cannot proceed unless it is part of a Family.
login.xbox.unknown=An unknown error occurred while logging in with Xbox (XErr %d)
console.title=Messages and Errors console.title=Messages and Errors
console.launcherConsoleTitle=Launcher Messages console.launcherConsoleTitle=Launcher Messages
console.uploadLog=Upload Log console.uploadLog=Upload Log