我正尝试使用预定义的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方面还很陌生,所以我还在学习。 :)
非常感谢任何想法。
谢谢。
答案 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)。