Azure Active Directory中的简单目录查找

时间:2016-07-08 20:44:44

标签: azure azure-active-directory microsoft-graph

我正在编写一个简单的桌面应用程序,需要从Microsoft的目录中检索有关用户的一些基本属性。具体做法是:

  1. 我正在编写单个租户本机LOB应用程序。
  2. 应用程序在我的桌面上运行。
  3. 该应用程序以我登录的域帐户运行。
  4. 组织'域帐户同步到AAD。
  5. 我没有尝试保护本机Web应用程序或Web API或类似的东西。我不需要用户登录。
  6. 我通过外部事件管理工具拥有组织中人员的电子邮件地址。我需要根据电子邮件地址从AAD查找AAD帐户个人资料数据(地址簿信息 - 特别是职位名称)。我只会阅读AAD数据。
  7. 到目前为止,我已完成以下工作: -

    1. Azure AD Graph API似乎是获取配置文件信息的正确方法。特别是,该信息可在端点获得:https://graph.windows.net/ {tenant} / users / {email}?api-version = 1.6

    2. 在AAD中注册本机应用程序时,未提供任何密钥。所以我没有客户的秘密。

    3. 在这里查看GitHub中的示例:https://github.com/Azure-Samples/active-directory-dotnet-graphapi-console。这里的说明似乎是错误的,因为没有Keys部分可用[见(2)]。

    4. 基于上面的示例,我写了一个简单的函数。代码如下:

          private static async Task PrintAADUserData(string email)
          {
              string clientId = "0a202b2c-6220-438d-9501-036d4e05037f";
              Uri redirectUri = new Uri("http://localhost:4000");
              string resource = "https://graph.windows.net/{tenant}";
              string authority = "https://login.microsoftonline.com/{tenant}/oauth2/authorize";
              AuthenticationContext authContext = new AuthenticationContext(authority);
      
              AuthenticationResult authResult = await authContext.AcquireTokenAsync(resource, clientId, redirectUri, new PlatformParameters(PromptBehavior.Auto));
      
              string api = String.Format("https://graph.windows.net/{tenant}/users/{0}?api-version=1.6", email);
              LOG.DebugFormat("Using API URL {0}", api);
      
              // Create an HTTP client and add the token to the Authorization header
              HttpClient httpClient = new HttpClient();
              httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(authResult.AccessTokenType, authResult.AccessToken);
              HttpResponseMessage response = await httpClient.GetAsync(api);
      
              string data = await response.Content.ReadAsStringAsync();
              LOG.Debug(data);
          }
      

      问题

      1. 运行时的应用程序能够启动身份验证页面。我为什么需要那个?该应用程序已作为我的域帐户运行。是否需要额外的身份验证?如果我在Azure中将此应用程序作为工作进程运行,那么我就不想使用我的域凭据。

      2. 主要问题似乎是资源网址错误。访问Azure AD Graph API需要指定哪些资源?

      3. 谢谢,

        Vijai。

        EDITS

        根据@Saca的评论,代码和应用程​​序已经过编辑。

        代码

        string clientId = ConfigurationManager.AppSettings["AADClientId"];
        string clientSecret = ConfigurationManager.AppSettings["AADClientSecret"];
        string appIdUri = ConfigurationManager.AppSettings["AADAppIdURI"];
        string authEndpoint = ConfigurationManager.AppSettings["AADGraphAuthority"];
        string graphEndpoint = ConfigurationManager.AppSettings["AADGraphEndpoint"];
        
        AuthenticationContext authContext = new AuthenticationContext(authEndpoint, false);
        AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.windows.net", new ClientCredential(clientId, clientSecret));
        ExistingTokenWrapper wrapper = new ExistingTokenWrapper(authResult.AccessToken);
        ActiveDirectoryClient client = new ActiveDirectoryClient(new Uri(graphEndpoint), async () => await wrapper.GetToken());
        
        IUser user = client.Users.Where(_ => _.UserPrincipalName.Equals(email.ToLowerInvariant())).Take(1).ExecuteSingleAsync().Result;
        

        应用 AAD Application Permissions Setup 错误 未处理的异常:System.AggregateException:发生一个或多个错误。 ---> System.AggregateException:发生一个或多个错误。 ---> Microsoft.Data.OData.ODataErrorException:没有足够的权限来完成操作。 ---> System.Data.Services.Client.DataServiceQueryException:处理此请求时发生错误。 ---> System.Data.Services.Client.DataServiceClientException:{" odata.error":{" code":" Authorization_RequestDenied"," message": {" lang":" zh","价值":"没有足够的权限来完成操作。"}}}

        看来,尽管提供了正确的权限,正确的资源并且能够获取令牌,但仍然存在缺失。

3 个答案:

答案 0 :(得分:1)

此处需要考虑的关键是,如果您的应用程序是无人机客户端,则由用户在其计算机上运行的安全服务器或桌面客户端运行。

如果是前者,则您的应用程序被视为机密客户端,并且可以信任秘密,即密钥。如果这是您的方案,即样本所涵盖的方案,那么您需要使用clientId和clientSecret。

您在应用程序的配置页面中没有看到 Keys 部分的最可能原因是,而不是选择 Web应用程序和/或Web API ,根据示例中的步骤#7,您在首次创建应用程序时选择了 Native Client Application 。此“类型”无法更改,因此您需要创建一个新的应用程序。

如果您的方案是后者,那么您的应用程序将被视为公共客户端,并且不能信任秘密,在这种情况下,您唯一的选择是提示用户输入凭据。否则,即使您的应用程序拥有自己的授权层,也可以轻松反编译并提取和使用秘密。

顺便说一句,您的资源网址是正确的。

答案 1 :(得分:0)

原来问题不在于代码。我不是AAD管理员。似乎任何需要在我们的租户中对AAD执行身份验证的应用程序都需要具有AAD管理员启用的权限。一旦他们为我的应用程序启用了权限(并获得了AAD注册的所有权),这就开始工作了。

答案 2 :(得分:0)

希望帮助一些使用GraphClient的人:

var userPriNam = "johndoe@cloudalloc.com";
var userLookupTask = activeDirectoryClient.Users.Where(
    user => user.UserPrincipalName.Equals(userPriNam, StringComparison.CurrentCultureIgnoreCase)).ExecuteSingleAsync();
User userJohnDoe = (User)await userLookupTask;

来自https://www.simple-talk.com/cloud/security-and-compliance/azure-active-directory-part-5-graph-api/