Azure web AD graph api with adal version 2 nuget p

2019-09-14 00:42发布

问题:

I am trying to pull azure ad user info using azure AD graph api. Will graph api work with adal 2 nuget packages?

Reason for this question is My webapplication is using below code in for auth and works only with Adal2x versions using Microsoft.IdentityModel.Clients.ActiveDirectory.

But Azure ad graph uses different way to pull token and it works only with adal3 .AcquireTokenSilentAsync is part of adal3. AcquireTokenByAuthorizationCode is part of adal2 for authentication on startup. I have to use both authentication and graph api. Is there any option to user graph api with adal2x version to match both?

public void ConfigureAuth(IAppBuilder app)
        {
            ApplicationDbContext db = new ApplicationDbContext();

            app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

            app.UseCookieAuthentication(new CookieAuthenticationOptions());

            app.UseOpenIdConnectAuthentication(
                new OpenIdConnectAuthenticationOptions
                {
                    ClientId = clientId,
                    Authority = Authority,
                    PostLogoutRedirectUri = postLogoutRedirectUri,

                    Notifications = new OpenIdConnectAuthenticationNotifications()
                    {
                        //If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                        AuthorizationCodeReceived = (context) =>
                        {
                            var code = context.Code;
                            ClientCredential credential = new ClientCredential(clientId, appKey);
                            string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                            AuthenticationContext authContext = new AuthenticationContext(Authority, new ADALTokenCache(signedInUserID));
                            //AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                            //code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
                            AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
                            code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId);
                            return Task.FromResult(0);
                        }
                    }
                });
        }

graph api code

public async Task<ActionResult> Index()
        {
            UserProfile profile;
            string tenantId = ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value;
            AuthenticationResult result = null;

            try
            {
                // Get the access token from the cache
                string userObjectID =
                    ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")
                        .Value;
                AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
                    new NaiveSessionCache(userObjectID));
                ClientCredential credential = new ClientCredential(clientId, appKey);

                result = await authContext.AcquireTokenSilentAsync(graphResourceId, credential,
                    new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));

                // Call the Graph API manually and retrieve the user's profile.
                string requestUrl = String.Format(
                    CultureInfo.InvariantCulture,
                    graphUserUrl,
                    HttpUtility.UrlEncode(tenantId));
                HttpClient client = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                // Return the user's profile in the view.
                if (response.IsSuccessStatusCode)
                {
                    string responseString = await response.Content.ReadAsStringAsync();
                    profile = JsonConvert.DeserializeObject<UserProfile>(responseString);
                }
                else
                {
                    // If the call failed, then drop the current access token and show the user an error indicating they might need to sign-in again.
                    authContext.TokenCache.Clear();

                    profile = new UserProfile();
                    profile.DisplayName = " ";
                    profile.GivenName = " ";
                    profile.Surname = " ";
                    ViewBag.ErrorMessage = "UnexpectedError";
                }
            }
            catch (Exception e)
            {
                if (Request.QueryString["reauth"] == "True")
                {
                    //
                    // Send an OpenID Connect sign-in request to get a new set of tokens.
                    // If the user still has a valid session with Azure AD, they will not be prompted for their credentials.
                    // The OpenID Connect middleware will return to this controller after the sign-in response has been handled.
                    //
                    HttpContext.GetOwinContext()
                        .Authentication.Challenge(OpenIdConnectAuthenticationDefaults.AuthenticationType);
                }

                //
                // The user needs to re-authorize.  Show them a message to that effect.
                //
                profile = new UserProfile();
                profile.DisplayName = " ";
                profile.GivenName = " ";
                profile.Surname = " ";
                ViewBag.ErrorMessage = "AuthorizationRequired";
            }

            return View(profile);
        }

回答1:

Based on the test, the AcquireTokenSilentAsync method is exited in version 2.28.3. And in the latest version of ADAL(3.13.8), the method is support asynchronous. We can use AcquireTokenByAuthorizationCodeAsync instead of AcquireTokenByAuthorizationCode. To use this method, you can also refer the code sample active-directory-dotnet-webapp-webapi-openidconnect.

But Azure ad graph uses different way to pull token and it works only with adal3 .AcquireTokenSilentAsync is part of adal3. AcquireTokenByAuthorizationCode is part of adal2 for authentication on startup. I have to use both authentication and graph api. Is there any option to user graph api with adal2x version to match both?

Azure AD Graph is used to read and modify objects such as users, groups, and contacts in a tenant. It doesn't matther how we accquire the token to use this REST API.

And the Active Directory Authentication Library is helped to acquire the token from Azure AD, but the difference version has some difference. More details about the release version of ADAL, you can refer here.

In your scenario, both V2.0 and V3.0 version of ADAL should work. I suggest that you use the latest version since it fixed the several bugs in the old version.