Office 365任务API-使用web.config C#中的固定用户凭据访问API

时间:2018-07-27 05:24:57

标签: c# asp.net-mvc-5 office365 azure-active-directory outlook-api

我正尝试使用预定义的Microsoft帐户用户名和密码访问Outlook 365任务api,并将其放入配置文件中。

当前,我的应用程序正在使用

重定向到microsoft登录页面
    HttpContext.GetOwinContext().Authentication.Challenge(
              new AuthenticationProperties { RedirectUri = "/" },
              OpenIdConnectAuthenticationDefaults.AuthenticationType);

然后我在当前已登录的用户上下文中获得令牌。

     string accessToken = await AuthProvider.Instance.GetUserAccessTokenAsync();
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("Authorization", "Bearer" + accessToken);

GetUserAccessTokenAsync()的片段

    string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
        HttpContextBase httpContextBase = HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase;

        SessionTokenCache tokenCache = new SessionTokenCache(signedInUserID, httpContextBase);
       Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext authContext = new Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext(SettingsHelper.Authority, tokenCache);
        ClientCredential clientCredential = new ClientCredential(SettingsHelper.ClientId, SettingsHelper.ClientSecret);

        string userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
        UserIdentifier userId = new UserIdentifier(userObjectId, UserIdentifierType.UniqueId);

        try
        {
            AuthenticationResult result = await authContext.AcquireTokenSilentAsync(SettingsHelper.OutlookResourceId, clientCredential, userId);
            return result.AccessToken;
        }
        catch (AdalException ex)
        {
            HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
                new AuthenticationProperties() { RedirectUri = "/" },
                OpenIdConnectAuthenticationDefaults.AuthenticationType);

           throw new Exception(ex.Message);
        }

但是我的目标是删除此登录名,而只需使用固定的管理员帐户即可访问api。

是否可以从与登录的用户凭证不同的用户凭证中获取令牌?

我正在尝试搜索示例,但找不到适合的示例。

我在使用API​​方面还很陌生,所以我还在学习。 :)

非常感谢任何想法。

谢谢。

1 个答案:

答案 0 :(得分:1)

第一个选择(也许是更安全的选择)将是小的入职流程,您可以通过该流程与管理员登录,获取管理员的刷新令牌,并将其存储在安全的地方。 然后,只要需要访问令牌,就可以使用刷新令牌。 虽然您必须记住要刷新刷新令牌,但它也会过期。 但是,每当您获得一个带有令牌的令牌时,都会获得一个新的刷新令牌,因此这不是问题。 与第二种方法不同,此方法的最大优点是它允许管理员帐户具有MFA等。

第二个选项是使用“资源所有者密码凭证授予”流程。 我相信ADAL.NET不会让您访问允许从机密客户端执行的AcquireTokenAsync重载,因此您必须手动进行HTTP调用才能获取令牌。

以下是ROPC的示例:

string tokenUrl = $"https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/token";
var req = new HttpRequestMessage(HttpMethod.Post, tokenUrl);

req.Content = new FormUrlEncodedContent(new Dictionary<string, string>
{
    ["grant_type"] = "password",
    ["client_id"] = "23d3be1b-a671-4452-a928-78fb842cb969",
    ["client_secret"] = "REDACTED",
    ["resource"] = "https://graph.windows.net",
    ["username"] = "testuser@mytenant.onmicrosoft.com",
    ["password"] = "REDACTED"
});

using (var client = new HttpClient())
{
    var res = await client.SendAsync(req);

    string json = await res.Content.ReadAsStringAsync();
}

HTTP请求:

POST https://login.microsoftonline.com/mytenant.onmicrosoft.com/oauth2/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: login.microsoftonline.com
Content-Length: 277
Expect: 100-continue
Connection: Keep-Alive

grant_type=password&client_id=23d3be1b-a671-4452-a928-78fb842cb969&client_secret=REDACTED&resource=https%3A%2F%2Fgraph.windows.net&username=testuser%40mytenant.onmicrosoft.com&password=REDACTED

ROPC的最大缺点是该用户帐户无法使用MFA,也不能成为联盟用户。 我个人更喜欢第一种选择,但它也有缺点。 刷新令牌可能由于某些原因而失效,其中之一是密码重置(尽管这也会影响ROPC)。