在 outlook 加载项中实施 outlook 日历 api

Implement outlook calendar api in outlook add-in

我正在尝试在 Outlook 365 加载项中实施 Office365 Outlook 日历 API。 Outlook 日历 API 已在 Web 应用程序中完全实现。 OAuth2 和 Web 应用程序中返回的 auth_token 一切正常。

我在加载项中使用 OAuth2 登录时遇到问题。如果您在加载项中打开 Microsoft 的 OAuth2-Login,它会在您输入您的 appdev****@outlook[dot]com 帐户后打开一个 Internet Explorer 实例。这不适用于会话中保存的 auth_token。

我试图将 auth_token 保存在数据库中(参见 //测试部分)并在加载项中为用户请求它。此错误带有 DataServiceClientExceptionUnauthorized 未知位置。

    [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));
        }
    }

新答案 这是Officeadd-in新一代(以前的App for Office)和OAUTH认证的通病。 add-in 在沙盒 iFrame 中运行的事实强制在弹出窗口 window 中进行身份验证。在父级(沙盒 iFrame)window 中检索身份验证令牌也存在一些问题,因为在此上下文中禁止框架通信。 我提出了一个解决方案here but the best solution comes from Richard DiZerega and is proposed here。 据我了解,您尝试将 auth_token 保存在数据库中,以便稍后 iFrame add-in 会请求它。它与理查德·迪泽雷加 (Richard DiZerega) 的提议不符。

旧的错误答案 您遇到此问题是因为您可能将 Azure AD 应用程序注册为 Web 应用程序。现在您正在使用没有任何 'url location' 的本机客户端请求它,这就是失败的原因。

native client 有不同的身份验证方案。

我认为这没什么大不了的,只是 register another app 在您的 Azure AD 中用于本机客户端(这是您创建应用程序时提出的第一个问题)。