使用 App Model V2 访问日历

Using App Model V2 to get access to calendar

我们在 Azure 的 ASP.NET 上有一个网络应用程序,我们想要访问当前用户的日历以显示今天的事件和未读电子邮件的数量。我们有使用 graph.microsoft.com 的应用程序,默认 "Work or School Account" 身份验证是使用 Visual Studio 创建的,但这不适用于 App Model V2。

如何构建能够使用 App Model V2 进行身份验证并访问 graph.microsoft.com 的应用程序?

您需要使用 Microsoft.IdentityModel.Clients.ActiveDirectory;

一个好的样品在 https://azure.microsoft.com/en-us/documentation/articles/active-directory-appmodel-v2-overview/

App Model V2 应用程序需要执行的步骤是:

  1. 使用 https://apps.dev.microsoft.com 上的应用程序注册门户注册您的应用程序。请记住为您注册的 clientID 和 clientsecret。
  2. 在 VS2015 中创建一个 asp.net 无需身份验证(匿名)
  3. 添加 Nuget 包Microsoft.IdentityModel.Clients.ActiveDirectory
  4. 添加使用Microsoft.IdentityModel.Clients.ActiveDirectory到控制器
  5. 您需要将范围添加到您的代码作为私有成员

私有静态字符串[]范围={ “https://graph.microsoft.com/calendars.readwrite”};

  1. Add 添加以下设置到 web.config

    <add key="ida:ClientID" value="..." />
    <add key="ida:ClientSecret" value="..." />
    
  2. 您必须创建 2 个额外的方法。一个用于登录,一个用于授权:

登录:

        public async Task<ActionResult> SignIn()
    {
        string authority = "https://login.microsoftonline.com/common/v2.0";
        string clientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"];
        AuthenticationContext authContext = new AuthenticationContext(authority);

        // The url in our app that Azure should redirect to after successful signin
        Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));

        // Generate the parameterized URL for Azure signin
        Uri authUri = await authContext.GetAuthorizationRequestUrlAsync(scopes, additionalScopes, clientId,
            redirectUri, UserIdentifier.AnyUser, null);

        // Redirect the browser to the Azure signin page
        return Redirect(authUri.ToString());
    }

授权:

        public async Task<ActionResult> Authorize()
    {
        // Get the 'code' parameter from the Azure redirect
        string authCode = Request.Params["code"];

        string authority = "https://login.microsoftonline.com/common/v2.0";
        string clientId = System.Configuration.ConfigurationManager.AppSettings["ida:ClientID"];
        string clientSecret = System.Configuration.ConfigurationManager.AppSettings["ida:ClientSecret"];
        AuthenticationContext authContext = new AuthenticationContext(authority);

        // The same url we specified in the auth code request
        Uri redirectUri = new Uri(Url.Action("Authorize", "Home", null, Request.Url.Scheme));

        // Use client ID and secret to establish app identity
        ClientCredential credential = new ClientCredential(clientId, clientSecret);

        try
        {
            // Get the token

            var authResult = await authContext.AcquireTokenByAuthorizationCodeAsync(
                authCode, redirectUri, credential, scopes);

            // Save the token in the session
            Session["access_token"] = authResult.Token;
            return Redirect(Url.Action("Tasks", "Home", null, Request.Url.Scheme));
        }
        catch (AdalException ex)
        {
            return Content(string.Format("ERROR retrieving token: {0}", ex.Message));
        }
    }

accestoken 处于会话状态。

现在您可以使用正确的访问令牌调用 graph.microsoft.com 并获取数据:

        private async Task<List<DisplayEvent>> GetEvents()
    {
        List<DisplayEvent> tasks = new List<DisplayEvent>();

        HttpClient httpClient = new HttpClient();
        var accessToken = (string)Session["access_token"];

        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        HttpResponseMessage response = await httpClient.GetAsync("https://graph.microsoft.com/beta/users/me/events");

        if (response.IsSuccessStatusCode)
        {
            string s = await response.Content.ReadAsStringAsync();
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            EventModels eventList = serializer.Deserialize<EventModels>(s);

            foreach (EventModel v in eventList.value)
            {
                //Fill tasks will events
            }
        }
        return tasks;
    }