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

Office 365 Tasks API - access api using fixed user credentials in web.config C#

我正在尝试使用预定义的 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 方面还很陌生,所以我还在学习。 :)

非常感谢任何想法。

提前谢谢你。

第一个选项(也许是更安全的选项)是有一个小的入职流程,您可以通过该流程与管理员一起登录,为他们获取刷新令牌,并将其存储在安全的地方。 然后,您可以在需要访问令牌时使用刷新令牌。 尽管您必须记住刷新刷新令牌以及它也过期。 但是每次你获得一个令牌时你都会得到一个新的刷新令牌,所以应该不是问题。 这种方式最大的好处就是可以让admin账号拥有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)。