Using OAuth2 to access Calendar, Contact and Mail API in Office 365 Exchange Online

I am excited to announce that finally EWS in Exchange Online as part of Office 365 exposes a RESTful API for Calendar, Contact and Mail that uses OAuth2 for authorization. In this blog I want to briefly describe Exchange's underlying OAuth2 implementation and how to use OAuth2 to access the new Calendar, Contact and Mail APIs.

First and foremost Office 365 fully integrates with Microsoft Azure Active Directory (AAD) to implement the OAuth2 protocol. There is an exciting announcement available here from Alex Simons, Director of AAD that outlines the new AAD capabilities around this protocol. At the end of this blog I will refer to more documentation. Don't hesitate to ask questions on Stack Overflow about accessing the new APIs using the OAuth2 protocol or about the APIs themselves. Please tag your question with [ms-office] and [ews] to get the fastest response possible.

I will focus in this post on the basic concepts and will highlight some of the differences compared to other OAuth2 implementations to get you started as fast as possible. 

Step One: Registering your application

Before you can use OAuth2 to access the Calendar, Contact and Mail APIs, your application needs to be registered in AAD. When you sign up for Office 365 for business or Office 365 developer, don’t worry, you already get AAD. If you are using Visual Studio, the app registration and permission management in AAD is done automatically for you! Outside of Visual Studio, you should visit the Microsoft Azure Portal and do the application registration there. For a step by step walkthrough, go here. During the application registration process a client ID for your application is created, client secrets for web apps are managed, and the permissions your application needs for accessing the APIs are defined.

Important:   Permissions must be defined up-front in AAD for the APIs as part of the registration process. While you might be used to specifying the permissions with the authorization request in other OAuth2 implementations by using the "scope" parameter, this is not possible at this point. In order for your application to configure these permissions in AAD, the AAD tenant where your application is registered must be linked to an Office 365 subscription with Exchange Online.

Step Two: Triggering user consent (aka authorization)

The goal of your application is to access the Calendar, Contact and Mail APIs. For this you need to get an access token that is passed along with the API request to Office 365. An OAuth2 authorization request is the first step for your application to get an access token. As part of the authorization process, user consent is involved. User consent is the act of displaying a dialog that clearly lists the permissions that your application is requesting. The user can decide if the permissions your application is requesting should be granted. The permissions that appear in this consent dialog are the same permissions you configured in Step One in AAD.

A typical authorization request looks like this (make sure you use https):

GET https://login.windows.net/common/oauth2/authorize?response_type=code&client_id=acb81092-056e-41d6-a553-36c5bd1d4a72&redirect_uri=https://mycoolwebapp.azurewebsites.net&resource=https:%2f%2foutlook.office365.com%2f&state=5fdfd60b-8457-4536-b20f-fcb658d19458

 

Parameter

Description

response_type

Required. Value is always code

client_id

Required. Value of your client_Id given when you registered your application with AAD

resource

Required. The Office 365 resource your app wants to access. As you want to access Office 365 Calendar, Contact, and Mail APIs this is "https://outlook.office365.com/".

state

Required. A long unique string value of your choice that is hard to guess. Used to prevent CSRF. For example, this can be a Guid generated by your app with each authorization request.

redirect_uri

Required. URI in your app where users will be sent after authorization. Must be registered in AAD.

Important: Redirect URIs must be registered in AAD as "Reply URLs" as part of the initial app registration, or at any point in time later in the process of developing your app. Failure to specify the correct redirect_uri will cause the authorization request to fail. So check your Reply URLs in AAD with your app registration.

If the user authorizes your application they will be redirected to the redirect_uri that you specified in your request above along with a temporary authorization code and the same state that you passed in the request above.

Upon successful authorization, the redirected URL should look like:

{your redirect uri}/?code={authorization code issued by AAD}&state={same state Guid passed as in the authorize request}

Ensure that the state parameter in this response matches the one you passed in the authorization request above. If the state does not match, that means the request may be a result of CSRF and must be rejected. 

If the user does not allow authorization to your application, redirection to the redirect_uri still occurs. Additional query parameters indicate the user canceled authorization and a short description of the error: 

{your redirect uri}/?error=access_denied&error_description=AADSTS65004%3a+The+resource+owner+or+authorization+server+denied+the+request.%0d&state={same state Guid passed as in the authorize request}

