iOS 客户端:我可以让用户登录到 Active Directory,但是如何访问 MS Graph API?
iOS client: I can have user sign into Active Directory, but how to access MS Graph API?
我正在开发需要从 MS Azure Active Directory 读取用户数据的 iOS 应用程序。
我已成功遵循 MS Azure 文档中有关 iOS 应用程序的一些示例,并成功调出他们的身份验证页面并让用户登录。我得到的是一些用户数据,形式为ADUserInformation object.
这是我的代码:
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 图API
但是,我想访问个人资料图片和所有其他数据。我读过 MS Graph API 提供了它,但我不确定我将如何以及在哪里放置令牌。
我是否使用来自 result.tokenCacheItem.accessToken 的令牌?如果是这样,在 header?或 body?
或者我只是按 graph.windows.com 两次。第一次拿到Authentication Token,第二次拿到数据?
我阅读了很多文档,其中 none 有效,因为我不断收到 Token Missing or Malformed 错误消息。
我的图表 API 代码如下所示:
-(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
}
如果有人可以提供使用 objective c 成功从 MS Graph API 检索数据的工作代码示例,那将是一个很大的帮助。
感谢您的宝贵时间!
我认为您遇到的问题是 http header 字段设置不正确。试试这个 -
NSString *authValue = [NSString stringWithFormat:@"Bearer %@", accessToken];
[request setValue:authValue forHTTPHeaderField:@"Authorization"];
我在 MS MSDN 的入门项目和代码示例中找到了答案
https://msdn.microsoft.com/en-us/office/office365/howto/starter-projects-and-code-samples
对我有帮助的具体项目是这样的:
https://github.com/OfficeDev/O365-iOS-Microsoft-Graph-Profile
在浏览该示例时请记住:
替换 INSERT-AUTHORITY-HERE - 您在其中配置应用程序的租户的名称。格式应为 https://login.windows.net/(YourAzureUserName).onmicrosoft.com
也有效
替换 INSERT-RESOURCE-ID-HERE - 您的移动应用后端的 ID。这是 Web API 服务应用程序 ID。不是本机客户端 iOS 应用程序。
替换 INSERT-CLIENT-ID-HERE - 您从 iOS NATIVE 客户端应用程序复制的客户端 ID。不是 Web API 服务应用程序。
使用 HTTPS 方案替换 INSERT-REDIRECT-URI-HERE - 您网站的 /.auth/login/done 端点。这个值应该类似于
@"https://XXXXXXXXXX.azurewebsites.net/.auth/login/done"
如果您在导入 ADAL 框架时遇到问题...
http://shanghaiseagull.com/index.php/2016/05/11/import-another-project-framework-into-your-project/
库可以在这里找到:https://github.com/AzureAD/azure-activedirectory-library-for-objc
希望它能帮助刚起步的人...如果我能提供进一步的帮助,请告诉我。
我正在开发需要从 MS Azure Active Directory 读取用户数据的 iOS 应用程序。
我已成功遵循 MS Azure 文档中有关 iOS 应用程序的一些示例,并成功调出他们的身份验证页面并让用户登录。我得到的是一些用户数据,形式为ADUserInformation object.
这是我的代码:
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 图API
但是,我想访问个人资料图片和所有其他数据。我读过 MS Graph API 提供了它,但我不确定我将如何以及在哪里放置令牌。
我是否使用来自 result.tokenCacheItem.accessToken 的令牌?如果是这样,在 header?或 body?
或者我只是按 graph.windows.com 两次。第一次拿到Authentication Token,第二次拿到数据?
我阅读了很多文档,其中 none 有效,因为我不断收到 Token Missing or Malformed 错误消息。
我的图表 API 代码如下所示:
-(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 }
如果有人可以提供使用 objective c 成功从 MS Graph API 检索数据的工作代码示例,那将是一个很大的帮助。
感谢您的宝贵时间!
我认为您遇到的问题是 http header 字段设置不正确。试试这个 -
NSString *authValue = [NSString stringWithFormat:@"Bearer %@", accessToken];
[request setValue:authValue forHTTPHeaderField:@"Authorization"];
我在 MS MSDN 的入门项目和代码示例中找到了答案
https://msdn.microsoft.com/en-us/office/office365/howto/starter-projects-and-code-samples
对我有帮助的具体项目是这样的: https://github.com/OfficeDev/O365-iOS-Microsoft-Graph-Profile
在浏览该示例时请记住:
替换 INSERT-AUTHORITY-HERE - 您在其中配置应用程序的租户的名称。格式应为 https://login.windows.net/(YourAzureUserName).onmicrosoft.com
也有效
替换 INSERT-RESOURCE-ID-HERE - 您的移动应用后端的 ID。这是 Web API 服务应用程序 ID。不是本机客户端 iOS 应用程序。
替换 INSERT-CLIENT-ID-HERE - 您从 iOS NATIVE 客户端应用程序复制的客户端 ID。不是 Web API 服务应用程序。
使用 HTTPS 方案替换 INSERT-REDIRECT-URI-HERE - 您网站的 /.auth/login/done 端点。这个值应该类似于 @"https://XXXXXXXXXX.azurewebsites.net/.auth/login/done"
如果您在导入 ADAL 框架时遇到问题...
http://shanghaiseagull.com/index.php/2016/05/11/import-another-project-framework-into-your-project/
库可以在这里找到:https://github.com/AzureAD/azure-activedirectory-library-for-objc
希望它能帮助刚起步的人...如果我能提供进一步的帮助,请告诉我。