2017-04-12 24 views
2

私は現在、Web APIとMVC UI(最終的には同じAPIと通信できるモバイルUIも持つ)を使用して新しいプロジェクトを設定しています。IdentityServer4 - APIのユーザー権限

  1. ユーザーが自身のアプリケーションに追加されたログインまたは
  2. IdentityServerユーザーをサインアップするIdentityServer4サーバーにそれらを脱ぐMVC UIにナビゲート:

    だから、私は、次の計画を持っています

  3. 権限はその後、自分のアクセスを制限するために、ユーザーに設定することができ
  4. データベースのユーザテーブルは

これは、IDサーバだけでは、アイデンティティ・サーバーであることを意味する(と私ans私は人々が自分の役割とアクセス許可を心配することなく、Googleなどを介してログインすることができます)。

上記を達成するには、クライアントではなくAPIに対するユーザーのアクセス許可を確認する必要があります(クライアントはウェブ、電話アプリ、JavaScriptクライアントなど何でもかまいません)ユーザーのアクセス許可を処理するためのもの)。

APIでは、私はPermissionhandlerとPermissionRequirement認証ポリシーを実装しました。だから、APIコントローラやメソッドでは、私は[Authorize(Policy = "CreateUser")]のようにすることができます。システム権限ごとにポリシーを設定する必要があるようです。

だから、認可ハンドラで私のことを行う必要があります

  1. 彼らはアプリのデータベースに存在した場合はそうでない場合は、その権限と認証を確認するか、
  2. を拒否
  3. 現在のユーザーのユーザー名を取得します。アプリケーションデータベースに存在する場合は、後で管理パネルからアクセス権を設定することができます。

これは、ユーザーのユーザー名をIDエバー。私はそれを行うためにUserInfoClientを使用する必要があると理解していますが、ユーザーのトークン/資格情報を使用してIDサーバーからクレームを取得する方法や、少なくともUser.Identity.Nameを取得する方法を理解することはできません。

私はサブIDを使用してアプリケーションデータベースにユーザーを追加できますが、権限を管理している人はその人が誰なのか分からないので、実際に電子メールを使用する必要があります。

MVCクライアントでは、User.Identity.Nameが問題なく表示されますが、そのAPIの値はnullです。

私の質問は、現在のユーザーのIdentity.Name、username、またはEメールをAPI内からどのように取得するのですか?

ありがとうございました。

答えて

0

私はあなたがすでにthisのような類似したウェブAPIIdentityServerAuthenticationを設定すると考えている - あなたは、Webサービスの呼び出しを行うときに、あなたが同じトークンを渡す必要があります

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
{ 
    ... 
    app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions 
    { 
     Authority = "http://UrlOfIentityServer", 
     RequireHttpsMetadata = false, 
     ApiName = "exampleapi" 
    }); 
    ... 
} 

IdentityServerthisのような -

using (var httpClient = new HttpClient()) 
{ 
    string accessToken = await HttpContext.Authentication.GetTokenAsync("access_token"); 

    httpClient.BaseAddress = new Uri("http://UrlOfWebAPI"); 
    httpClient.DefaultRequestHeaders.Clear(); 
    httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); 

    return await httpClient.GetStringAsync("api/clock/time"); 
} 
+0

私は自分のアプリケーションの別の層(すなわち、別のプロジェクト)で私の承認ハンドラを持っているので、私はそのようにするHttpContextにアクセスすることはできません。私はAuthorizationHandlerContextにアクセスできますが、HttpContextにアクセスできるかどうかはわかりません。私は間違っているかもしれません。 – Craig

2

は、私は今それを割ったと思います。

  var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext; 
     if (mvcContext != null) 
     { 
      // Use the UserInfo endpoint to get the user's claims 
      var discoveryClient = new DiscoveryClient("http://localhost:5000"); 
      var doc = await discoveryClient.GetAsync(); 

      var accessToken = await mvcContext.HttpContext.Authentication.GetTokenAsync("access_token"); 

      var userInfoClient = new UserInfoClient(doc.UserInfoEndpoint); 
      var response = await userInfoClient.GetAsync(accessToken); 

      var claims = response.Claims; 
     } 

これはhttps://docs.microsoft.com/en-us/aspnet/core/security/authorization/policiesの下部に詳細な権利であるので、マイクロソフトによると、それは正しい方法です。

あなたはこのアイデアを吹き飛ばしましたが、勝っていただきありがとうございます。私はこの血まみれのものを何時間も見つめていた。あなたが時々必要とするのは、誰か他の誰かが何かを言うことです、何か、そしてその呪いは壊れています! :)

私はまだ誰かが持っている場合、これを達成するためのより良い方法に公開されています。

乾杯

+0

ようこそ。 +1と私も何かを学ぶので、共有するためにありがとう。 – Win

+0

私は似たようなことをやろうとしていて、IDサーバがRBACの例だけを見つけて、「役割」の主張を提供することに非常に心配していました。これは私にとっても間違っていたようだ。アプリケーションは、ユーザーのアクセス許可を判断し、クライアントが要求しているものと比較します。クライアントがユーザーから同意を得たという理由だけで、ユーザーが実際に要求された操作を実行する権限を持っているとは限りません。あなたのアプローチの私の唯一の質問は、ユーザーがアイデンティティを使って電子メールアドレスやその他の主張を変更した場合、それがアプリケーションレベルでどのように更新されるのでしょうか? – crush

+0

@crushそれは良い点であり、 (私が取り組んでいたプロジェクトはもはや進んでいない)。たぶん、心配する必要がないかもしれません。異なるサービスの電子メールが異なる人もいますので、IdentityServerで電子メールを変更するかどうかは気にする必要がありますか?気にしていれば、プロファイルエディタを設定して関連する変更をIdentityServerに渡すことができます。彼らはとにかく私の最初の考えです。 – Craig

関連する問題