iOS ADAL – 使用刷新令牌进行静默呼叫

我正在使用iOS ADAL库版本2.2.6并在成功登录后接收刷新令牌。 现在我想通过使用此刷新令牌进行静默调用。 我尝试使用以下方法,但无法返回访问令牌。

ADAuthenticationContext *authContext; [authContext acquireTokenSilentWithResource:resourceId clientId:clientId redirectUri:redirectUri userId:strUserID //loggedIn userID completionBlock:^(ADAuthenticationResult *result){ // It alway throws an error //Please call the non-silent acquireTokenWithResource methods. if(result.error){ ADAuthenticationError *error = nil; authContext = [ADAuthenticationContext authenticationContextWithAuthority:inputData.authority error:&error]; [authContext acquireTokenWithResource:inputData.ResourceID clientId:inputData.ClientId // Comes from App Portal redirectUri:inputData.RedirectUri // Comes from App Portal completionBlock:^(ADAuthenticationResult *result) { if (AD_SUCCEEDED != result.status){ // Show alert with error description } else{ //Handle Success token } }]; }else{ //Handle Success token } }]; 

但它始终抛出一个错误,说"The user credentials are needed to obtain access token. Please call the non-silent acquireTokenWithResource methods."

有没有办法使用刷新令牌进行静默呼叫? 请帮帮我。 提前致谢。

当您使用Microsoft的身份validation库时,您应该首先检查缓存中是否有用户可以在提示用户登录之前用于您的资源。这样我们就可以检查用户之前是否已登录过您的应用或是否有其他应用与您的应用共享状态可能已经要求用户在其他地方登录。

如果找到用户,我们将尝试获取令牌而不会中断用户。 有时用户会更改密码或执行其他操作,即使他们之前已登录过您的应用,也需要他们再次登录。 这就是你所看到的。 该库告诉您,对于您尝试获取令牌的用户,他们需要再次登录才能正确使用。

为了优雅地处理所有这些情况,我们建议您使用以下伪代码模式:

 acquireTokenSilent() (if error InteractiveAuthenticationRequired) { acquireTokenInteractively() } 

模式首先检查您指定的用户是否在令牌缓存中可用。 如果是,则我们调用Azure Active Directory服务以查看该用户的刷新令牌是否有效。 如果这两个都为真,那么用户将以静默方式登录。 如果未找到用户或服务器拒绝刷新令牌,则会从库发送错误,指示用户需要以交互方式登录。

在上面,您正在执行此第一部分,但您没有处理用户在出现问题时需要登录的情况。

最好的方法是使用ADErrorCode AD_ERROR_USER_INPUT_NEEDED捕获错误

以下是有关如何执行此模式的代码示例。

 // Here we try to get a token from the stored user information we would have from a successful authentication [authContext acquireTokenSilentWithResource:data.resourceId clientId:data.clientId redirectUri:redirectUri userId:data.userItem.userInformation.userId completionBlock:^(ADAuthenticationResult *result) { if (!result.error) { completionBlock(result.tokenCacheStoreItem.userInformation, nil); } else { if ([result.error.domain isEqual:ADAuthenticationErrorDomain] && result.error.code == AD_ERROR_USER_INPUT_NEEDED) { // Here we know that input is required because we couldn't get a token from the cache [authContext acquireTokenWithResource:data.resourceId clientId:data.clientId redirectUri:redirectUri userId:data.userItem.userInformation.userId completionBlock:^(ADAuthenticationResult *result) { if (result.status != AD_SUCCEEDED) { completionBlock(nil, result.error); } else { data.userItem = result.tokenCacheStoreItem; completionBlock(result.tokenCacheStoreItem.userInformation, nil); } }]; } else { completionBlock(nil, result.error); } } }]; 

请记住,这段代码非常详细。 你很可能想拥有acquireTokenWithResource:一个可以用[self acquireTokenWithResource]调用的单独方法