2012-04-05 4 views
1

フォーム認証に奇妙な問題があります。私は独自のカスタムプリンシパルクラスとアイデンティティクラスを持っており、サインイン後にHttpContext.Current.Userをこのプリンシパルに設定し、キャッシュ(HttpContext.Current.Cache)に格納します。時間がたつと奇妙な行動が始まるようです。これは私のAuthenticateRequestハンドラです:Asp.netフォーム認証 - プリンシパルの変更?

protected void Application_AuthenticateRequest(object sender, EventArgs e) { 
    string userName; 

    var formAuthCookie = HttpContext.Current.Request.Cookies[ FormsAuthentication.FormsCookieName ]; 
    var isAuthenticated = HttpContext.Current.Request.IsAuthenticated; 

    if (isAuthenticated || formAuthCookie != null) { 
     if (!isAuthenticated) { 
      var ticket = FormsAuthentication.Decrypt(formAuthCookie.Value); 
      userName = ticket.Name; 
     } 
     else { 
      userName = HttpContext.Current.User.Identity.Name; 
     } 

     var prin = (IPrincipal)HttpContext.Current.Cache[ userName ]; 

     if (prin != null) { 
      HttpContext.Current.User = prin; 
     } 
    } 
} 

これは常に問題なく動作します。カスタムプリンシパルはキャッシュから取り出され、現在のコンテキストのユーザーに正しく設定されます。

問題は、ページが読み込まれると、Page.UserプロパティにGenericPrincipal(ロールなし)とFormsIdentityがあることです。私はこれがどこで起こっているのか分かりません。もちろん、FormsAuthはロールを制限されたページにすることができますが、ユーザーは適切な役割を果たしていないため、ページは機能しません。

私がAuthenticateRequestハンドラで設定したprincpalが置き換えられる理由は何ですか?

+0

をあなたはキャッシュが毎回アプリドメインrecylesを意味し、ベースのAppDomainされている間をFormsAuthenticationは、クッキーベースであることを認識しない、それが失われたすべてのもの... –

+0

アプリケーションプールがあることされていませんリサイクル。実際にあなたは私に思い出させました、アプリケーションプールをリサイクルすることは少し問題を修正するようです。クッキーは、セッションと同時に期限切れになるように設定されています。問題は、キャッシュが失われているということではありません。上のコードをトレースして、正しいプリンシパルが抜け出し、文字通り、後でpage_loadの後に別のプリンシパルがあることがわかります。 – Andy

+0

フォームの認証Cookieと同時に期限切れになるようにセッションを設定しないでください。 http://completedevelopment.blogspot.com/2009/12/caution-with-using-sessiontimeout-and.html –

答えて

-1

代わりにこれを試してみてください:

var formAuthCookie = Context.Request.Cookies[ FormsAuthentication.FormsCookieName ]; 
var isAuthenticated = Context.Request.IsAuthenticated; 

if (isAuthenticated || formAuthCookie != null) { 
    if (!isAuthenticated) { 
     var ticket = FormsAuthentication.Decrypt(formAuthCookie.Value); 
     userName = ticket.Name; 
    } 
    else { 
     userName = Context.User.Identity.Name; 
    } 

    var prin = (IPrincipal)Context.Cache[ userName ]; 

    if (prin != null) { 
     Context.User = prin; 
    } 
} 
+0

これと私との違いを強調できますか? – Andy

+0

@Andy - 小さなコードブロックなので、変更は明らかです。 HttpContext.Current。*をContextに変更するだけです。* –

+0

これは違いがありません。 – bang

関連する問題