gpt4 book ai didi

asp.net-mvc - 如何从 HttpContext 获取 JWT(使用 OpenIdConnect),并将其传递给 Azure AD Graph API

转载 作者:行者123 更新时间:2023-12-02 15:58:10 29 4
gpt4 key购买 nike

背景

我们在 2016 年开发了一个使用 WS-Federation 进行身份验证的应用程序,以从本地 AD 获取声明。 IT 战略的方向已经改变,正在转向 Azure AD(当前托管混合环境)。

我们正在使用 OpenIDConnect 将身份验证从 WS-Fed 迁移到 AAD。使用新方法让用户登录并进行身份验证非常简单 - 正确进行配置,并发出身份验证质询,罗伯特是你母亲的兄弟。

问题

如果我的术语有误,请纠正我;我们需要从 Active Directory 中获取一些无法通过默认 JWT 访问的属性(据我所知)。因此,我们需要通过 HTTP 将 JWT 传递到 Graph API,以从 Active Directory 获取我们想要的属性。

我知道格式正确且经过身份验证的请求可以提取必要的数据,因为我已设法使用图形浏览器(AAD 浏览器,而不是 Microsoft Graph 浏览器)查看它。

问题

如果我上面的理解是正确的,我如何从 ASP.Net 中的 HttpContext 中提取 JWT?如果我正确掌握了所有这些较低级别的 HTTP 内容,我需要在 Graph API 请求的请求 header 中包含 JWT,并且我应该获得所需的 JSON 文档作为响应。

(编辑,为了 future 读者的利益:您实际上需要为您尝试访问的特定服务获取新 token ,在本例中为 Azure AD。您可以使用代表流来执行此操作,或使用作为应用程序流程)。

Request.Headers["IdToken"] 返回 null,所以我想知道这里出了什么问题。

代码这是在服务器启动时运行的身份验证配置:

    public void Configuration(IAppBuilder app)
{
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
//ConfigureAuth(app); //Old WsFed Auth Code

//start the quartz task scheduler
//RCHTaskScheduler.Start();

//Azure AD Configuration
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());


app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
//sets client ID, authority, and RedirectUri as obtained from web config
ClientId = clientId,
ClientSecret = appKey,
Authority = authority,
RedirectUri = redirectUrl,

//page that users are redirected to on logout
PostLogoutRedirectUri = redirectUrl,

//scope - the claims that the app will make
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.IdToken,

//setup multi-tennant support here, or set ValidateIssuer = true to config for single tennancy
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
SaveSigninToken = true
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed
}

}
);
}

这是我用于制作 GraphAPI 请求的部分完整代码:

        public static async Task<int> getEmployeeNumber(HttpContextBase context)
{

string token;
int employeeId = -1;
string path = "https://graph.windows.net/<domain>/users/<AAD_USER_ID>?api-version=1.6";


HttpWebRequest request = null;
request = (HttpWebRequest)HttpWebRequest.Create(path);
request.Method = "GET";
request.Headers.Add(context.GetOwinContext().Request.Headers["IdToken"]);
WebResponse response = await request.GetResponseAsync();
throw new NotImplementedException();

}

最佳答案

好吧,我花了几天时间才解决(以及来自 Juunas 的一些指示),但这绝对是可行的,只需对代码进行一些轻微的修改 here 。上述是微软的OpenId指南。

我绝对建议阅读您的具体内容 authentication scenario ,并查看相关示例。

以上内容将使您入门,但要从 Graph API 获取 JWT(不要与 Microsoft Graph 混淆),您需要在进行身份验证时获取身份验证代码,并将其存储在 token 缓存中.

您可以从 this 中获取可用的 token 缓存来自 Microsoft 的示例(MIT 许可证)。现在,就我个人而言,我发现这些示例与复杂的用例过于混淆,而实际上它们应该概述基础知识,但这只是我的情况。尽管如此,这些足以让您接近。

现在来看一些代码。请允许我提请您注意“ResponseType= CodeIdToken”。

public void ConfigureAuth(IAppBuilder app)
{
//Azure AD Configuration
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());


app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
//sets client ID, authority, and RedirectUri as obtained from web config
ClientId = clientId,
ClientSecret = appKey,
Authority = authority,
RedirectUri = redirectUrl,


//page that users are redirected to on logout
PostLogoutRedirectUri = redirectUrl,

//scope - the claims that the app will make
Scope = OpenIdConnectScope.OpenIdProfile,
ResponseType = OpenIdConnectResponseType.CodeIdToken,

//setup multi-tennant support here, or set ValidateIssuer = true to config for single tennancy
TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
//SaveSigninToken = true
},
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = OnAuthenticationFailed,
AuthorizationCodeReceived = OnAuthorizationCodeReceived,
}

}
);
}

提供上述参数后,在您进行身份验证时将运行以下代码:

        private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification context)
{
var code = context.Code;
ClientCredential cred = new ClientCredential(clientId, appKey);
string userObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
AuthenticationContext authContext = new AuthenticationContext(authority, new NaiveSessionCache(userObjectId));

// If you create the redirectUri this way, it will contain a trailing slash.
// Make sure you've registered the same exact Uri in the Azure Portal (including the slash).
Uri uri = new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult result = await authContext.AcquireTokenByAuthorizationCodeAsync(code, uri, cred, "https://graph.windows.net");
}

这将为您的 token 缓存提供可以传递给图形 API 的代码。从这里,我们可以尝试使用 Graph API 进行身份验证。

 string path = "https://graph.windows.net/me?api-version=1.6";
string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
string userObjectId = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
string resource = "https://graph.windows.net";
AuthenticationResult result = null;
string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);
ClientCredential cc = new ClientCredential(ConfigurationManager.AppSettings["ClientId"], ConfigurationManager.AppSettings["ClientSecret"]);
AuthenticationContext auth = new AuthenticationContext(authority, new NaiveSessionCache(userObjectId));
try
{
result = await auth.AcquireTokenSilentAsync(resource,
ConfigurationManager.AppSettings["ClientId"],
new UserIdentifier(userObjectId, UserIdentifierType.UniqueId)).ConfigureAwait(false);
}
catch (AdalSilentTokenAcquisitionException e)
{
result = await auth.AcquireTokenAsync(resource, cc, new UserAssertion(userObjectId));

}

获得身份验证 token 后,您可以通过 Http 请求将其传递到 Graph API(这是最简单的部分)。

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(path);
request.Method = "GET";
request.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + result.AccessToken);
WebResponse response = request.GetResponse();

System.IO.Stream dataStream = response.GetResponseStream();

从这里,您将拥有一个数据流,您可以将其传递到流读取器中,从中获取 JSON,并执行您想要的任何操作。就我而言,我只是查找目录中的用户数据,但不包含在 Azure AD 身份验证的默认声明中。所以就我而言,我调用的 URL 是

"https://graph.windows.net/me?api-version=1.6"

如果您需要更深入地了解您的目录,我建议使用 Graph Explorer 。这将帮助您构建 API 调用。现在,我再次发现 Microsoft 文档有点迟钝(如果您想了解一些巧妙的内容,请查看 Twilio API)。但一旦你弄清楚了,其实并没有那么糟糕。

编辑:此问题已从 Stack Overflow 获得“值得注意的问题”徽章。 请注意,这解决了此场景中 Azure AD Auth 的 ADAL 实现。您应该使用 MSAL,因为 ADAL 现已弃用!大部分是相同的,但在实现上存在一些关键差异。

关于asp.net-mvc - 如何从 HttpContext 获取 JWT(使用 OpenIdConnect),并将其传递给 Azure AD Graph API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51509182/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com