Просмотр исходного кода

Merge pull request #3940 from Pigeon0v0/auth

微软登录设备代码流
龙腾猫跃 2 лет назад
Родитель
Сommit
49fe40662f
1 измененных файлов с 45 добавлено и 24 удалено
  1. 45 24
      Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb

+ 45 - 24
Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb

@@ -506,6 +506,7 @@ NextInner:
         End If
         End If
         '尝试登录
         '尝试登录
         Dim OAuthTokens As String()
         Dim OAuthTokens As String()
+        Dim ClientId As String = ""
         If Input.OAuthRefreshToken = "" Then
         If Input.OAuthRefreshToken = "" Then
             '无 RefreshToken
             '无 RefreshToken
 Relogin:
 Relogin:
@@ -513,10 +514,10 @@ Relogin:
             If OAuthCode = "Cancel" Then Exit Sub
             If OAuthCode = "Cancel" Then Exit Sub
             If Data.IsAborted Then Throw New ThreadInterruptedException
             If Data.IsAborted Then Throw New ThreadInterruptedException
             Data.Progress = 0.2
             Data.Progress = 0.2
-            OAuthTokens = MsLoginStep2(OAuthCode, False)
+            OAuthTokens = MsLoginStep2(OAuthCode, False, ClientId)
         Else
         Else
             '有 RefreshToken
             '有 RefreshToken
-            OAuthTokens = MsLoginStep2(Input.OAuthRefreshToken, True)
+            OAuthTokens = MsLoginStep2(Input.OAuthRefreshToken, True, ClientId)
         End If
         End If
         '要求重新打开登录网页认证
         '要求重新打开登录网页认证
         If OAuthTokens(0) = "Cancel" Then Exit Sub
         If OAuthTokens(0) = "Cancel" Then Exit Sub
@@ -837,39 +838,59 @@ LoginFinish:
             Return RegexSeek(Result, "(?<=code\=)[^&]+")
             Return RegexSeek(Result, "(?<=code\=)[^&]+")
         End If
         End If
     End Function
     End Function
+
     '微软登录步骤 2:从 OAuth Code 或 OAuth RefreshToken 获取 {OAuth AccessToken, OAuth RefreshToken}
     '微软登录步骤 2:从 OAuth Code 或 OAuth RefreshToken 获取 {OAuth AccessToken, OAuth RefreshToken}
-    Private Function MsLoginStep2(Code As String, IsRefresh As Boolean) As String()
+    Private Function MsLoginStep2(Code As String, IsRefresh As Boolean, ClientId As String, Optional ExpiresIn As String = "900") As String()
         McLaunchLog("开始微软登录步骤 2(" & If(IsRefresh, "", "非") & "刷新登录)")
         McLaunchLog("开始微软登录步骤 2(" & If(IsRefresh, "", "非") & "刷新登录)")
 
 
         Dim Request As String
         Dim Request As String
         If IsRefresh Then
         If IsRefresh Then
-            Request = "client_id=00000000402b5328" & "&" &
+            Request = "grant_type=refresh_token" & "&" &
+                      "client_id=" & ClientId & "&" &
+                      "device_code=" & Code & "&" &
                       "refresh_token=" & Uri.EscapeDataString(Code) & "&" &
                       "refresh_token=" & Uri.EscapeDataString(Code) & "&" &
-                      "grant_type=refresh_token" & "&" &
-                      "redirect_uri=" & Uri.EscapeDataString("https://login.live.com/oauth20_desktop.srf") & "&" &
-                      "scope=" & Uri.EscapeDataString("service::user.auth.xboxlive.com::MBI_SSL")
+                      "scope=XboxLive.signin%20offline_access"
         Else
         Else
-            Request = "client_id=00000000402b5328" & "&" &
-                      "code=" & Uri.EscapeDataString(Code) & "&" &
-                      "grant_type=authorization_code" & "&" &
-                      "redirect_uri=" & Uri.EscapeDataString("https://login.live.com/oauth20_desktop.srf") & "&" &
-                      "scope=" & Uri.EscapeDataString("service::user.auth.xboxlive.com::MBI_SSL")
+            Request = "grant_type=urn:ietf:params:oauth:grant-type:device_code" & "&" &
+                      "client_id=" & ClientId & "&" &
+                      "device_code=" & Code & "&" &
+                      "scope=XboxLive.signin%20offline_access"
         End If
         End If
         Dim Result As String
         Dim Result As String
-        Try
-            Result = NetRequestMulty("https://login.live.com/oauth20_token.srf", "POST", Request, "application/x-www-form-urlencoded", 2)
-        Catch ex As Exception
-            If ex.Message.Contains("must sign in again") OrElse ex.Message.Contains("invalid_grant") Then '#269
-                Return {"Relogin", ""}
-            Else
-                Throw
+        Dim stopwatch As Stopwatch = Stopwatch.StartNew()
+
+        While stopwatch.Elapsed < TimeSpan.FromSeconds(ExpiresIn)
+            Try
+                Result = NetRequestMulty("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", "POST", Request, "application/x-www-form-urlencoded", 2)
+            Catch ex As Exception
+                If ex.Message.Contains("must sign in again") OrElse ex.Message.Contains("invalid_grant") Then '#269
+                    Return {"Relogin", ""}
+                ElseIf ex.Message.Contains("authorization_declined") Then
+                    Hint("你拒绝了 PCL2 的访问权限申请,验证过程被中断!")
+                    Return {"Cancel", ""}
+                ElseIf ex.Message.Contains("expired_token") Then
+                    Hint("Token 已过期,请尝试重新验证!")
+                    Exit While
+                ElseIf ex.Message.Contains("AADSTS70016") Then
+                    Continue While
+                Else
+                    Throw
+                End If
+            End Try
+
+            If Result IsNot Nothing Then
+                Dim ResultJson As JObject = GetJson(Result)
+                Dim AccessToken As String = ResultJson("access_token").ToString
+                Dim RefreshToken As String = ResultJson("refresh_token").ToString
+                Return {AccessToken, RefreshToken}
             End If
             End If
-        End Try
 
 
-        Dim ResultJson As JObject = GetJson(Result)
-        Dim AccessToken As String = ResultJson("access_token").ToString
-        Dim RefreshToken As String = ResultJson("refresh_token").ToString
-        Return {AccessToken, RefreshToken}
+            Thread.Sleep(1000)
+        End While
+
+        Hint("验证超时,请尝试重新验证!")
+        Return {"Cancel", ""}
+
     End Function
     End Function
 
 
     ''微软登录步骤 1:获取 DeviceCode 并显示验证提示
     ''微软登录步骤 1:获取 DeviceCode 并显示验证提示