2016-07-08 2 views
1

私は、Microsoftのディレクトリからユーザーに関するいくつかの基本的なプロパティを取得する必要がある単純なデスクトップアプリケーションを作成しています。具体的にはAzure Active Directoryでの単純なディレクトリ参照

  1. 私は1つのテナントネイティブLOBアプリケーションを作成しています。
  2. アプリケーションはデスクトップ上で動作します。
  3. アプリケーションは、ログオンしたドメインアカウントとして実行されます。
  4. 組織のドメインアカウントは、AADに同期されます。
  5. 私は、ネイティブのWebアプリケーションやWeb APIなどを保護しようとしていません。ユーザーにサインインする必要はありません。
  6. 組織内の外部のイベント管理ツールから電子メールアドレスを取得しています。私は電子メールアドレスに基づいてAADからAADアカウントプロファイルデータ(アドレス帳情報、具体的には職種)を検索する必要があります。私はAADデータだけを読んでいます。

はこれまでのところ、私は次のように行われている: -

  1. AzureのADグラフAPIは、プロファイル情報を取得するための正しい方法であることが表示されます。特に、この情報はエンドポイントで利用可能です:https://graph.windows.net/ {テナント}/users/{email}?api-version = 1.6

  2. AADにネイティブアプリケーションを登録するとき、キーは提供されませんでした。だから、私はクライアントの秘密を持っていない。

  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にアクセスするには、どのようなリソースを指定する必要がありますか?

おかげで、

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; 

のApp AAD Application Permissions Setup エラー 未処理の例外:System.AggregateException:1つの以上のエラーが発生しました。 ---> System.AggregateException:1つ以上のエラーが発生しました。 ---> Microsoft.Data.OData.ODataErrorException:操作を完了するための権限が不十分です。 ---> System.Data.Services.Client.DataServiceQueryException:この要求の処理中にエラーが発生しました。 System.Data.Services.Client.DataServiceClientException:{"odata.error":{"code": "Authorization_RequestDenied"、 "message":{"lang": "en"、 "value": "権限が不十分です"}}}

正しい権限を与えても正しいリソースとトークンを取得できるにもかかわらず、まだ何か不足しているようです。

+0

から

var userPriNam = "[email protected]"; var userLookupTask = activeDirectoryClient.Users.Where( user => user.UserPrincipalName.Equals(userPriNam, StringComparison.CurrentCultureIgnoreCase)).ExecuteSingleAsync(); User userJohnDoe = (User)await userLookupTask; 

は、あなたが得た例外を解決する方法を見つけたことがありますか?私はあまりにも正確な例外を取得するため** Authorization_RequestDenied ** –

+0

@Arunkumarはい。 1月21日に追加した回答をご覧ください。テナントの管理者にAADの有無を確認してください。 – VJK

答えて

0

実際の問題はコードでは分かりませんでした。私はAAD管理者ではない。テナントでAADに対して認証を実行する必要のあるアプリケーションは、AAD管理者が許可する必要があります。私のアプリケーションのアクセス権を有効にした後(そしてAAD登録の所有権も取得した)、これが動作し始めました。

1

ここで重要なのは、アプリケーションが、マシン上のユーザーによって実行される安全なサーバーまたはデスクトップクライアントから実行されるヘッドレスクライアントである場合です。

前者の場合、アプリケーションは機密クライアントであるとみなされます。秘密鍵、つまり鍵で信頼されることができます。このシナリオがサンプルでカバーされている場合は、clientIdとclientSecretを使用する必要があります。

、あなたのアプリケーションの設定ページにキーセクションが表示されない可能性が高い理由は、あなたが、代わりに、試料中のステップ#7ごとにWebアプリケーションおよび/またはウェブAPIを選択する、ということですアプリケーションを初めて作成するときにネイティブクライアントアプリケーションを選択します。この「タイプ」は変更できないため、新しいアプリケーションを作成する必要があります。

シナリオが後者の場合、アプリケーションは公開クライアントとみなされ、秘密を信頼することはできません。この場合、唯一のオプションはユーザーに資格情報の入力を求めるオプションです。それ以外の場合は、あなたのアプリケーションが独自の認証レイヤーを持っていても、簡単にデコンパイルしてシークレットを抽出して使用することができます。

あなたのリソースのURLは間違いありません。

+0

ありがとう@Saca。私はネイティブアプリケーションとしてアプリケーションを再作成しました。また、ディレクトリデータを読み取るための権限を委任されているのではなく、アプリケーションのアクセス許可を与えましたさらに、リソースURIにテナントIDを含めないように見えます。これらの修正後、私はトークンを取得することができます。ただし、ディレクトリデータにアクセスしようとすると、依然として要求拒否エラーが発生します。 {"code": "Authorization_RequestDenied"、 "message":{"lang": "en"、 "value": "操作を完了するための権限がありません"}}} 更新されたコードの元の質問のEDITS。 – VJK

関連する問題