2014-12-01 97 views
0

試圖與Azure的Active Directory來驗證和獲取郵件,日曆數據的日曆事件,的accessToken成功返回:iOS的身份驗證Azure中的Active Directory及獲得Office 365的交換

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 =「訪問被拒絕。檢查憑據並重試。」; }; }

回答

1

我知道它晚來回答它,但是可能對於像我誰是努力得到同樣的事情做

我已經這樣做了使用office 365 SDK適用於iOS其中包含所有內置類是有幫助做你的工作。

如果您下載他們的示例代碼,它會爲您提供進行某些操作(郵件,日曆,聯繫人,一個驅動器)所需的所有詳細信息。

在使用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,你可以得到一個特定用戶的前景事件,在此之前,請確保您有在Azure的AD完全權限否則你可能會得到0事件響應。

請注意所有的方法都來自SDK示例,除了第一種方法來查看如何獲取我建議下載exchange example from the github的事件。

+0

我不知道該投票,因爲從Office 365的代碼示例具有相同的完整的詳細信息。如果我可以通過評論得到一些幫助,以改善答案,請讓我知道 – NSDumb 2015-02-16 09:54:08

+1

SO喜歡避免依賴鏈接的答案。官方文檔相關部分(鏈接旁)的引用意味着如果遠程站點不可用,答案仍然有用。 – Sobrique 2015-02-16 12:33:10

+0

@Sobrique:好的,讓我在我的答案中添加更多數據感謝您的幫助 – NSDumb 2015-02-16 12:44:36

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 

     }]; 

    } 
}]; 

    } 
相關問題