web-dev-qa-db-ja.com

サーバー側はOwin Authenticationを使用してキャッシュを要求します

以前はFormsAuthenticationを使用していたアプリケーションがあり、少し前にIdentityModelWindowsIdentityFrameworkを使用するように切り替えたので、クレームベースの認証を利用できますが、使用して実装するのはかなり醜いものでした。それで、私はOwinAuthenticationを見ています。

OwinAuthenticationAsp.Net Identityフレームワークを調べています。しかし、現時点でAsp.Net Identityフレームワークの唯一の実装はEntityModelを使用しており、私はnHibernateを使用しています。したがって、今のところ、Asp.Net IdentityをバイパスしてOwin Authenticationを直接使用することを試みています。私はようやく「 Identity Frameworkのマジックを無視してOWIN認証ミドルウェアを使用して求めるクレームを取得する方法を教えてください 」のヒントを使用して、有効なログインを取得できましたクレームはかなり大きいです。 IdentityModelを使用したとき、サーバーにクレームをキャッシュするサーバー側のキャッシュメカニズムを使用でき、Cookieはキャッシュされた情報の単純なトークンを保持していました。 OwinAuthenticationにも同様の機能がありますか、それとも自分で実装する必要がありますか?

私はこれらのボートの1つに乗ることになると思います...

  1. クッキーは3KBのままですが、まあ、少し大きいです。
  2. IdentityModelOwinのSessionCachingに似た、私が知らない機能を有効にします。
  3. アプリケーションの起動時にOwinを構成するときにCookieが膨張する原因となる情報をキャッシュして、フックできるかどうかを確認するために、独自の実装を記述します。
  4. 私はこれをすべて間違って行っていて、私が考えていないアプローチがあるか、Owinで何かを誤用しています。

    public class OwinConfiguration
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Application",
                AuthenticationMode = AuthenticationMode.Active,
                CookieHttpOnly = true,
                CookieName = "Application",
                ExpireTimeSpan = TimeSpan.FromMinutes(30),
                LoginPath = "/Login",
                LogoutPath = "/Logout",
                ReturnUrlParameter="ReturnUrl",
                SlidingExpiration = true,
                Provider = new CookieAuthenticationProvider()
                {
                    OnValidateIdentity = async context =>
                    {
                        //handle custom caching here??
                    }
                }
                //CookieName = CookieAuthenticationDefaults.CookiePrefix + ExternalAuthentication.ExternalCookieName,
                //ExpireTimeSpan = TimeSpan.FromMinutes(5),
            });
        }
    }
    

[〜#〜] update [〜#〜]提供されたHongyeの情報を使用して目的の効果を得ることができ、以下のロジックを思いつきました...

Provider = new CookieAuthenticationProvider()
{
    OnValidateIdentity = async context =>
    {
        var userId = context.Identity.GetUserId(); //Just a simple extension method to get the ID using identity.FindFirst(x => x.Type == ClaimTypes.NameIdentifier) and account for possible NULLs
        if (userId == null) return;
        var cacheKey = "MyApplication_Claim_Roles_" + userId.ToString();
        var cachedClaims = System.Web.HttpContext.Current.Cache[cacheKey] as IEnumerable<Claim>;
        if (cachedClaims == null)
        {
            var securityService = DependencyResolver.Current.GetService<ISecurityService>(); //My own service to get the user's roles from the database
            cachedClaims = securityService.GetRoles(context.Identity.Name).Select(role => new Claim(ClaimTypes.Role, role.RoleName));
            System.Web.HttpContext.Current.Cache[cacheKey] = cachedClaims;
        }
        context.Identity.AddClaims(cachedClaims);
    }
}
32
Nick Albrecht

OWIN cookie認証ミドルウェアは、セッションキャッシングのような機能をまだサポートしていません。 #2はオプションではありません。

#3は正しい方法です。 Prabuが示唆したように、コードでは次のようにする必要があります。

OnResponseSignIn:

  • 一意のキー(GUID)を使用してcontext.Identityをキャッシュに保存します
  • 一意のキーが埋め込まれた新しいClaimsIdentityを作成する
  • Context.Identityを新しいIDに置き換えます

OnValidateIdentity:

  • コンテキストから一意のキークレームを取得します。
  • 一意のキーでキャッシュされたIDを取得する
  • キャッシュされたIDを使用してcontext.ReplaceIdentityを呼び出します。

私はあなたにクッキーをgzipすることを提案するつもりでしたが、OWINはすでにそれをTicketSerializerで行っていることがわかりました。あなたのためのオプションではありません。

15
Hongye Sun
Provider = new CookieAuthenticationProvider()
{
    OnResponseSignIn = async context =>
    {
        // This is the last chance before the ClaimsIdentity get serialized into a cookie. 
        // You can modify the ClaimsIdentity here and create the mapping here. 
        // This event is invoked one time on sign in. 
    }, 
    OnValidateIdentity = async context => 
    {
        // This method gets invoked for every request after the cookie is converted 
        // into a ClaimsIdentity. Here you can look up your claims from the mapping table. 
    }
}
8
Praburaj

IAuthenticationSessionStoreを実装して、Cookieをデータベースに保存できます。

Cookieをredisに保存する例を次に示します。

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)),
LoginPath = new PathString("/Auth/LogOn"),
LogoutPath = new PathString("/Auth/LogOut"),

});

完全な例をチェックしてください ここで

1
Alex Nguyen