2

我正在尝试使用预定义的 Microsoft 帐户用户名和密码访问 Outlook 365 任务 API,我将在配置文件中输入这些用户名和密码。

目前我的应用程序正在使用重定向到微软登录页面

    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 很陌生,所以我还在学习。:)

任何想法都非常感谢。

先感谢您。

4

1 回答 1

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)。

于 2018-07-27T07:30:14.907 回答