2017-07-14 10 views
2

Owin + Oauth2 + Identity2の使用。Web API2のID2ベアラトークンのアクセス許可の変更

私は、変更したデフォルトの基本認証設定でWeb APIを使用しています。

私startup.cs部分クラス

public void ConfigureAuth(IAppBuilder app) 
    { 
     // Enable the application to use a cookie to store information for the signed in user 
     // and to use a cookie to temporarily store information about a user logging in with a third party login provider 
     app.UseCookieAuthentication(new CookieAuthenticationOptions()); 
     app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);//TODO: prob wont need this 

     // Configure the application for OAuth based flow 
     PublicClientId = "self"; 

     OAuthOptions = new OAuthAuthorizationServerOptions 
     { 
      TokenEndpointPath = new PathString("/Token"), 
      Provider = new ApplicationOAuthProvider(PublicClientId), 
      AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),//TODO: prob wont need this 
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), 
      // In production mode set AllowInsecureHttp = false 
      AllowInsecureHttp = true //TODO: set debug mode 
     }; 

     // Token Generation 
     app.UseOAuthBearerTokens(OAuthOptions); 
    } 

public void Configuration(IAppBuilder app) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     ConfigureAuth(app); 

     WebApiConfig.Register(config); 
     app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); 
     app.UseWebApi(config); 
    } 

私applicationOAuthProvider.cs

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) 
    { 
     //get user 
     var service = new CarrierApi.CarrierManagementClient(); 
     var result = service.LoginAsync(context.UserName, context.Password); 
     var user = result.Result.Identity; 

     //TODO: log stuff here? i.e lastlogged etc? 

     if (user == null) 
     { 
      context.SetError("invalid_grant", "The user name or password is incorrect."); 
      return; 
     } 

     ClaimsIdentity oAuthIdentity = user; 
     ClaimsIdentity cookiesIdentity = user; 

     AuthenticationProperties properties = CreateProperties(user.GetUserName()); 
     AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties); 
     context.Validated(ticket); 
     context.Request.Context.Authentication.SignIn(cookiesIdentity); 
    } 

あなたは私を実際に見ることができるように根元の部分の私startup.csクラス既存のDBへのwcf呼び出しを介してIDを取得します。郵便配達員を使用するとき、私は/トークンのURLを取得し、私のベアラートークンを取得し、次のリクエストで私はそれをヘッダーに渡し、私のコントローラーメソッドを呼び出します。

これは、ユーザーがアクセスを許可していない場合、アクセスが許可されていれば、うまくいきます。

私は同じwcfとDBを使用してユーザーのアクセス権を変更すると、郵便受けに同じリクエストを送信すると、iveがユーザーに割り当てられているロールでその権限を削除してもアクセスできます。

パーミッションが「リフレッシュ」されているか、各リクエストで再度チェックされていることを確認するにはどうすればよいですか?

+0

あなたは、1回のリクエストごとにWCFサービスに電話をかけたいですか? – DavidG

+0

私はデータベースに設定されているアクセス許可をチェックする必要があります、wcfはdbへの唯一のアクセスです。基本的に私はちょうどアクセス許可を確認する方法が必要です変更した場合は、セッションや何かを更新する必要がありますので、許可が働くように – lemunk

答えて

3

ログインしたユーザーのすべてのロールは、ログイン時にGrantResourceOwnerCredentialsメソッドのclaimとして、ベアラトークンに格納されます。要求を許可する必要がある場合、ロールは、ベアラトークンに格納されているリストで、AuthorizationFilterのデフォルトの実装によって検索されます。したがって、ユーザーの権限を変更する場合は、新しいログインが必要です。フィールディングは彼のdissertationに書いたように

この動作は、Restfullアーキテクチャのステートレスcontraintを尊重し、またこれを使用すると、異なる動作が必要な場合は、複数の可能性があるパフォーマンスとセキュリティ

間の良好なバランスです。

のリフレッシュトークン

あなたはapplicationOAuthProviderクラスのGrantRefreshToken方法を実現する最新の情報に更新トークンを、使用することができます。リフレッシュされたユーザーのアクセス許可を取得して新しいアクセストークンを作成することができます。これはhowを学ぶ良い記事です。

に注意してください:

  • より多くの複雑さをなし、リアルタイムエフェクト
  • クライアント上。あなたはアクセストークンが短い寿命を持っている場合、あなたは(ユーザー権限が変更されていない場合であっても)多くの場合、それを更新する必要がアクセストークンが
  • の期限切れを待たなければならないそうでない場合は、長寿命が問題に
を解決しません

各要求のアクセス権を確認

カスタムAuthorizationFilterを実装し、データベースのユーザーのアクセス許可をチェックできますが、それは遅い解決策です。

キャッシュとログインセッション

あなたはGrantResourceOwnerCredentials方法で、ログインごとに(GUIDなど)、ユーザーセッションの鍵を生成し、そして請求などベアラトークンに格納することができます。 2つのインデックス(ユーザーセッションのキーとuserId)を使用して、キャッシュシステム(Redisなど)にも格納する必要があります。 Redisの公式文書はhowと説明しています。ユーザーのpermessionsが変更された場合

、あなたはあなたがカスタムAuthorizationFilterを実装し、セッションがある場合は、キャッシュ内の各要求のためにチェックすることができるのuserId

で検索、キャッシュシステムで、そのユーザのすべてのセッションを無効にすることができます有効で、ユーザーセッションのキーで検索します。

は注意してください:これはステートレス制約に違反することになりますし、あなたのアーキテクチャでは、あなたがAuthorizaAttribute filterの標準的な実装を見つけることができます。ここ


をrestfullません。 AuthorizeAttributeを拡張し、IsAuthorizedメソッドをオーバーライドするカスタムフィルタを作成できます。

他の方法がありますが、ユーザーのアクセス許可はどのくらいの頻度で変更されますか?多くのシステムでは、セキュリティが最初の要件であるシステムでも、アクティブなセッション中にユーザーのアクセス許可の構成が変更された場合は、新しいログインをアクティブにするために新しいログインが必要です。 この標準動作を変更する必要がありますか?

ご存知の方は、私はキャッシュシステムを使用して解決策を提案します。

+0

情報のために、おかげであなたのアイデンティティをキャッシュ層にし、認証フィルタは、 – lemunk

+0

更新トークンはどうですか?それは結果を更新するためにアイデンティティをもう一度呼び出すのでしょうか? – lemunk

+0

あなた自身でリフレッシュトークンのメカニズムを実装する必要があります。そのため、ユーザーの権限を更新することができます。私は私の答えをより詳細に編集します。 –

関連する問題