【问题标题】:Azure web AD graph api with adal version 2 nuget package带有 adal 版本 2 nuget 包的 Azure Web AD 图 api
【发布时间】:2017-03-08 11:29:30
【问题描述】:

我正在尝试使用 azure AD graph api 提取 azure 广告用户信息。 graph api 可以与 adal 2 nuget 包一起使用吗?

这个问题的原因是 我的 web 应用程序使用以下代码进行身份验证,并且仅适用于使用 Microsoft.IdentityModel.Clients.ActiveDirectory 的 Adal2x 版本。

但 Azure 广告图使用不同的方式来提取令牌,它仅适用于 adal3。AcquireTokenSilentAsync 是 adal3 的一部分。 AcquireTokenByAuthorizationCode 是 adal2 的一部分,用于在启动时进行身份验证。我必须同时使用身份验证和图形 api。是否有任何选项可以让用户使用 adal2x 版本的图形 api 来匹配两者?

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);
                        }
                    }
                });
        }

图形api代码

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);
        }

【问题讨论】:

  • 这个问题有什么更新吗?

标签: c# asp.net azure-active-directory azure-ad-graph-api


【解决方案1】:

根据测试,AcquireTokenSilentAsync 方法在版本2.28.3 中退出。并且在最新版本的 ADAL(3.13.8) 中,该方法是支持异步的。我们可以使用AcquireTokenByAuthorizationCodeAsync 代替AcquireTokenByAuthorizationCode。要使用这种方法,也可以参考代码示例active-directory-dotnet-webapp-webapi-openidconnect

但 Azure 广告图使用不同的方式来提取令牌,它仅适用于 adal3。AcquireTokenSilentAsync 是 adal3 的一部分。 AcquireTokenByAuthorizationCode 是 adal2 的一部分,用于在启动时进行身份验证。我必须同时使用身份验证和图形 api。是否有任何选项可以让用户使用 adal2x 版本的图形 api 来匹配两者?

Azure AD Graph 用于读取和修改租户中的用户、组和联系人等对象。我们如何获取令牌以使用此 REST API 并不重要。

Active Directory Authentication Library是帮助从Azure AD获取token的,但是不同版本有一些区别。更多ADAL发布版本详情,可以参考here

在您的场景中,ADAL 的 V2.0 和 V3.0 版本都应该可以工作。我建议你使用最新版本,因为它修复了旧版本中的几个错误。

【讨论】:

  • 谢谢 我了解了背景。使用此处的代码生成的令牌是否可以与 graphapi 一起使用? stackoverflow.com/questions/42662234/…
  • 我已经回答了这个问题,如果您还有问题,请随时告诉我。
  • Azure AD Graph REST 根据 access_token 验证请求。为确保您有权限读取该组的 ,您需要确保 access_token 中有Group.Read.All 权限。并且您需要在注册应用程序时在门户中配置此权限。请注意,此权限是委托权限。有关 Azure AD Graph 权限范围的更多详细信息,请参阅here
  • 它需要管理员同意该应用程序,然后可以登录该站点的每个人都可以使用此令牌调用 Azure AD Graph。如果您在 Azure 门户上注册应用程序,则默认已授予权限。
  • 您是否为该应用授予了Group.Read.All 权限?您是否可以通过从this site 解码来检查此权限是否在 access_token 中?
猜你喜欢
  • 2018-10-11
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多