Background
We developed an application in 2016 that authenticated using WS-Federation, to grab claims from the on-premises AD. The direction of the IT strategy has changed, and is moving toward Azure AD (currently hosting a hybrid environment).
We're in the process of migrating the authentication from WS-Fed, to AAD, using OpenIDConnect. Getting the user signed in and authenticated with the new method was surprisingly straightforward - do the config properly, and issue the authenticate challenge, and Robert is your mother's brother.
The Problem
Please correct me if I'm getting my terminology wrong here; we need to grab some attributes from Active Directory that aren't accessible (as far as I can tell) via the default JWT. So, we need to pass the JWT to the Graph API, via HTTP, to get the attributes we want from active directory.
I know that a properly formatted and authenticated request can pull the necessary data, because I've managed to see it using the graph explorer (the AAD one, not the Microsoft Graph one).
The Question
If my understanding above is correct, how do I pull the JWT from the HttpContext in ASP.Net? If I've grasped all this lower level HTTP stuff correctly, I need to include the JWT in the request header for the Graph API request, and I should get the JSON document I need as a response.
(Edit, for the benefit of future readers: You actually need to acquire a new token for the specific service you're trying to access, in this case Azure AD. You can do this using the on-behalf-of flow, or using the as-an-application flow).
Request.Headers["IdToken"] is returning null, so I'm wondering what's going wrong here.
The Code Here's our Authentication config that runs on server startup:
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
}
}
);
}
Here's my partially complete code for crafting the GraphAPI request:
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();
}