Tag Archives: Azure AD

Developing Yammer apps for iOS/OS X with ADAL, REST API and Swift 2.0

You’re interested to develop applications on top of Yammer (Microsoft’s Enterprise Social Network) but you’re currently working on iOS/OS X devices ? No problem ūüėČ

Yammer offer to developers a REST API to allow them build applications on top of the product. Microsoft has also started to move the authentication mechanism to Office 365, to let people to use the same credentials as for other services in their company (Outlook, SharePoint, Skype for Business…).

In this article, we’ll discover what are the main steps to create our first application which will use the Yammer REST API and Office 365 authentication, in conjunction with Swift 2.0, the new programming language of Apple platforms, updated during the WWDC 2015.

Declare your application in Azure Active Directory

The first step to accomplish to be able to develop an application which will call the Yammer REST API with the Office 365 authentication (based on Azure AD), is to declare your application in Azure.

To do this, you need to be a global administrator of your tenant, and you can achieve this by using the Azure Management Portal : https://manage.windowsazure.com

On the Azure Management Portal, go to Active Directory section, select the appropriate directory, select applications and create a new native application.

After you fill the requested information (a name and a redirect URL), you have to declare for each service (SharePoint, Exchange, Active Directory…) what permissions are needed by your application as you can see below.

Few weeks ago, Microsoft has released a new permission which allows you to use the Yammer REST API (it’s a preview for now). So just add it to your application (as you can see below) and save your modifications.

Office 365 Yammer - Azure AD Permissions

Authenticate with ADAL

The second step to develop your application is to acquire an authentication token from Azure AD and to pass it to the Yammer REST API when you want to retrieve data.

The simplest way to acquire an authentication token from Azure AD is to use the Azure Active Directory Library (aka. ADAL) which can be downloaded for free on GitHub : https://github.com/AzureAD/azure-activedirectory-library-for-objc

After downloading the library and integrating it in your application (cf. documentation on GitHub on how to achieve this goal), you can acquire a token with just few lines of code.

var authError: ADAuthenticationError?
var authContext = ADAuthenticationContext(authority: "https://login.windows.net/common", error: &authError)
var bearerToken: String!

