2013-12-14 83 views
2

我有兩個控制器,AdminController和的AccountController用下面的代碼ASP.NET MVC 3 HttpContext.Current.User.Identity.IsAuthenticated永遠是假的

的AccountController:

[HttpPost] 
    public ActionResult LogOn(LogOnViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      _authenticationService.SetPrincipal(model.UserName); 
      var exists = _authenticationService.ValidateCredentials(userName, password); 
      FormsAuthentication.SetAuthCookie(model.UserName, false); 
      if(exists){ 
       return RedirectToAction("Index", "Admin"); 

      } 
     } 

     return RedirectToAction("LogOn"); 
    } 

AdminController:

[Authenticate] 
public class AdminController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    { 
     return View(); 
    } 
} 

AuthenticateAttribute繼承自AuthorizeAttribute並具有以下代碼:

protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authenticated = false; 
     if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated) 
     { 
      //some actions 
     } 
     else 
     { 
      FormsAuthentication.SignOut(); 
      FormsAuthentication.RedirectToLoginPage(); 
     } 

     return authenticated; 
    } 

_authenticationServiceAuthenticationService類的實例和SetPrincipal()方法有以下代碼:

public void SetPrincipal(string userName) 
    { 
     var identity = new GenericIdentity(userName); 
     var principal = new GenericPrincipal(identity, null); 
     Thread.CurrentPrincipal = principal; 
     if (HttpContext.Current != null) 
     { 
      var ticket = new FormsAuthenticationTicket(1, 
       principal.Identity.Name, 
       DateTime.Now, 
       DateTime.Now.AddMinutes(30), 
       false, 
       String.Empty, 
       FormsAuthentication.FormsCookiePath); 

      string encryptedCookie = FormsAuthentication.Encrypt(ticket); 
      var authenticationCookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName]; 
      if (authenticationCookie != null) 
      { 
       authenticationCookie.Value = encryptedCookie; 
       authenticationCookie.Expires = DateTime.Now.AddMinutes(30); 
      } 
      HttpContext.Current.User = principal; 
     } 
    } 

當我調試,看AuthenticationService.SetPrincipal() HttpContext.Current.User.Identity.IsAuthenticated是真實的。但重定向到中的AdminController的Index操作總是爲false。結果我再次重定向到LogOn視圖。 我在做什麼錯?

+0

我不爲什麼你使用'HttpContext.Current'當你接收當前HTTP上下文關係中'AuthorizeCore(HttpContextBase的HttpContext)'參數認爲它解決您的問題,但。 –

+0

在httpContext參數中IsAuthenticated屬性也是錯誤的,不幸的是。我無法理解發生了什麼魔術 – anykey3

回答

0

我沒有看到任何地方你實際上將cookie發回給客戶端。爲了在每個後續請求中進行身份驗證,您必須將加密的cookie發送回客戶端,以便它可以將其傳回您的站點。

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie); 
Response.Cookies.Add(cookie); 

我看到你試圖在這裏得到當前驗證cookie:

var authenticationCookie = HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName]; 

但同樣,這是一個GET,沒有一套(或發送cookie的背面)功能線。在您的身份驗證中的這一點上,如果您設置了調試器,則authenticationCookie將始終爲NULL。

此外,我沒有看到您在任何操作或功能中驗證密碼的位置。確保你沒有忽視那一步。

您的代碼還有一個想法/問題/問題。您在控制器操作中設置了一個名爲userExists的變量,但您調用的函數是void類型,所以......您無需設置該變量,只需調用該函數即可。

_authenticationService.SetPrincipal(model.UserName); 
return RedirectToAction("Index", "Admin"); 
+0

我編輯了我的問題。 _authenticationService.ValidateCredentials(字符串用戶名,字符串密碼)用於密碼驗證。之後,我使用FormsAuthentication.SetAuthCookie(model.UserName,false)來設置cookie。 – anykey3

+0

我做了你的建議,但問題沒有解決 – anykey3

+0

@Tommy FormsAuthentication.SetAuthCookie();設置cookie並將其發送回客戶端。 –