2011-09-04 25 views
1

我注意到,如果用戶仍然登錄或擁有持久性cookie,即使他在數據庫(用戶表標誌)中被「禁用」或禁用,用戶仍然可以訪問一切,直到該cookie消失或用戶退出該網站。巨大的安全權利。MVC 3 FormsAuthentication和禁用的用戶帳戶

所以我放在一起檢查這一點的ActionFilterAttribute,對我來說令人不安的是我必須擊中他的ActionFilterAttribute應用到的每個控制器的數據庫。這樣做必須有更好的方式,但我還沒有找到。

任何想法將真棒..

回答

1

必須有這樣做的更好的辦法,但我還沒有找到一個還沒有。

不,沒有。抱歉。如果禁用/禁止用戶的概念僅存在於您的數據庫中,則除了點擊數據庫之外沒有別的辦法。 ASP.NET僅驗證在每個請求上發送的身份驗證Cookie的有效性。它甚至不知道殘疾用戶是什麼意思,所以你不能指望它比已經做的更多。

+0

嘿達林,從您不錯的聽覺再次先生。什麼有關創建禁用的帳戶的數據集和緩存呢?每次用戶被標記,我都可以使緩存失效......只是一個念頭。然後過濾器可以檢查它而不是擊中數據庫。 – CrazyCoderz

+0

@CrazyCoderz,當然,將這些信息存儲在內存中將是一個解決方案。要小心,雖然你的應用程序非常成功,並且你開始擁有數百萬用戶(這是我所希望的),但你可能會遇到問題。更不用說,將這些信息存儲在內存中意味着您不能再在Web場中運行,因爲2個節點不會共享相同的內存。這意味着用戶可以在一臺Web服務器上完全有效並在另一臺Web服務器上禁用。所以如果你走這條路線要非常小心,並確保同步緩存。 –

+0

嗯好點。 – CrazyCoderz

1

有幾個選項:

1)您可以驗證用戶的身份驗證是否通過掛鉤會話開始有效。這樣,如果用戶擁有持久性cookie,則可以驗證用戶名並在需要時過期cookie。

2)您可以使用基於時間的機制來每隔幾個請求(每5分鐘或其他)檢查用戶身份驗證狀態。您可以使用UserData字段將​​時間戳值存儲在用戶會話中或auth cookie本身中。這可以讓您重新檢查用戶auth cookie是否需要更頻繁地過期,但將數據庫調用保持在最低限度。

+0

如果他們有一個持久的cookie身份驗證將始終有效。我嘗試了類似的東西,這是我注意到的。 – CrazyCoderz

+0

我不是在說檢查auth cookie,我是在談論打到數據庫或其他什麼,並檢查標誌。如果被禁用或禁用,則會使auth cookie失效。 – TheCodeKing

+0

啊,好的。是的,這是我目前正在使用我的過濾器,我不喜歡使用屬性注入來讓我的倉庫進入過濾器,但它的工作原理。 – CrazyCoderz

1

MyThis是我想出瞭解決方案:

在用戶帳戶會員服務中添加函數返回用戶的帳戶是否仍然有效。

public class UserAccountMembershipService : IMembershipService 
{   
    public bool UserIsActive(Guid userId) 
    { 
     if (userId == new Guid()) throw new ArgumentException("Value cannot be null or empty.", "userName"); 
     MembershipUser user = _provider.GetUser(userId, true); 
     return user.IsApproved; 
    } 
} 

覆蓋的AuthorizeAttribute如下:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     IMembershipService membershipService = new UserAccountMembershipService(); 

     //Check to see if the user's account is still active 
     bool isActive = false; 
     if (httpContext.User.Identity.IsAuthenticated) 
     { 
      Guid userId = (Guid)Membership.GetUser(httpContext.User.Identity.Name).ProviderUserKey; 
      isActive = membershipService.UserIsActive(userId); 
     } 

     if (!isActive) 
     { 
      //If the user's account is no longer active log him/her out 
      IFormsAuthenticationService FormsService = new FormsAuthenticationService(); 
      FormsService.SignOut(); 
     } 
     //Call the base AuthorizationCore method 
     return base.AuthorizeCore(httpContext) && isActive; 
    } 
}