Before we continue with the next step on how to trade in the authorization code to an actual access token that you can use to access the Office 365 Calendar, Contact and Mail APIs we need to talk about a very nice variation of authorization you can request for a web application. Note that following doesn't apply for a native application. In particular AAD offers for a web application the capability for an administrator of an Office 365 Organization to consent on-behalf of all users in this organization. Once an administrator does this, users will not see any additional consent dialog with authorization requests. Essentially what this provides you is that your web application can have a sign-up experience for an organization in addition to an individual sign-up for a user.

You can accomplish this kind of organization sign-up in your app by simply modifying the authorize request to add an additional parameter called "prompt". For the example above this would be:

GET https://login.windows.net/common/oauth2/authorize?response_type=code&client_id=acb81092-056e-41d6-a553-36c5bd1d4a72&redirect_uri=https://mycoolwebapp.azurewebsites.net&resource=https:%2f%2foutlook.office365.com%2f&state=5fdfd60b-8457-4536-b20f-fcb658d19458&prompt=admin_consent

Triggering admin consent for an organization sign-up:

Parameter

Description

prompt

Value: "admin_consent". Indicates that the authorization request is for all users in an Office 365 Organization.

Important: Only an administrator of an Office 365 Organization can consent to such an authorization request. If an end-user tries to do this, AAD will redirect back to your application with an specific error indicating that consent could not be given.

Step Three: Trade-In for an access/refresh token

We're almost there. At this point we have an authorization code from a user or an administrator dependent on the authorization request your application sent. This code can be used to request an access token. Together with the access token your application will also receive a refresh token and an ID token. For the API access only the access token is important. The refresh token is for your app to keep in a safe place in an encrypted persistent temporary or permanent storage dependent on your app's requirements. You use the refresh token to request additional access tokens for either the same Calendar, Contact and Mail APIs or other Office 365 APIs such as OneDrive Pro. The ID token can be used to authenticate the user to your application. It contains the users ID and the organizations ID as known by AAD. You can use those IDs for your app's own memory or profile store on who signed up. Both access token and refresh token are JSON encoded web tokens that can be easily parsed. The specific properties to use for building an app-specific profile store in the ID token are "oid" for the user identifier and "tid" for the organization identifier.

Let's look at how such a token request looks like using the code.

Code Request:

The base token URL is:

POST https://login.windows.net/common/oauth2/token

The body is form encoded:

grant_type=authorization_code&code={code from the authorize request}&redirect_uri={reply url for your application}&client_id={your application's client id in AAD}&client_secret={your application's client secret}

Important : The redirect_uri in the token request must be the same as the one used with the original authorize request.

A successful response to this request contains the following fields in a JSON object:

Field

Description

access_token

Base64 url encoded JSON web token for API access.

token_type

Always "Bearer"

expires_in

The time period (in seconds) after which the access token will become invalid. For now this value is 60 minutes.

expires_on

Time in Unix epoch when the access token expires.

resource

The Office 365 resource or API that this access token applies to.

refresh_token

Opaque refresh token for your app to keep and get additional access tokens.

scope

The permissions that this access token contains.

id_token

Base64 url encoded JSON web token for user identification by the client application.

After 60 minutes the access token becomes invalid. A good pattern to follow is to cache this access token and use it to call the Calendar, Contact and Mail APIs until the API returns a 401 access denied with an error code of "invalid_token". In that 401 event your app should use the refresh token to get a new access token and retry the request.

Note: In case you are curious about what an access token or ID Token look like, there is a great web app available at https://jwt.calebb.net that allows you to simply cut and paste the token received from a token request and peek into the fields.

Request additional access tokens with a refresh token

Below is the request your app uses to get a new access token. The actual response is the same as in the code request, thus together with the access token your app receives a new refresh token. You should take the new refresh token to replace the old one as refresh tokens will expire in some period of time too.

The base token URL is:

 POST https://login.windows.net/common/oauth2/token

 The body is form encoded:

 

grant_type=refresh_token&refresh_token={the current RefreshToken in your applications cache}&client_id={your application's client id in AAD}&client_secret={your application's client secret}&resource={Uri of the API}

 

Important: The resource parameter indicates what API endpoint your application wants access to within the Office 365 APIs. For the Calendar, Contact and Mail API this is "https://outlook.office365.com".

As briefly mentioned above, the refresh token, while long living, becomes invalid at some point too. One example is if the user changes their password, refresh tokens become invalid. Your app can react to this gracefully by handling an error response from the token request that returns "invalid_grant". If this happens your app should go back to the authorization request as outlined in Step One to get a new authorization code and use this to get a new access token/refresh token pair.

 

Step Four: Accessing the API with the access token

We are almost there. Your application has an access token at this point for the Calendar, Contact and Mail API. Using this access token is fairly simple. When sending a RESTful API https request the access token is attached in the standard authorization header with the Bearer auth scheme. An example is listed below: 

GET https://outlook.office365.com/api/v1.0/me/folders/inbox/messages?$top=10

User-Agent: My-Cool-WebApp/1.0client-request-id: 9aa1c740-25e2-4841-9146-ef7018f7bf37return-client-request-id: trueauthorization: Bearer {access token your app received in Step Three}

Important: Always use https with your API request.

Unrelated to OAuth2, there are three http request headers the Office365 APIs would want your application to specify. This is the "User-Agent" the "client-request-id" and "Date". For User Agent you can follow RFC 2616 which basically describes it as {ProductName}/{ProductVersion} [{comment}]. For "client-request-id" your app should create a new Guid for each request. When the request fails "return-client-request-id" returns the Guid that was submitted as "client-request-id" with the request. It is highly recommended that you persist the failed request together with client-request-id and all http response headers in some application log. The "Date" requst header signals the date and time that the message was sent. It should follow the "HTTP-date" format as defined by RFC 2616)}. If you ever need help troubleshooting your application with the Office 365 APIs, this will be pave the route to a fast and successful resolution of the problem.

 

Client libraries are your Friend - use them!

Above I described how your application can apply the OAuth2 protocol for Office 365 APIs on the example of the Calendar, Contact and Mail API. While the OAuth2 protocol is a fairly straight forward and well understood pattern there are many things such as caching of access tokens/refresh tokens that are more complicated to handle within an application. The Azure Active Directory Authentication Library (ADAL) will help you abstracting not only the OAuth2 protocol, but also provide caching and mechanisms to get new access tokens. Whenever possible you should use this client library for your web or native app. ADAL comes for a variety of platforms including .NET, Windows Store, iOS and Android. Check them out!

Summary

Hopefully this blog provided you with enough detail to get started developing an exciting application for the Calendar, Contact and Mail API in Office 365. We would love to hear from you at this forum and are eager to know about your apps and feedback on how we can improve on our APIs and authentication to them.

Note that there will be many more functionalities coming in the next month and I will try to keep the blog updated whenever a new capability lights up. For example, the current blog describes the OAuth2 code flow, and AAD in the near future will provide a OAuth2 implicit flow that is optimized for JavaScript-based applications such as Office 365 mail apps. For sure we will post about this pretty soon. We are also working on having OpenID Connect available for single sign-on into your web app and Office 365. All more exciting functionality that will make application development more easy and hopefully worry-free regards the way your application authenticates with Office 365 APIs.

Additional documentation of interest

Finally, as promised, some pointers to documentation. Lots of time went into these and they are well worth reading while sipping your morning or afternoon coffee:

OAuth Sandbox: https://oauthplay.azurewebsites.net/

API Sandbox: https://apisandbox.msdn.microsoft.com/

Platform Overview: https://msdn.microsoft.com/en-us/office/office365/howto/platform-development-overview

Apps for Office: https://msdn.microsoft.com/en-us/library/office/fp161507(v=office.15).aspx

Office on Github: https://github.com/OfficeDev

OAuth2 Authorization Grant: https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx

OAuth2 client libraries: https://msdn.microsoft.com/en-us/library/azure/dn151135.aspx

AAD on GitHub: https://github.com/AzureADSamples

Comments

  • Anonymous
    March 25, 2014
    I started playing with the Exchange API a couple of days ago, and I'm liking it so far. So, I put together a two-parter on how to get started coding: mobilitydojo.net/.../microsoft-provides-a-restful-api-for-exchange-part-1 mobilitydojo.net/.../microsoft-provides-a-restful-api-for-exchange-part-2 I also created a repo on GitHub for the purpose of having a proof of concept for labs: github.com/.../CustomOffice365OWA (The initial commit does not have all the bells and whistles of a proper OWA or snazzy UI, but it's something to get started with.)

  • Anonymous
    March 31, 2014
    Nice! Thanks for doing this Andreas.

  • Anonymous
    May 14, 2014
    Hi, Does anyone know what is the resource url to access the files and folders for OneDrive for Business. Many Thanks

  • Anonymous
    May 30, 2014
    In step two, can we send the users email address as a param to auto-populate this login request? In my application, once entering the email here, it redirects to their adfs install, so I am trying to automate this step.

  • Anonymous
    May 30, 2014
    Yes, simply add "login_hint" to the URL e.g. GET login.windows.net/.../authorize

  • Anonymous
    June 03, 2014
    Making a GET request to "outlook.office365.com/.../Messages" sending Headers {    client-request-id: 'b81b2074-c34e...',    Authorization: 'Bearer eyJ0eXAiOiJK...',    Accept: 'application/json;odata.metadata=full',    return-client-request-id: true } Where client-request-id is a unique Guid and  Authorization has the base64 AccessToken I'm always having RESPONSE statusCode:  401 headers:  { server: 'Microsoft-IIS/8.0',  'request-id': 'e97ba485-b....',  'client-request-id': 'b81b2074-c34e....',  'x-ms-diagnostics': '2000001;reason="No applicable user context claims found.";error_category="invalid_token"',  'x-powered-by': 'ASP.NET',  'x-feserver': 'CO1PR06CA033',  'www-authenticate': 'Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000@*", error="invalid_token",Basic Realm=""',  date: 'Tue, 03 Jun 2014 23:44:57 GMT',  'content-length': '0' }

  • Anonymous
    June 04, 2014
    Please try the following: In the request capture the base64encoded AccessToken and copy&paste this into http://jwt.calebb.net to get the content of the token. Please respond with the content of the token and also with the complete client-request-id and/or request-id and the time of the request in UTC. Thank you! Matthias

  • Anonymous
    June 04, 2014
    Hi I have registered my app using "_layouts/15/appregnew.aspx". I haven't got an account in Windows Azure. I try to connect using oauth but I get an error. msdn.microsoft.com/.../jj687469%28v=office.15%29.aspx Array (    [error] => access_denied    [error_description] => AADSTS65005: Resource 'myCLIENTID' does not exist or one of its queried reference-property objects are not present. Trace ID: 923debb6-0391-4d17-93bd-b400bb79e5cb Correlation ID: 7816531f-776e-4347-9749-cd0fa3dc8eee Timestamp: 2014-06-05 12:40:40Z    [state] => 5fdfd60b-8457-4536-b20f-wrerr58d19458 ) Thank you.

  • Anonymous
    June 09, 2014
    { "typ": "JWT", "alg": "RS256", "x5t": "kriMPdmBvx68skT8-mPAB3BseeA" }. { "aud": "https://outlook.office365.com", "iss": "sts.windows.net/.../", "iat": 1402349572, "nbf": 1402349572, "exp": 1402353472, "ver": "1.0", "tid": "22c06f24-ee3c-4566-aca5-c905b92cc25c", "amr": [  "pwd" ], "altsecid": "1:live.com:000600009237F9AC", "idp": "live.com", "email": "narciso_sl7@hotmail.com", "given_name": "NARCISO", "family_name": "GUILLEN", "unique_name": "live.com#narciso_sl7@hotmail.com", "appid": "486248f0-f6d5-41da-97b8-eaee90bd69db", "appidacr": "1", "scp": "Contacts.Write Calendars.Write user_impersonation", "acr": "1" }. [signature]

  • Anonymous
    June 24, 2014
    How to get Client Secret? Azure Management Portal only shows Client Id.

  • Anonymous
    June 25, 2014
    Ok, got it, Need to generate keys in azure management portal. Keys = Client Secret Thanks

  • Anonymous
    June 26, 2014
    Is it possible to send an authorization request to an API (with the username /password) and get the authentication code without the user having to go in to login.windows.net/.../wsfederation ? We got an in house background application which syncs data between mailbox contacts. We are using a service account and we know the password for that account.    

  • Anonymous
    June 30, 2014
    There is no way in the code flow to avoid username/password. We're working on a client credential flow for later this fall that will give you the functionality required to run background services. For this you will not need a username/password, but the application will directly assert its identity and authenticate as itself.

  • Anonymous
    June 30, 2014
    Hi Matthias, Thanks for your comment. Do you know if this feature will be available sometime soon? My problem with the Token system is that for some reason (network issues etc) if we cannot refresh the token within the time frame, the background application will fail and needs to wait till the user enters the password again. Will the new method be a trusted certificate system between the application and office365? Thanks.

  • Anonymous
    July 01, 2014
    Exchange will support the client credential flow in Office 365 as documented here: msdn.microsoft.com/.../dn645543.aspx. We're looking to have this ready in the 4th quarter of this year. The code flow [that we currently support] works well for web apps that implement some form of user interaction. Then you can build some form of experience for the user to signal that something is wrong with the refreshtoken to fix the situation. For unattended background apps such as service accounts the code flow is not the best approach. Client credential flow will cover this scenario better. Hope this helps. Matthias

  • Anonymous
    July 01, 2014
    Thanks for this, this will help us.

  • Anonymous
    July 01, 2014
    Is there a way to get the Tokens etc in XML format rather than the JSON format in POST requests to    login.windows.net/.../token ? Thanks.

  • Anonymous
    July 01, 2014
    I'm having trouble with step 2... First problem, its returning "session_state" instead of "state". I think this breaks the spec? Second problem, it seems to ignore the state I do pass and return a random new one.

  • Anonymous
    July 01, 2014
    In the redirect that comes back from AAD after your app does the authorize call, it should look similar to: https://**.azurewebsites.net/?code=AwABAAomitted for brevity5Ni9IAA&state=8b2a6bbb-69c1-40c5-ba4d-ad3e393a2a48&session_state=160f2840-8763-4324-9e2d-74d1e7f4db17 It has "state" that the app submits and session_state. Use only "state" to verify. I just tried with my web app and it seems to do exactly this. Is this not what you see?

  • Anonymous
    July 01, 2014
    All AccessTokens to Exchange Office 365 APIs are JWT format. Even if you manage to get a XML encoded token in response, our services would not be able to parse it and will 401 with "invalid_token".

  • Anonymous
    July 17, 2014
    The comment has been removed

  • Anonymous
    July 17, 2014
    Just to add more info on the above post "Thushara 17 Jul 2014 3:43 PM", I have checked the network traffic on my call back URL Port and it shows some unsuccessful HandShakes going on. I have uploaded a self signed certificate to the Azure Management Certificates section. Is this the correct place to set the certificate for push notifications ? Will a self signed certificate work for push notifications ? Thanks.

  • Anonymous
    August 05, 2014
    Hi Matthias Thank you for this tutorial. I followed each of your step and I was able to authentication and also get the calendar events for the user from o365. I have a doubt. Is there anyway to get the events of all the users that are there in the organization and also can I get the events without using oauth token...using something like app token? Is it there for O365? Thanks Gopika.

  • Anonymous
    August 07, 2014
    App Tokens is something we want to support in the next few month. Right now we only supported delegation flows where an application acts-on behalf of a specific user for a set of permissions. As part of this flow we limit access to the mailbox of the authenticated user (as expressed in the token). App Tokens will directly authenticate the app and when available will allow your app to get to all events of all users (if an administrator consented so). Hope this helps, Matthias

  • Anonymous
    August 11, 2014
    Thanks Matthias. I am not sure if I understood you properly. My need was to get calendar events while a cron runs. Here we are not able to use user token right. So I saw something called grant type client credentials. Does that help me in this context? But when I tried to get the access token in POSTMAN using client_credentials, it is giving me Request method not allowed error. Any ideas? Thanks Gopika

  • Anonymous
    August 12, 2014
    Hello there,                Is there a way I can get list of all the users in an Office365 domain using administrative credentials?

  • Anonymous
    August 13, 2014
    Hi Jude, yes. You can use the AAD Graph API to get a list of users. You need to configure your application for Directory.Read permissions. More info see: msdn.microsoft.com/.../jj126255.aspx. Thank you! Matthias

  • Anonymous
    August 13, 2014
    Hi Gopika, we are working on supporting the client credential flow as described in "msdn.microsoft.com/.../dn645545.aspx" for later this year. This is essentially an app-only call to our Rest services. Thank you! Matthias

  • Anonymous
    August 14, 2014
    Thank You Matthias. Waiting for it

  • Anonymous
    September 10, 2014
    Hi Matthias, Is there any update regarding the client credential flow support? And will it be available for the Files REST API? Cheers Al

  • Anonymous
    September 16, 2014
    No update yet regards Exchange support for client credential flow. Still working on it. I plan to post another blog as soon as this is complete.

  • Anonymous
    September 24, 2014
    Hi Matthias, Thank you so much for posting this article.. This is really important for the project that I am currently working on. Regards, K.K.Kushan Randima Bsc .(Hons). Software Engineer Davton Ltd

  • Anonymous
    October 07, 2014
    Where to get the Client Secrete for my app. I Have create a web based app. I am able to see only Client-id.

  • Anonymous
    October 23, 2014
    Matthias has what you reference below been completed as yet ? Thanks. "Hi Gopika, we are working on supporting the client credential flow as described in "msdn.microsoft.com/.../dn645545.aspx" for later this year. This is essentially an app-only call to our Rest services."

  • Anonymous
    November 04, 2014
    I am having trouble retrieving data using the Office365 API. I have a Java service application which has no user interface which needs to retrieve data from Office365. I registered the app in Azure and received a Client ID and Client Key. I am able to successfully invoke the "login.windows.net/<tenant ID>/oauth2/token" URL and receive a valid access token. However, when I then take that access token and add a "Authorization: Bearer <access token>" header and make a call to "xyzdomain-my.sharepoint.com/.../" , I get the following error: "x-ms-diagnostics →3001000;reason="There has been an error authenticating the request.";category="invalid_client"" Any idea how I can resolve this ?

  • Anonymous
    November 04, 2014
    Client credential flow aka "App-Only" for service apps is not yet available on the Office 365 Rest APIs. We're targeting about end of the year to have this deployed in production.

  • Anonymous
    November 17, 2014
    The comment has been removed

  • Anonymous
    December 07, 2014
    I am trying to create an app to allow any user to connect to their Office365 account and browse their contacts with the Graph API's. After struggling a lot, I found your article and tried to add some of the information you suggest to add, like state and resource in the authorization request, but the result is always the same: when I try to access a resource on the Graph API, I get a 401 error. I wonder if I am trying to do something that it is not possible to do.

  • Anonymous
    January 08, 2015
    i'm currently working on an application that uses the older SOAP/XML Exchange webservices and the autodiscovery mechanism to access data. Is the possibility of using the oAuth "client credetial flow" also planned for these APIs? And is there a timeframe when this will be possible? Currently i can request an oAuth access token and add it in the "Authorization: Bearer" HTTP Header but i still receive 401 response codes, so it seems that the token is ( not yet ? ) accepted as authentication option.

  • Anonymous
    January 09, 2015
    @Georg: Yes, this should work. You can actually do something like: "exchangeService.Credentials = new OAuthCredentials(authenticationResult.AccessToken);" where authenticationResult is the result of using ADAL to aquire the token. Can you capture the x-ms-diagnostics response header for more details why it fails please. Also when you decode the token at http://jwt.calebb.net if you could check what is in the "scp" claim. EWS only works when full mailbox permissions are requested. EWS Soap does not support granular permissions like the Rest APIs do.

  • Anonymous
    January 09, 2015
    @Paolo: That is possible. The app needs to request Directory read rights, and then you do a request against "string api = String.Format("{0}{1}/users?api-version=2013-04-05", appConfig.GraphResourceUri, tenantId);", where appConfig.GraphResourceUri is "graph.windows.net/" and tenantId is the ID of the tenant of the directory you like to browse. Note that directory read permissions can only be given by an admin, so your app needs to pass "prompt=admin_consent" with the authorize request.

  • Anonymous
    January 09, 2015
    @Andrew: Client Credential flow is available now. I am currently working on a blog that describes how-to. Hopefully I have this done soon. Stay tuned :-)

  • Anonymous
    January 21, 2015
    @Matthias: I have been a quiet lurker, greatly anticipating the release of the above mentioned blog. I feel like a cat on its ninth life with curiosity waiting to finish me off! :) Any idea when the magical beast of Client Credential Flow Blog Post will be unleashed? Thanks for all the hard work on these APIs for us!

  • Anonymous
    January 30, 2015
    Hi! I was able to obtain a token via client_credentials flow but this token s not a correct one - according the x-ms-diagnostics header, it has too low protection level, 1 instead of 2. Registered my app via direct access to Office365 AD account by Visual Studio "Add connected service" feature. Can't use acess code flow because it does not work in sandboxed frame for me... (windowopen returns undefined (and even totally replaced by MS). Guess it related to some error messages in chrome cosole abount PostMessage failures. In sandboxed iframe request that works well in normal browser window, with itemId in request url, are result to 404.11 (double escaping) (were able to test it in only in chrome). Thanks for help.

  • Anonymous
    February 07, 2015
    @Zeus, than you! It is finally there. Sorry it took a bit longer. I also wrote a sample web app using this on git. The git link is in the post. Have fun! blogs.msdn.com/.../10587970.aspx @Konstantin. You cannot currently register certificates with your app in other way than directly through the manifest in the app registration in Windows Azure portal (see my blog on step-by-step how to do this). We hope we can improve on this in the future.

  • Anonymous
    February 08, 2015
    Hi is there a way to get the calendar mail and contact details of a user by using the access token of the admin when i give that prompt= admin_consent ?

  • Anonymous
    March 09, 2015
    Hi I am trying to use the JS client library sample code to access a logged in user's contacts and email and fill in a table for him to select. Could you point me to a sample code / existing implementation where I can have a look ? Or if you can help me in the current thing where I am stuck - This below function is what I have added so far. This function gets called when a user clicks on 'Outlook' on our site. But the console here displays an error - O365Auth is not defined which is understandable. But I am not able to get how and where to define the auth. And since mine is a simple website, would the user get redirected to microsoft for loggin in or can that be done in the form of a popup?      // Authenticate with Outlook      function authOutlook() { $button = $("#outlook-login-button"); $button.off("click"); var organizerContact = []; var authContext; var authToken; // for use with creating an outlookClient later. authContext = new O365Auth.Context(); authContext.getIdToken("outlook.office365.com/")  .then((function (token) {  authToken = token;  // The auth token also carries additional information. For example:      userName = token.givenName + " " + token.familyName;  }).bind(this), function (reason) {  console.log('Failed to login. Error = ' + reason.message);  });   /* var outlookURL = "outlook.office365.com/.../contacts"; $.ajax({ url:outlookURL, method:"GET", dataType: 'jsonp', success:function(response){ console.log('Get request response - '+response); } }); / var outlookClient = new Microsoft.OutlookServices.Client('outlook.office365.com/.../v1.0&, authToken.getAccessTokenFn('https://outlook.office365.com')); outlookClient.me.contacts.getContacts().orderBy('DisplayName asc').fetch().then( function (result) { result.currentPage.forEach(function (contact) { console.log(contact.displayName); contact.emailAddresses.forEach(function(emailAddress) { console.log('  ' + emailAddress.address); }); }); }, function(error) { console.log(error); } );      }  

  • Anonymous
    April 16, 2015
    Hi I'm trying to use this mechanism to authenticate in IMAP client. I get an access token on google and outlook.com and using it on IMAP client and it works fine, but in office 365 outlook it doesn't work. This auth mechanism can be used only on API or it can be used in IMAP? And MS supports office 365 oauth2 in imap?

  • Anonymous
    April 20, 2015
    I found issue. Office 365 Outlook not support OAuth authentication using IMAP. OAuth using only for API.

  • Anonymous
    May 19, 2015
    Hi Matthias, Thank you for the article. Could you please confirm something for me. I understand that all of there solutions require a web browser and a user to authenticate in the browser? Is there a authentication solution where now browser interaction is required? I want to simply have a back office service that creates and deletes events in users calendars without them having to grant me access. Thank you.

  • Anonymous
    May 22, 2015
    Hi Karol, client credential flow does not require a web app for the runtime of your service. The part that requires a web experience right now is the installation of the service app into a tenant in case your service is a multi-tenant service that other companies can acquire. This acquisition of the service app into another tenancy is web driven so an admin of the other organization must "consent" that this app is allowed as a service app in the organization. Note in case you build a service for only one single tenant, this is not required. Meaning if the service runs in the same organization/tenant that the service is registered as an app (by the admin of the org) then no additional steps are necessary. Does this help? Thanks, Matthias

  • Anonymous
    June 21, 2015
    Hi, I have followed your advice exactly. Got auth token, then access token for exchange apis. But when tying to do a get to a resource, say contacts, or mail or anything, I keep getting a 401 unauthorized. I have double, triple, quadruple checked the form of the GET making sure that everything is correct but getting nowhere. I have researched heaps of info online but to no avail. I'm absolutely stumped as to why I cannot use my Good access token to access to API endpoints. Not sure if anyone else is facing this, but this has pretty much taken up a whole day and still going no-where. Any help would be greatly appreciated.

  • Anonymous
    August 05, 2015
    I've gotten all of this to work for one specific users.  What I'm trying to do it give one super-user access to everyone's email.  No matter what permissions I give the user in the Azure configurations or in their unique Office365 profile I cannot get past the 403 error. Any tips?  Thanks!

  • Anonymous
    August 12, 2015
    Hello, I'm using next scopes for requesting access_token: [u"openid", u"outlook.office.com/Mail.ReadWrite"]. But in response from u'https://login.microsoftonline.com' I don't see refresh_token! Should I add another scope for retrieving it?

  • Anonymous
    September 11, 2015
    Hello, can i limit login with specified domain email only. I want to give only access to certain email with my domain name. Please sugges

  • Anonymous
    October 18, 2015
    Hello Matthias, Im having the same problem as Anton above me, that is that I dont get a refresh token, only a access token, can you help me out? Greetings, Konstantin

  • Anonymous
    October 19, 2015
    The comment has been removed

  • Anonymous
    November 06, 2015
    Hello Matthias, Can you please provide any help/links for implementing App Tokens....is it relased in new version ;  i can see the Last updates[response on 7 Aug 2014 3:39 PM to Gopika ] from you that , it will be released soon..

  • Anonymous
    November 11, 2015
    Can you read events from Shared Mailboxes using this? I keep getting Access Denied errors when trying to access a shared mailbox

  • Anonymous
    November 17, 2015
    Like Daniel I also would really appreciate any advice on how to access a Shared Mailbox as I get 403 Forbidden

  • Anonymous
    February 29, 2016
    Same is the case with me. Can any one please let me know is there a possibility to access shared calendar events using outlook rest api.

  • Anonymous
    March 03, 2016
    The "here" link in "Step One: Registering your application" is broken.

    • Anonymous
      March 28, 2016
      Thanks Andrew! I'll update it with Azure's new link.
  • Anonymous
    March 03, 2016
    Hi , I was looking to integrate Outlook calendar API in my Project,Just I want to check Create Event , Delete Event and Update Event with Developer Console first Like Google Have There Google Developer Console.We can check Google Calendar API using It,like same way Can we have console for test Outlook Calendar API?Thanks in Advance.

    • Anonymous
      March 28, 2016
      Currently our OAuth Sandbox allows you to test GET requests. We're updating it to support POST, PATCH and DELETE so that you can test the other operations, so this should be available to you soon.
  • Anonymous
    March 09, 2016
    We are developing an app that syncs user's emails and calendar events through subscription mechanism. We are facing a strange issue that revokes the user's refresh token after 14 days. We are also using the updated refresh token every time we receive it. It only happens for few users and works for others. We are also kind of sure that passwords were not changed by those users for whom we lost refresh tokens. In short the refresh token expiration seems to be a bit inconsistent.

    • Anonymous
      March 28, 2016
      Sorry to hear that! If you're sure that you're updating your stored refresh token every time you get a new token, could you please post details on Stack Overflow and tag it with the "azure" tag?
  • Anonymous
    May 02, 2016
    Hi Matthias,I manage to authenticate properly to O365 when the user is a regular user. However, when the user is a federated user the authentication fails. What has to be done differently?Regards,Doron

  • Anonymous
    May 03, 2016
    The comment has been removed

  • Anonymous
    May 24, 2016
    Hello I´m Max software engineer at Avantica. I´m develop a java web app and I need use our domain as login authentication and then read some emails from our inbox. How can I use the EWS with java I saw some examples using tokens but I need more details. Thanks in advance...!

  • Anonymous
    April 11, 2017
    I've registered one app. But on triggering the authorization flow, I receive this error - Additional technical information: Correlation ID: d5a2b2ac-9624-49a0-b630-3eb0bdd5dd57 Timestamp: 2017-04-11 11:15:55Z AADSTS90093: This application requires application permissions to another application. Consent for application permissions can only be performed by an administrator. Sign out and sign in as an administrator or contact one of your organization's administrators. Can you please help in resolving this?

    • Anonymous
      April 11, 2017
      It sounds like you registered for app permissions rather than delegated permissions. You'll need to fix up your registration or create a new one. If you can't figure it out please post on Stack Overflow.