feat: 使用授权代码流登录微软帐户 (#5330)

This commit is contained in:
CiiLu
2026-02-10 00:41:12 +08:00
committed by Glavo
parent 33dc39e59e
commit b7fbebae43
15 changed files with 533 additions and 243 deletions

View File

@@ -77,7 +77,7 @@ public class OAuth {
private Result authenticateAuthorizationCode(Options options) throws IOException, InterruptedException, JsonParseException, ExecutionException, AuthenticationException {
Session session = options.callback.startServer();
options.callback.openBrowser(NetworkUtils.withQuery(authorizationURL,
options.callback.openBrowser(GrantFlow.AUTHORIZATION_CODE, NetworkUtils.withQuery(authorizationURL,
mapOf(pair("client_id", options.callback.getClientId()), pair("response_type", "code"),
pair("redirect_uri", session.getRedirectURI()), pair("scope", options.scope),
pair("prompt", "select_account"))));
@@ -106,7 +106,7 @@ public class OAuth {
options.callback.grantDeviceCode(deviceTokenResponse.userCode, deviceTokenResponse.verificationURI);
// Microsoft OAuth Flow
options.callback.openBrowser(deviceTokenResponse.verificationURI);
options.callback.openBrowser(GrantFlow.DEVICE, deviceTokenResponse.verificationURI);
long startTime = System.nanoTime();
long interval = TimeUnit.MILLISECONDS.convert(deviceTokenResponse.interval, TimeUnit.SECONDS);
@@ -237,9 +237,10 @@ public class OAuth {
/**
* Open browser
*
* @param url OAuth url.
* @param grantFlow the grant flow.
* @param url OAuth url.
*/
void openBrowser(String url) throws IOException;
void openBrowser(GrantFlow grantFlow, String url) throws IOException;
String getClientId();

View File

@@ -47,10 +47,10 @@ public final class MicrosoftAccount extends OAuthAccount {
this.characterUUID = requireNonNull(session.getProfile().getId());
}
protected MicrosoftAccount(MicrosoftService service, CharacterSelector characterSelector) throws AuthenticationException {
protected MicrosoftAccount(MicrosoftService service, OAuth.GrantFlow flow) throws AuthenticationException {
this.service = requireNonNull(service);
MicrosoftSession acquiredSession = service.authenticate();
MicrosoftSession acquiredSession = service.authenticate(flow);
if (acquiredSession.getProfile() == null) {
session = service.refresh(acquiredSession);
} else {
@@ -105,7 +105,7 @@ public final class MicrosoftAccount extends OAuthAccount {
@Override
public AuthInfo logInWhenCredentialsExpired() throws AuthenticationException {
MicrosoftSession acquiredSession = service.authenticate();
MicrosoftSession acquiredSession = service.authenticate(OAuth.GrantFlow.DEVICE);
if (!Objects.equals(characterUUID, acquiredSession.getProfile().getId())) {
throw new WrongAccountException(characterUUID, acquiredSession.getProfile().getId());
}

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.auth.microsoft;
import org.jackhuang.hmcl.auth.AccountFactory;
import org.jackhuang.hmcl.auth.AuthenticationException;
import org.jackhuang.hmcl.auth.CharacterSelector;
import org.jackhuang.hmcl.auth.OAuth;
import java.util.Map;
import java.util.Objects;
@@ -39,9 +40,7 @@ public class MicrosoftAccountFactory extends AccountFactory<MicrosoftAccount> {
@Override
public MicrosoftAccount create(CharacterSelector selector, String username, String password, ProgressCallback progressCallback, Object additionalData) throws AuthenticationException {
Objects.requireNonNull(selector);
return new MicrosoftAccount(service, selector);
return new MicrosoftAccount(service, (OAuth.GrantFlow) additionalData);
}
@Override

View File

@@ -69,9 +69,9 @@ public class MicrosoftService {
return profileRepository;
}
public MicrosoftSession authenticate() throws AuthenticationException {
public MicrosoftSession authenticate(OAuth.GrantFlow flow) throws AuthenticationException {
try {
OAuth.Result result = OAuth.MICROSOFT.authenticate(OAuth.GrantFlow.DEVICE, new OAuth.Options(SCOPE, callback));
OAuth.Result result = OAuth.MICROSOFT.authenticate(flow, new OAuth.Options(SCOPE, callback));
return authenticateViaLiveAccessToken(result.getAccessToken(), result.getRefreshToken());
} catch (IOException e) {
throw new ServerDisconnectException(e);