首页 > 解决方案 > (iOS) 成功获取token,但应用第二次打开时无法从web API获取结果

问题描述

我正在使用 ADAL 2.4.1(适用于 iOS)。应用登录 Azure AD 后成功获取令牌,并能够使用令牌调用 Web API 并获取数据。但是,我退出/终止了该应用程序并再次打开该应用程序。应用程序仍然可以获取令牌,但无法从 Web API 获取数据。服务器将向应用程序返回一个 HTML 脚本。

该应用程序将登录 Azure AD 以获取访问令牌并将其存储在应用程序中(使用钥匙串)。我将使用存储的访问令牌来调用 API。

获取 API 的函数:

ADAuthenticationContext *authContext = [ADAuthenticationContext authenticationContextWithAuthority:AUTHORITY_URL error:nil];
authContext.credentialsType = AD_CREDENTIALS_AUTO;
NSURL *redirectUri = [[NSURL alloc]initWithString:REDIRECT_URI];

[authContext acquireTokenWithResource:"api_path"
                             clientId:CLIENT_ID
                          redirectUri:redirectUri
                       promptBehavior:AD_PROMPT_AUTO
                               userId:nil
                 extraQueryParameters: @""
                      completionBlock:^(ADAuthenticationResult *result)
 {
     if (result.status != AD_SUCCEEDED)
     {
         completionBlock(nil, nil, result.error);
     }
     else
     {
         completionBlock(result.tokenCacheItem.userInformation, result.tokenCacheItem.accessToken, nil);
     }
 }];

获取数据表单 WebAPI 的函数:

    NSURL *url=[NSURL URLWithString:"API Path"];
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)postData.length];

    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    NSMutableURLRequest *request = [NSMutableURLRequest new];
    [request setURL:url];
    [request setHTTPMethod:@"POST"];
    [request setTimeoutInterval: 15];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];       
    NSString* authValueToken = [NSString stringWithFormat:@"Bearer %@", "ADAL Token"];
    [request setValue:authValueToken forHTTPHeaderField:@"Authorization"];

    [request setHTTPBody:postData];

    [NSURLConnection sendAsynchronousRequest:request queue:opsQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         NSString* resultString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
         NSLog(@"result : %@", resultString);

首次启动应用,应用需要登录Azure AD或使用其他应用“Microsoft Authenticator”获取token。获取token成功,从web API获取数据。此外,应用程序会将令牌存储在应用程序中(使用钥匙串)。

第二次启动应用程序,因为我在“acquireTokenWithResource”函数中选择了 AD_PROMPT_AUTO。该应用程序将自动检查令牌(存储在钥匙串中)是否首先过期。如果未过期,它将使用此令牌调用 API。但是,服务器会向应用程序返回一个 HTML 脚本。此 HTML 脚本与登录页面相同。

HTML 脚本:

             Sign in to your account

<noscript>
    <meta http-equiv="Refresh" content="0; URL=https://login.microsoftonline.com/jsdisabled" />
</noscript>


    <link rel="shortcut icon" href="https://secure.aadcdn.microsoftonline-p.com/ests/2.1.8383.13/content/images/favicon_a_eupayfgghqiai7k9sol6lg2.ico" />

<meta name="robots" content="none" />
https://login.live.com/logout.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com","urlUxPreviewOptOut":"https://login.microsoftonline.com/common/uxpreview/optout","showCantAccessAccountLink":true,"fShowAsyncTileLoad":true,"urlFeatureAnnouncementBlogPost":"https://aka.ms/AA1edlw","fCollapseExcessLinks":true,"fShowLoginV2PreviewLink":true,"fEnableShowResendCode":true,"iShowResendCodeDelay":90000,"sSMSCtryPhoneData":"AF~Afghanistan~93!!!AX~Ã…land.....

标签: azure-active-directory

解决方案


您尝试访问的 API 可能未将请求标识为经过身份验证的请求,并且正在重定向客户端以使用 Azure AD 登录。这种行为有点奇怪,但如果 API 也是可以在浏览器中访问的端点,则可以解释。

您的客户端(移动应用程序)可能未在请求中正确发送访问令牌。在您的代码中,您有以下行:

NSString* authValueToken = [NSString stringWithFormat:@"Bearer %@", "ADAL Token"];

如果这实际上是您在应用程序代码中的内容,那么您需要更新它以实际使用Authorization标头中的访问令牌(从 ADAL 获得),而不是字符串“ADAL 令牌”。


推荐阅读