Merge pull request #3940 from Pigeon0v0/auth

微软登录设备代码流
This commit is contained in:
龙腾猫跃
2024-09-22 01:53:04 +08:00
committed by GitHub
@@ -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" & "&" & "scope=XboxLive.signin%20offline_access"
"redirect_uri=" & Uri.EscapeDataString("https://login.live.com/oauth20_desktop.srf") & "&" &
"scope=" & Uri.EscapeDataString("service::user.auth.xboxlive.com::MBI_SSL")
Else Else
Request = "client_id=00000000402b5328" & "&" & Request = "grant_type=urn:ietf:params:oauth:grant-type:device_code" & "&" &
"code=" & Uri.EscapeDataString(Code) & "&" & "client_id=" & ClientId & "&" &
"grant_type=authorization_code" & "&" & "device_code=" & Code & "&" &
"redirect_uri=" & Uri.EscapeDataString("https://login.live.com/oauth20_desktop.srf") & "&" & "scope=XboxLive.signin%20offline_access"
"scope=" & Uri.EscapeDataString("service::user.auth.xboxlive.com::MBI_SSL")
End If End If
Dim Result As String Dim Result As String
Dim stopwatch As Stopwatch = Stopwatch.StartNew()
While stopwatch.Elapsed < TimeSpan.FromSeconds(ExpiresIn)
Try Try
Result = NetRequestMulty("https://login.live.com/oauth20_token.srf", "POST", Request, "application/x-www-form-urlencoded", 2) Result = NetRequestMulty("https://login.microsoftonline.com/consumers/oauth2/v2.0/token", "POST", Request, "application/x-www-form-urlencoded", 2)
Catch ex As Exception Catch ex As Exception
If ex.Message.Contains("must sign in again") OrElse ex.Message.Contains("invalid_grant") Then '#269 If ex.Message.Contains("must sign in again") OrElse ex.Message.Contains("invalid_grant") Then '#269
Return {"Relogin", ""} 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 Else
Throw Throw
End If End If
End Try End Try
If Result IsNot Nothing Then
Dim ResultJson As JObject = GetJson(Result) Dim ResultJson As JObject = GetJson(Result)
Dim AccessToken As String = ResultJson("access_token").ToString Dim AccessToken As String = ResultJson("access_token").ToString
Dim RefreshToken As String = ResultJson("refresh_token").ToString Dim RefreshToken As String = ResultJson("refresh_token").ToString
Return {AccessToken, RefreshToken} Return {AccessToken, RefreshToken}
End If
Thread.Sleep(1000)
End While
Hint("验证超时,请尝试重新验证!")
Return {"Cancel", ""}
End Function End Function
''微软登录步骤 1:获取 DeviceCode 并显示验证提示 ''微软登录步骤 1:获取 DeviceCode 并显示验证提示