azure - Azure Active Directory 中的简单目录查找

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

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

  1. 我正在编写一个单租户 native LOB 应用程序。
  2. 该应用程序在我的桌面上运行。
  3. 应用程序以我登录的域帐户运行。
  4. 组织的域帐户已同步到 AAD。
  5. 我并不是想保护 native Web 应用程序或 Web API 或类似的东西。我不需要用户登录。
  6. 我通过外部事件管理工具获得了组织内人员的电子邮件地址。我需要根据电子邮件地址从 AAD 查找 AAD 帐户个人资料数据(地址簿信息 - 特别是职位名称)。我只会读取 AAD 数据。

到目前为止,我已经完成了以下操作:-

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

  2. 在 AAD 中注册 native 应用程序时,未提供 key 。所以我没有客户 secret 。

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

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

    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. 主要问题似乎是资源 URL 错误。我需要指定什么资源才能访问 Azure AD Graph API?

谢谢

维杰。

编辑

根据@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":"en","value":"权限不足完成操作。"}}}

看来,尽管提供了正确的权限、正确的资源并能够获取 token ,但仍然缺少一些东西。

最佳答案

这里要考虑的关键是您的应用程序是否是从安全服务器运行的 headless 客户端,或者是由用户在其计算机上运行的桌面客户端。

如果是前者,那么您的应用程序将被视为 secret 客户端,并且可以通过 secret (即 key )来信任。如果这是您的场景,也就是示例所涵盖的场景,那么您需要使用 clientId 和 clientSecret。

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

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

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

关于azure - Azure Active Directory 中的简单目录查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38275123/

相关文章:

ios - 带有 Cordova 应用程序的 Azure 通知中心 (iOS)

c# - 使用 PKCE 的 Azure 授权代码流不适用于 secret 客户端(Web 应用客户端类型)

Azure B2C 租户失败,错误为 "Tenant creation failed."

c# - Xamarin : iOS Authentication error with Microsoft login

python - 我可以在 OneDrive/Sharepoint 中创建不过期 token 吗?

azure - 如何使用 microsoft graph api 获取 azure ad 用户属性

javascript - Azure 计算机视觉 : Recognize Printed Text

使用自动安全性的 Azure 资源管理器服务连接 : What permissions are assigned over the Resource Group?

azure - 如何将 Azure Functions 返回值绑定(bind)到输出?

azure - Azure AD session token 的位置