[英]How to implement Azure AD B2C PasswordReset functionality in an iOS App
[英]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 忘記密碼流程將幾乎是愚蠢的:
B2C_1A_SignUpSignIn
策略要求令牌B2C_1A_SignUpSignIn
)AADB2C90118
)B2C_1A_PasswordReset
啟動B2C_1A_PasswordReset
B2C_1A_SignUpSignIn
啟動B2C_1A_SignUpSignIn
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
與應用類方法,它從上一次成功的政策getTokenSilently
或getTokenInteractively
,總是用它來構建應用程序對象。
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.