尝试使用Azure Active Directory进行身份验证并获取邮件,日历数据,accessToken成功返回:
authority = @"https://login.windows.net/common/oauth2/authorize";
redirectUriString = @"http://xxxxxx.xxxxxxx.com/oauth";
resourceId = @"https://outlook.office365.com";
clientId = @"xxxxxxx-xxxxx-xxx";
-(void) getToken : (BOOL) clearCache completionHandler:(void (^) (NSString*))completionBlock;
{
ADAuthenticationError *error;
authContext = [ADAuthenticationContext authenticationContextWithAuthority:authority
error:&error];
[authContext setValidateAuthority:YES];
NSURL *redirectUri = [NSURL URLWithString:redirectUriString];
if(clearCache){
[authContext.tokenCacheStore removeAllWithError:&error];
if (error) {
NSLog(@"Error: %@", error);
}
}
[authContext acquireTokenWithResource:resourceId
clientId:clientId
redirectUri:redirectUri
completionBlock:^(ADAuthenticationResult *result) {
if (AD_SUCCEEDED != result.status){
// display error on the screen
[self showError:result.error.errorDetails];
}
else{
completionBlock(result.accessToken);
}
}];
}
- (NSArray的*)getEventsList {
__block NSMutableArray * todoList;
[self getToken:YES completionHandler:^(NSString* accessToken){
NSURL *todoRestApiURL = [[NSURL alloc]initWithString:@"https://outlook.office365.com/api/v1.0/me/folders/inbox/messages?$top=2"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:todoRestApiURL];
NSString *authHeader = [NSString stringWithFormat:@"Bearer %@", @""];
[request addValue:authHeader forHTTPHeaderField:@"Authorization"];
[request addValue:@"application/json; odata.metadata=none" forHTTPHeaderField:@"accept"];
[request addValue:@"fbbadfe-9211-1234-9654-fe435986a1d6" forHTTPHeaderField:@"client-request-id"];
[request addValue:@"Presence-Propelics/1.0" forHTTPHeaderField:@"User-Agent"];
//[request addValue:@"true" forHTTPHeaderField:@"return-client-request-id"];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error == nil){
NSArray *scenarios = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
todoList = [[NSMutableArray alloc]initWithArray:scenarios];
//each object is a key value pair
NSDictionary *keyVauePairs;
for(int i =0; i < todoList.count; i++)
{
keyVauePairs = [todoList objectAtIndex:i];
NSLog(@"%@", keyVauePairs);
}
}
NSLog(@"Finished");
//[delegate updateTodoList:TodoList];
}];
}];
return nil; }
在响应对象中返回错误:
{ error = { code = ErrorAccessDenied; message =“访问被拒绝。检查凭据,然后重试。”; }; }
答案 0 :(得分:1)
我知道很晚才回答这个问题,但对于像我这样努力完成同样事情的人来说可能会有所帮助
我使用适用于iOS的office 365 SDK来完成此操作,其中包含所有内置类来完成您的工作。
如果您下载示例代码,它将为您提供执行某些操作所需的所有详细信息(邮件,日历,联系人,一个驱动器)。
在使用SDK之前,请确保您登录Azure AD和register your application and add permissions,这样就不会收到403错误代码或任何拒绝访问的消息。
我使用以下代码从Outlook日历中获取我的活动详情
[self getClientEvents:^(MSOutlookClient *client) {
NSURLSessionDataTask *task = [[[client getMe] getEvents] read:^(NSArray<MSOutlookEvent> *events, MSODataException *error) {
if (error==nil) {
if (events.count!=0) {
dispatch_async(dispatch_get_main_queue(), ^{
for(MSOutlookEvent *calendarEvent in events){
NSLog(@"name = %@",calendarEvent.Subject);
}
});
}else{
NSLog(@"No events found for today");
}
}
}];
[task resume];
}];
getClientEvents 是一种方法,可以调用Office 365 SDK并获取用户的事件详细信息,但它首先获取资源的令牌,然后使用获取的令牌进行调用
-(void)getClientEvents : (void (^) (MSOutlookClient* ))callback{
[self getTokenWith : @"https://outlook.office365.com" :true completionHandler:^(NSString *token) {
MSODataDefaultDependencyResolver* resolver = [MSODataDefaultDependencyResolver alloc];
MSODataOAuthCredentials* credentials = [MSODataOAuthCredentials alloc];
[credentials addToken:token];
MSODataCredentialsImpl* credentialsImpl = [MSODataCredentialsImpl alloc];
[credentialsImpl setCredentials:credentials];
[resolver setCredentialsFactory:credentialsImpl];
[[resolver getLogger] log:@"Going to call client API" :(MSODataLogLevel *)INFO];
callback([[MSOutlookClient alloc] initWithUrl:@"https://outlook.office365.com/api/v1.0" dependencyResolver:resolver]);
}];
}
getTokenWith方法首先获取资源的令牌,然后使用获取的令牌进行必要的调用以获取事件,但在获取令牌之前,它会检查缓存以查看是否有任何令牌可用于相同的资源。
// fetch tokens for resources
- (void) getTokenWith :(NSString *)resourceId : (BOOL) clearCache completionHandler:(void (^) (NSString *))completionBlock;
{
// first check if the token for the resource is present or not
if([self getCacheToken : resourceId completionHandler:completionBlock]) return;
ADAuthenticationError *error;
authContext = [ADAuthenticationContext authenticationContextWithAuthority:[[NSUserDefaults standardUserDefaults] objectForKey:@"authority"] error:&error];
NSURL *redirectUri = [NSURL URLWithString:@"YOUR_REDIRECT_URI"];
[authContext acquireTokenWithResource:resourceId
clientId:[[NSUserDefaults standardUserDefaults] objectForKey:@"clientID"]
redirectUri:redirectUri
completionBlock:^(ADAuthenticationResult *result) {
if (AD_SUCCEEDED != result.status){
[self showError:result.error.errorDetails];
}
else{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:result.tokenCacheStoreItem.userInformation.userId forKey:@"LogInUser"];
[userDefaults synchronize];
completionBlock(result.accessToken);
}
}];
}
getCacheToken方法:检查是否有任何资源的可重用令牌。
-(BOOL)getCacheToken : (NSString *)resourceId completionHandler:(void (^) (NSString *))completionBlock {
ADAuthenticationError * error;
id<ADTokenCacheStoring> cache = [ADAuthenticationSettings sharedInstance].defaultTokenCacheStore;
NSArray *array = [cache allItemsWithError:&error];
if([array count] == 0) return false;
ADTokenCacheStoreItem *cacheItem;
for (ADTokenCacheStoreItem *item in array) {
if([item.resource isEqualToString:resourceId]){
cacheItem = item;
break;
}
}
ADUserInformation *user = cacheItem.userInformation;
if(user == nil) return false;
if([cacheItem isExpired]){
return [self refreshToken:resourceId completionHandler:completionBlock];
}
else
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:user.userId forKey:@"LogInUser"];
[userDefaults synchronize];
completionBlock(cacheItem.accessToken);
return true;
}
}
使用此代码和Office 365 SDK,您可以获取特定用户的Outlook事件,然后确保您在Azure AD中拥有完整权限,否则您可能会收到0个事件作为响应。
请注意所有方法都来自SDK示例,除了第一种方法,以查看如何获取我建议下载exchange example from the github的事件。
答案 1 :(得分:0)
您还可以使用MSGraph SDK获取日历和事件:
检查此链接:配置过程相同,仅提取事件不同(查看用于获取事件的给定代码):
How to Fetch/Create calender by O365-iOS-Connect?
注意:上面的链接用于从Outlook获取日历,但此过程与此相同,但您应在身份验证后使用此代码并完成获取事件操作,如下所示:
- (IBAction)getCalendarsEvents:(id)sender {
[NXOAuth2AuthenticationProvider setClientId:clientId
scopes:@[@"https://graph.microsoft.com/Files.ReadWrite",
@"https://graph.microsoft.com/Calendars.ReadWrite"]];
[[NXOAuth2AuthenticationProvider sharedAuthProvider] loginWithViewController:nil completion:^(NSError *error) {
if (!error) {
[MSGraphClient setAuthenticationProvider:[NXOAuth2AuthenticationProvider sharedAuthProvider]];
self.client = [MSGraphClient client];
// Authentication done
[[[[_client me] events] request] getWithCompletion:^(MSCollection *response, MSGraphUserEventsCollectionRequest *nextRequest, NSError *error){
NSArray *arr = response.value;
MSGraphEvent *event = arr.firstObject;
// Here you will getting outlook events
}];
}
}];
}