6

モバイル デバイスや Web クライアントから消費される ASP.NET Web API プロジェクトで認証/承認を実行するために、優れた Thinktecture.IdentityModel ライブラリを使用しています。基本認証を使用してモバイル クライアントを認証し、Web API にアクセスし、Thinktecture.IdentityModel が提供する組み込みの SessionToken 生成を利用しています。ただし、ClaimsIdentity クレーム コレクションに追加されたクレームを取り消す方法については、いくつかの懸念があります。これは、クライアントに提供される SessionToken にエンコードされます (と思います)。

これが私がこれまでに持っているものです:

IdentityModel サンプル プロジェクトの例に従って、次のクラスを作成しました。

public static class  SecurityConfig
{
  public static void ConfigureGlobal(HttpConfiguration globalConfig)
  {
      globalConfig.MessageHandlers.Add(new AuthenticationHandler(CreateConfiguration()));
  }

  public static AuthenticationConfiguration CreateConfiguration()
  {
      var authentication = new AuthenticationConfiguration()
          {
              ClaimsAuthenticationManager = new MyClaimsTransformer(),
              RequireSsl = false, //TODO:TESTING only
              EnableSessionToken = true,
              SessionToken = new SessionTokenConfiguration()
              {
                  EndpointAddress = "/Authenticate"
              }
          };
       authentication.AddBasicAuthentication(Membership.ValidateUser);

      return authentication;
   }
}

私の Global.asax クラスから呼び出されます

SecurityConfig.ConfigureGlobal(GlobalConfiguration.Configuration);

モバイル デバイスは、個人からユーザー名とパスワードを収集し、認証ヘッダーを適切に設定して、必要な Web エンドポイントに資格情報を提供します。http://myhost/api/Authenticate

サーバーでは、私の Membership.ValidatUser がユーザー名/パスワードで呼び出され、検証された場合は、の Authenticate メソッドMyClaimsTransformerが呼び出されます。

public class ClaimsTransformer : ClaimsAuthenticationManager
{
   public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
   {
     if (!incomingPrincipal.Identity.IsAuthenticated)
     {
        return base.Authenticate(resourceName, incomingPrincipal);
     }
     return incomingPrincipal;
   }
}

その後、モバイル クライアントはトークンを受け取ります。このトークンは、後続の要求の認証ヘッダーで渡すことができます。

これはすべてうまくいきます。

ここでやりたいことは、ClaimsTransformer に、次の疑似コードのようなコードを追加することです。

var nameClaim = incomingPrincipal.Claims.First(c => c.Type == ClaimTypes.Name);

//Using value in nameClaim lookup roles or permissions for this user.
var someListofRoles = SomeMethodToGetRoles(nameClaim.Value);

//Add user roles to the Claims collection of the ClaimsPrincipal.
foreach(var role in someListOfRoles)
{
   incomingPrincipal.Identities.First().AddClaim(new Claim("Role", role.Name));
}

私の希望は、データベースから特定のユーザーのロールまたは権限のリストを要求する必要がある回数を制限し、カスタム AuthorizeAttribute でこれらのロール/権限をチェックするのを便利にすることでした。

ただし、これを追加し始めたとき、ユーザーがログインしてこのトークンを受け取ったシナリオを考え始めましたが、システムの別のユーザーによる何らかのアクションにより、ロールが変更または取り消された可能性があります。最初のユーザーは、期限切れになったロール/権限のリストを含むこのトークンを引き続き保持し、トークンの期限が切れるまでは何にでもアクセスできます。または、何かへの新しいアクセス権が与えられますが、何らかの方法でログアウトするまで実際にはそのアクセス権を受け取りません。

この方法で作成された SessionToken を無効にするメカニズムはありますか? または、ユーザーの役割/権限に変更が加えられたことを知る方法を見つけた場合、クレームを変更して SessionToken をシームレスに再発行するにはどうすればよいでしょうか?

また、SessionToken を完全に取り消すにはどうすればよいですか。つまり、ユーザーを「ログアウト」したい場合、どのように機能しますか?

4

2 に答える 2

0

データベースの変更通知のデザインは、実際にはあなた次第です。私が提案するのは、タイムスタンプ/行バージョンを使用してデータ(ユーザー/ロール)が古くなっているかどうかを確認することです。このデータのタイムスタンプ/行バージョンをユーザーセッションなどのサーバーに保存したり、クライアント側で Cookie/ヘッダーを保存したりできます。私は前者のアプローチをお勧めします。

古い場合は、トークンに関連する最新のデータ変更を反映して必要なすべての情報を再作成する必要がある CreateConfiguration() メソッドを再実行することをお勧めします。

于 2013-04-03T04:05:51.910 に答える