authContext.acquireTokenWithResource("https://www.yammer.com/", clientId: "...", redirectUri: "...", completionBlock: { (result: ADAuthenticationResult!) in
    guard (authError == nil) && (result.accessToken != nil) else {
        // Authentication Error
        return
    }

    bearerToken = result.accessToken
}

The Swift code above is pretty simple to understand :

  • We declare an authentication context
  • We call the acquireTokenWithResource method with required parameters (clientId and redirectUri are the same you filled in step #1)
  • If the token was successfully acquired, we store it in a variable to use it later

Use the Yammer REST API

Now that we have a valid authentication token, we are now able to use the Yammer REST API. If you need some information about all the capabilities available in that API, you can refer to the official documentation : https://developer.yammer.com/v1.0/docs/userscurrentjson

In Swift, we are able to use all the frameworks (Foundation, AppKit, UIKit…) available on iOS/OS X and which allow us to perform advanced operations in a simple manner.

To perform HTTP communications, we can use the NSURLSession class. With just few lines of code, we are able to send a request to a server (synchronously or asynchronously) and to retrieve the response.

let URLSession = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
let request = NSMutableURLRequest(URL: NSURL(string: "https://www.yammer.com/api/v1/users/current")!)
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue(bearerToken, forHTTPHeaderField: "Auhtorization")
let task = URLSession.dataTaskWithRequest(request) { (data: NSData?, response: NSURLResponse?, error: NSError?) in
    guard (data != nil) else {
        // No data returned
        return
    }
    processResult(data)
}
task?.resume()

The most important part in the code above, to authenticate the request, concerns the addition of an Authorization header to the request. The header is a concatenation of the token retrieved in step 2 with the Bearer keyword such as “Authorization: Bearer our_authentication_token“.

If the request is successfully executed (it returns data), then we call the processResult method by passing the retrieved data as parameter.

Deserialize JSON response and catch errors

The last step to perform in our application is to parse the retrieved data. Because we have passed an Accept header to the previous request to indicate that we want to retrieve the data as JSON, we just have to deserialize and to use them.

Once again thanks to Foundation which expose a class (NSJSONSerialization) to perform this operation.

If you used Swift 1.x during the last year, focus your attention on the code below. A brand new way to deserialize and catch potential errors has been introduced with Swift 2.0 (do … catch).

func processResult(data: NSData?) {    
    do {
        let JSONObject = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
        print(JSONObject, appendNewline: true)
    } catch let error as NSError {
        print(error, appendNewline: true)
    }
}

In the code above, we just print the deserialize object so it should display something like that :

{
    "activated_at" = "2015/01/01 01:01:00 +0000";
    admin = true;
    "birth_date" = "";
    "can_broadcast" = true;
    "can_browse_external_networks" = 1;
    "can_create_new_network" = 1;
    contact = { ... };
    department = Direction;
    email = "...";
    expertise = "Office 365 REST API, SharePoint, iOS, Objective-C, Swift";
    "external_urls" = ();
    "first_name" = "Stéphane";
    "follow_general_messages" = 0;
    "full_name" = "Stéphane Cordonnier";
    guid = "<null>";
    id = 123456789;
    interests = "<null>";
    "job_title" = "Technology Addict";
    "kids_names" = "<null>";
    "last_name" = Cordonnier;
    location = Paris;
    ...
}

If you want to use and parse the deserialized object, it’s a key/value dictionary so it’s pretty simple to use it.

AADSTS90093 – Calling principal cannot consent due to lack of permissions

When you develop your own applications which use the Office 365 REST API, it might happen that users are facing the following error message when they try to authenticate, when your application is supposed to ask the consent of the user to access his data.

AADSTS90093 - Authentication Error

The difficult thing to understand is why this message is displayed and why all users are not concerned ?

Declare the application’s rights in Azure AD

When you create an application, you have to declare which rights are needed to access data when you make calls to the REST API.

Those rights are declared in Azure AD through the web console (https://manage.windowsazure.com) as you can see below.

Azure Manage Portal - Application Permissions

Which is not indicated in the web console is that some of those rights need that an administrator (at the tenant level) give a consent to allow your application to use them.

If the consent of an administrator was not given and a non-administrator user tries to use the application, he will receive the following error message : AADSTS90093 – Calling principal cannot consent due to lack of permissions.

What permissions require an administrator consent ?

If you would like a complete description of how permissions work on Office 365, you could refer to the official documentation on MSDN : https://msdn.microsoft.com/office/office365/HowTo/application-manifest

In short if you want to know what permissions require an administrator consent, it depends of which product  and which features you want to use.

You can find below a quick summary (grouped by products) of all the permissions which require an administrator consent. All other permissions (not listed below) only require a user consent.

SharePoint

  • Have full control of all site collections
  • Run search queries as a user
  • Read user profiles
  • Read and write user profiles
  • Read managed metadata
  • Read and write managed metadata

Outlook

No permission requires an administrator consent

Azure Active Directory

  • Read all users’ full profiles
  • Read directory data (except if the application is registered in the same tenant as the user)
  • Read and write directory data
  • Access the directory as the signed-in user (only for web applications)

Yammer

No permission requires an administrator consent

What to do if I encounter the error message ?

If you are facing to the error message mentioned previously, the first thing to do is to check if your application uses one of the permission in the list above.

If it’s the case, make sure that you absolutely need it, otherwise remove the right from the declared permissions for your application in Azure AD and it should solve the problem.

For example, you can perform searches on SharePoint sites under the identity of the current user, even if you only have the “Read items in all site collection” permission. It’s not needed to add the “Run search queries as a user” permission.

If you need the permission, you have to ask a tenant administrator to consent your application. Until the administrator consent, all users which are not administrators of the Office 365 tenant won’t be able to log-in and use your application.

Introducing the new Office 365 unified API

Build conference was held in San Francisco this week (from April 29th to May 1st) and it was the place to be because Microsoft made a lot of announcements around its ecosystem (Windows 10, Azure, HoloLens, Office 365…).

Among all the news annouced this week, we particularly appreciated the launch (in preview version for now) of the Office 365 unified API. Let’s take a look to this new API.

Why a new API ?

As you probably know, Office 365 offers a lot of features for companies who needs a directory, emails, instant messaging, collaboration, videos, search, social network…

Each of these features are offered by a dedicated product (Azure AD, Exchange, Lync, SharePoint, Yammer, OneDrive for Business…) and it was pretty complicated to develop solutions which are connected with all of them.

Indeed, each product has its own API, accessible through a dedicated endpoint :

It’s to simplify all of this, that the new Office 365 Unified API was created. It allows developers to create solutions which are able to reach the content of each product from a single endpoint.

Office365 Unified API

A single endpoint is more easy to use and it simplifies a lot of tasks such as managing authentication tokens (you need one access token for each endpoint when you use the actual Office 365 APIs).

This new API works like the actual APIs so to use it, you need to :

  • Register you app in Azure AD
  • Define permission scopes and security
  • Authenticate through OAuth 2.0

Office365 Unified API - Registration in Azure

To retrieve data from your tenant and after successful completion of the authentication process, you can send requests to the endpoint as you can see in the following examples.

Me (or other users)

Get information about the current user (the authenticated user) :

https://graph.microsoft.com/beta/me

Get the picture (of given dimensions) for the current user :

https://graph.microsoft.com/beta/me/userphotos/96X77

Get the manager, the subordinates or the groups for the current user :

https://graph.microsoft.com/beta/me/manager
https://graph.microsoft.com/beta/me/directReports
https://graph.microsoft.com/beta/me/memberOf

Get information about another user in your company’s directory¬† :

https://graph.microsoft.com/beta/contoso.com/users/demo@contoso.com
https://graph.microsoft.com/beta/contoso.com/users/demo@contoso.com/manager
https://graph.microsoft.com/beta/contoso.com/users/demo@contoso.com/memberOf

Messages

Get the email messages for the current user :

https://graph.microsoft.com/beta/me/messages

Get the last 5 message for the current user :

https://graph.microsoft.com/beta/me/messages?$top=5

Get the next 5 messages ordered by creation date :

https://graph.microsoft.com/beta/me/messages?$top=5&$skip=5&$orderby=DateTimeCreated

Calendar / Events

Get the events for the current user :

https://graph.microsoft.com/beta/me/events

Get the events for the current user between the start date and the end date:

https://graph.microsoft.com/beta/me/calendarview?startdatetime=2015-04-01t01:00:00z&enddatetime=2015-04-16t23:00:00z

SharePoint Files / OneDrive Files

Get OneDrive’s for Business files for the current user and get a specific file by using its ID :

https://graph.microsoft.com/beta/me/files
https://graph.microsoft.com/beta/me/files/<id>

Get OneDrive’s for Business files for a given user :

https://graph.microsoft.com/beta/demo@contoso.com/files

Groups

Get the groups (collaboration and not security/distribution) for your company :

https://graph.microsoft.com/beta/contoso.com/groups?$filter=groupType+eq+'Unified'

Get the members, the files, and the conversations for a group by using its ID :

https://graph.microsoft.com/beta/contoso.com/groups/<id>/members
https://graph.microsoft.com/beta/contoso.com/groups/<id>/files
https://graph.microsoft.com/beta/contoso.com/groups/<id>/conversations

Office Graph / Delve

Get the people with whom the current user work with :

https://graph.microsoft.com/beta/me/workingWith

Get the data (documents, email attachments…) which are trending around the current user :

https://graph.microsoft.com/beta/me/trendingAround

What’s coming next ?

In the examples presented in this article, we only saw how to get data but you are already able to perform CRUD operations as you can do it today with other dedicated endpoints.

It’s also good to note that Microsoft has updated its client libraries for .NET, iOS and Android to support the new unified API.

The Office 365 Unified API available today is just the first version (a preview version) and a lot of improvements will be available in the future. New data types will be added in the next few months.

Among some of the improvements already announced by Microsoft during the conference :

  • Tasks
  • Notes
  • Skype
  • Personal Contacts
  • Notifications
  • And much more…

Want to learn more and want to try it ?

The first thing to see if you want to discover the new API (this article was based on it) is the webcast of the session named “Supercharging Your Custom Solutions with the Office 365 Unified API Endpoint” which has been recorded during the Build conference. It’s available on Channel 9 : http://channel9.msdn.com/Events/Build/2015/3-641

If you want to learn more about the new Office 365 Unified API, you can also refer to the official documentation available at http://dev.office.com/unifiedAPIs.

Microsoft has also created/updated some websites if you want to try the new API directly from your web browser: