当前位置: 首页 > 知识库问答 >
问题:

iOS客户端:我可以让用户登录到Active Directory,但如何访问MS Graph API?

何浩荡
2023-03-14

我正在开发一个iOS应用程序,需要从MS Azure Active Directory读取用户数据。

我已经成功地从MS Azure文档中学习了iOS应用程序的一些示例,并成功地打开了它们的身份验证页面,让用户登录。我得到的是一些AdUserInformation对象形式的用户数据。

    NSString *authority = @"https://login.microsoftonline.com/a5960f61-0bf9-4bf6-96cd-98c61d30XXXX/federationmetadata/2007-06/federationmetadata.xml";

    NSString *resourceId    = @"74cd2559-0389-4871-9904-bc767d71XXXX"; // (server)

    NSString *clientId      = @"c8a956a7-84b7-4050-875c-896aab6bXXXX";   //ios-client (us)

    NSURL *redirectUri = [[NSURL alloc]initWithString:@"https://XXXXevents.azurewebsites.net/.auth/login/done"];

    ADAuthenticationError *error;

    ADAuthenticationContext * authContext = [ADAuthenticationContext authenticationContextWithAuthority:authority error:&error];

    //authContext.parentController = parent;

    [ADAuthenticationSettings sharedInstance].enableFullScreen = YES;

    [authContext acquireTokenWithResource:resourceId
                                 clientId:clientId
                              redirectUri:redirectUri
                          completionBlock:^(ADAuthenticationResult *result) {

          if (result.status != AD_SUCCEEDED) {
              NSLog(@"%@", result);
              return;
          }
          else {

              //save all of this information into core data

              NSDictionary * payload = @{@"access_token" : result.tokenCacheItem.accessToken};
              NSLog(@"%@", payload);

              //@"aad"
              //@"windowsazureactivedirectory"

              [[QSActivityService defaultService].client loginWithProvider:     @"aad"
                                                                     token:     payload
                                                                completion:     ^(MSUser * _Nullable user, NSError * _Nullable error) {

                                                                NSLog(@"loginWithProvider-------");
                  if(!error) {
                      NSLog(@"YAY! %s - user: %@ ", __FUNCTION__, user.userId);

                      ADUserInformation * temp = result.tokenCacheItem.userInformation;

                                           [[CoreDataStack defaultStack] updateUserDetailFamilyName:temp.allClaims[@"family_name"]
                                                                           version:temp.allClaims[@"ver"]
                                                                             email:temp.allClaims[@"email"]
                                                                               nbf:temp.allClaims[@"nbf"]
                                                                               exp:temp.allClaims[@"exp"]
                                                                         givenName:temp.allClaims[@"given_name"]
                                                                               idp:temp.allClaims[@"idp"]
                                                                            ipaddr:temp.allClaims[@"ipaddr"]
                                                                               iss:temp.allClaims[@"iss"]
                                                                               oid:temp.allClaims[@"oid"]
                                                                               typ:temp.allClaims[@"typ"]
                                                                               sub:temp.allClaims[@"sub"]
                                                                               amr:temp.allClaims[@"amr"]
                                                                               aud:temp.allClaims[@"aud"]
                                                                               alg:temp.allClaims[@"alg"]
                                                                               iat:temp.allClaims[@"iat"]
                                                                               tid:temp.allClaims[@"tid"]
                                                                              name:temp.allClaims[@"name"]
                                                                        uniqueName:temp.allClaims[@"unique_name"]];

    //other code, no problems here

然而,我想访问个人资料图像,和所有其他数据。我已经读过MS Graph API提供了它,但我不确定如何以及在哪里放置令牌。

是否使用Result.TokenCacheItem.AccesStoken中的令牌?如果是,在标题中?还是尸体?

或者我只需点击graph.windows.com两次。第一次获取身份验证令牌,第二次获取数据?

-(void)getUsersUsingAccessToken:(NSDictionary*)token completion:(void (^)    (void))completion {

    NSString * tenant = @"a5960f61-0bf9-4bf6-96cd-98c61d306f12";

    NSString * accessToken = token[@"access_token"];

    NSString * urlString = [NSString stringWithFormat: @"https://graph.windows.net/%@/tenantDetails?api-version=1.6", tenant];

    NSString * httpVerb = @"POST";

    //build an info object and convert to json
    NSDictionary * bodyFormDict

    = [NSDictionary dictionaryWithObjectsAndKeys:
     @"client_credentials",                              @"grant_type",
     @"https://graph.windows.net",                       @"resource",
     @"c8a956a7-84b7-4050-875c-896aab6xxxx",            @"client_id",
     @"XLlZl69aUKiQTo4dpeiprItm+LYbDtpt6e9dn0bxxxx",    @"client_secret",
     nil];

    NSError *error = nil;

    //1st step
    NSData * jsonInputData = [NSJSONSerialization dataWithJSONObject:bodyFormDict
                                                             options:NSJSONWritingPrettyPrinted
                                                               error:&error];

    //2nd step
    NSString * httpBodyString = [[NSString alloc]
                                 initWithData:jsonInputData
                                 encoding:NSUTF8StringEncoding];


    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    sessionConfiguration.allowsCellularAccess = YES;

    self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration];

    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    request.HTTPMethod = httpVerb;

    [request setValue:  @"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue:  accessToken forHTTPHeaderField:@"Authorization: Bearer"];

    [request setHTTPBody:[httpBodyString dataUsingEncoding:NSUTF8StringEncoding]];

    //asynchronous
    NSURLSessionDataTask * getDataTask = [self.session dataTaskWithRequest:request
                                                         completionHandler:^(NSData * _Nullable data,
                                                                             NSURLResponse * _Nullable response,
                                                                             NSError * _Nullable error) {

    //other code

}

感谢您抽出时间!

共有1个答案

骆文华
2023-03-14

我认为您遇到的问题是http头字段设置不正确。试试这个-

    NSString *authValue = [NSString stringWithFormat:@"Bearer %@", accessToken];
    [request setValue:authValue forHTTPHeaderField:@"Authorization"];
 类似资料:
  • web应用程序的单点登录(SSO)(通过浏览器使用)已得到充分的证明和确立。为富客户端建立SSO比较困难,通常建议基于Kerberos票证,尤其是使用Windows登录域中的ActiveDirectory。 但是,我正在为以下问题寻找一个更通用的解决方案:我需要建立“真正的”SSO(所有应用程序的一个标识,即不仅仅是跨应用程序的密码同步),其中在客户端(非托管计算机,包括非Windows),“最终

  • 我用Jhipster生成器生成了一个项目,并尝试使用android客户端连接到服务器。我的登录部分有问题,我不知道如何生成/获取登录所需的csrf令牌。我看到web客户端将此令牌作为请求的一部分发送。 当我试图从邮递员和Android访问路线我收到这个错误: 谢谢

  • 我正在使用js vanilla与html和纯PHP 我做了注册和登录页面与数据库。当用户成功登录登录页面时,将执行SessionStorage.SetItem(“logged”、“loggedIn”);然后重定向用户到主页面的'/'。 到现在为止一切都很好。 但是如果我手动更改URL的话,它将直接访问主页面! 那么如何检查用户在加载主页面之前是否登录? 我意识到我应该使用SessionStorag

  •  说明 调用方法: $.f2e.util.yy.isInstallYY(fn); 函数说明: UDB登陆 参数说明: 参数名 类型 说明 备注 fn function 回调函数 null为未登录YY客户端 无 脚本 <script> $.f2e.util.yy.isInstallYY(function(data){ if(data){ //有登录

  • 我试图在一个Spring引导应用程序中使用keyCloak管理客户端来改变keyCloak中用户的角色,但是我甚至不能实例化keyCloak。 我正在尝试在这里获取KeyClope服务器,但是我得到了一个实例化错误

  • 我们计划将主动 MQ (STOMP) 用于我们的一个项目。其中一个要求是,如果我们发现用户不合适,就将其踢出/禁止。如何通过单板技术实现这一点?有点像在 IRC 中踢球的东西。