簡體   English   中英

MSAL B2C PasswordReset Flow 導致“無效授權”錯誤

[英]MSAL B2C PasswordReset Flow causes "invalid grant" error

我正在嘗試使用 iOS 上的 MSAL(1.1.7) 庫構建登錄/注冊和密碼重置流程。

對於B2C_1A_SignUpSignIn策略,一切似乎都正常。 在瀏覽器往返后收到令牌。

當用戶請求重置時,通過點擊AADB2C90118的“忘記密碼”:我根據文檔捕獲AADB2C90118錯誤代碼,並使用具有B2C_1A_PasswordReset策略的權限啟動新流程。

let authority = try MSALB2CAuthority(url: authURL)
let config = MSALPublicClientApplicationConfig(clientId: AuthCredential.clientID.description,
                                            redirectUri: AuthCredential.redirectUri.description,
                                              authority: authority)
config.knownAuthorities = [authority]
            
let application = try MSALPublicClientApplication(configuration: config)
            
return application

這一切都很好,重置流程,開始,可以完成並產生 accessToken 和 refreshToken。

現在問題來了,這些新獲取的令牌僅對B2C_1A_PasswordReset策略有效,當我靜默獲取令牌以用於我們的 api 時,它發生在B2C_1A_SignUpSignIn策略中。 這意味着我第一次嘗試執行包含對MSAL.getTokenSilently的調用的請求時,我收到此錯誤:

MSALErrorDescriptionKey=User interaction is required, 
MSALOAuthErrorKey=invalid_grant,
NSUnderlyingError=0x6000018a5590 {
    UserInfo = { MSALErrorDescriptionKey=AADB2C90088: The provided grant has not been issued for this endpoint. 
    Actual Value : B2C_1A_SignUpSignIn and Expected Value : B2C_1A_PasswordReset,
    MSALOAuthErrorKey=invalid_grant,
    MSALInternalErrorCodeKey=-42004 
    }
}

錯誤似乎相當清楚,如果我的理解至少是正確的,則沒有用戶,只有鏈接到B2C_1A_PasswordReset策略的 accessToken 和 refreshToken 。 並且需要手動用戶登錄。

我現在應該為用戶啟動手動登錄流程嗎?

iOS 忘記密碼流程將幾乎是愚蠢的:

  1. 點按帳戶(使用B2C_1A_SignUpSignIn策略要求令牌B2C_1A_SignUpSignIn
  2. iOS 提示允許在 safari 中打開 webview
  3. 用戶在 webview 中點擊“忘記密碼”
  4. 重定向回捕獲錯誤代碼的應用程序 ( AADB2C90118 )
  5. 使用 B2C_1A_PasswordReset 策略以B2C_1A_PasswordReset啟動B2C_1A_PasswordReset
  6. iOS 提示允許在 safari 中打開 webview
  7. 用戶跳過所有重置密碼圈
  8. 使用 accessToken 和 refreshToken 重定向回應用程序(我不能用於任何事情)
  9. 使用 B2C_1A_SignUpSignIn 策略以B2C_1A_SignUpSignIn啟動B2C_1A_SignUpSignIn
  10. iOS 提示允許在 safari 中打開 webview
  11. 用戶使用新憑據登錄
  12. 重定向回應用具有的accessToken和refreshToken(我可以使用)

Android沒有強制打開瀏覽器的提示,對於我的同事開發該流程,用戶在密碼重置后登錄,似乎在后台成功登錄。

我無法在 iOS 文檔中找到密碼重置流程的示例。 有其他平台的示例。

我可以以不同的方式構建它以獲得更好的流程嗎?

我們可以訪問后端,我們可以在那里做些什么嗎?

策略和在其上下文中檢索到的令牌是相關聯的。 可能有與不同策略相關聯的不同權限和流,因此從 MSAL/應用程序的角度來看,它們也可能是不同的后端。

好的,更好的流程是確保在使用getTokenSilently您還必須確保使用與檢索令牌的策略匹配的令牌。

在我在網上找到的所有 MSAL 示例中,這都不是問題,因為它們直接在 ViewController 中執行並保留對application對象的引用。 每次我需要它時,我都會像這樣設置它:

let authority = try MSALB2CAuthority(url: authURL)
let config = MSALPublicClientApplicationConfig(clientId: AuthCredential.clientID.description,
                                            redirectUri: AuthCredential.redirectUri.description,
                                              authority: authority)
config.knownAuthorities = [authority]
            
let application = try MSALPublicClientApplication(configuration: config)

具有執行特定任務所需的權限。 所以,就我而言,當用戶需要重置密碼時,我會更改權限,轉到 webview 並重置密碼,取回令牌,它們會自動放入 MSAL。 現在,當我打電話getTokenSilently我會用SignInSignUp政策,但在MSAL令牌將被鏈接到密碼重置策略=>“無效批”

我做了什么來修復它,因為我仍然認為僅在需要時實例化MSALPublicClientApplication的模式要好得多,因為這與應用程序中不同位置的各種 API 調用相關聯,而不僅僅是在一個 ViewController 中,是創建一個擴展上MSALPublicClientApplication與應用類方法,它從上一次成功的政策getTokenSilentlygetTokenInteractively ,總是用它來構建應用程序對象。

class func application() -> MSALPublicClientApplication? {
    do {
        let authURLString = UserDefaults.getMSALPolicyKey() ?? AuthCredential.signInAuthority.description
        let authURL = URL(string: authURLString)!
        let authority = try MSALB2CAuthority(url: authURL)
        
        let config = MSALPublicClientApplicationConfig(clientId: AuthCredential.clientID.description,
                                                       redirectUri: AuthCredential.redirectUri.description,
                                                       authority: authority)
        config.knownAuthorities = [authority]
        
        let application = try MSALPublicClientApplication(configuration: config)
        
        return application
        
    } catch {
        // catch and log error
        return nil
    }
}

政策應該像這樣保存:

application.acquireTokenSilent(with: silentParameters) { (result, error) in
    guard let result = result, let key = result.account.identifier, error == nil else {
    // Error handling
    UserDefaults.clearMSALPolicies() // clear policies so we default to standard policy 
        }
        
        completion(.failure(nsError))
    }
    // get policy directly from result
    UserDefaults.setMSALPolicyKey(key: result.authority.url.absoluteString)
    completion(.success(result.accessToken))
}

這將問題中的密碼重置流程列表縮減為 7 個步驟,並且用戶已登錄。

在 Android 上它實際上不起作用,我們只是有相當長的令牌,所以直到很晚,當帶有密碼重置策略的令牌過期並且客戶端嘗試使用 SignInSignOut 策略刷新它時,錯誤才出現在那里 => “無效授權”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM