I'm trying to implement the Office365 Outlook Calendar API inside the Outlook 365 Add-in. The Outlook Calendar API is fully implemented in the web application. Everything works fine with OAuth2 and the returned auth_token in the web application.
I'm having issues to sign in with OAuth2 inside the add-in. If you open the OAuth2-Login by Microsoft inside the add-in, it opens a Internet Explorer instance once you entered your appdev****@outlook[dot]com-account. This does not work with the auth_token saved in the session.
I tried to save the auth_token in a database (see //Test part) and request it for the user inside the add-in. This errors with a DataServiceClientException: Unauthorized Unknown location.
[Route("SignIn")]
public async Task<ActionResult> SignIn()
{
string authority = "https://login.microsoftonline.com/common";
string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
AuthenticationContext authContext = new AuthenticationContext(authority);
Uri redirectUri = new Uri(Url.Action("Authorize", "outlook", null, HttpContext.Request.Scheme));
Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, null, clientId,
redirectUri, UserIdentifier.AnyUser, null);
return Redirect(authUri.ToString());
}
[Route("Authorize")]
public async Task<ActionResult> Authorize()
{
string authCode = Request.Query["code"];
string authority = "https://login.microsoftonline.com/common";
string clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string clientSecret = "xxxxxxxxxxxx";
AuthenticationContext authContext = new AuthenticationContext(authority);
Uri redirectUri = new Uri(Url.Action("Authorize", "outlook", null, HttpContext.Request.Scheme));
ClientCredential credential = new ClientCredential(clientId, clientSecret);
try
{
var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
authCode, redirectUri, credential, scopes);
HttpContext.Session.SetString("access_token", authResult.Token);
HttpContext.Session.SetString("user_email", GetUserEmail(authContext, clientId));
//*** TEST ***
_dbContext.ApplicationUsers.FirstOrDefault(e => e.Email == "appdev****@outlook.com").AccessToken = authResult.Token;
_dbContext.ApplicationUsers.FirstOrDefault(e => e.Email == "appdev****@outlook.com").Email = GetUserEmail(authContext, clientId);
return Content("Access Token: " + authResult.Token + " Email: " + GetUserEmail(authContext, clientId));
}
catch (AdalException ex)
{
return Content(string.Format("ERROR retrieving token: {0}", ex.Message));
}
}
New answer This is a common problem with Office add-in new generation (formerly App for Office) and OAUTH authentication. The fact that the add-in runs in a sandboxed iFrame force the authentication to be made in a popup window. There are also some problems to retrieve the auth token in the parent (sandboxed iFrame) window because frame communications are forbidden in this context. I proposed a solution here but the best solution comes from Richard DiZerega and is proposed here. From what I have understood, you try to save the auth_token in a database so it will be requested by the iFrame add-in later on. It is closed to what Richard DiZerega proposes.
Old mistaken answer You are facing this issue because you probably registered you Azure AD app as a web application. Now you are requesting it with a native client without any 'url location' that is why this is failing.
There is a different authentication scenario for native client.
I think this is no big deal just register another app in your Azure AD for native client (this is the first question asked when you create an app).