2016-11-28 17 views
0

私のformsauthenticationticketを作成すると、Application_AuthenticateRequest(global.asax内)がimmediatlyでなく起動されます。 user.isroleをチェックすると空です。しかし後で別のアクションを試みると、Application_AuthenticateRequestが起動され、ユーザーのロールが設定されます。Application_AuthenticateRequestが遅くに発生する

ログイン機能:

 if (loggedIn) 
      { 
       ViewBag.loginFailed = 1; 
       string roles = "Administrator"; 
       CreateTicket(pharmacist.ID.ToString(), roles); 
       LoginRedirect(); 
      } 

方法:あなたが要求したとき

[Authorize(Roles = "Administrator, User")] 
    private void CreateTicket(string id, string role) 
    { 

     var ticket = new FormsAuthenticationTicket(
       version: 1, 
       name: id, 
       issueDate: DateTime.Now, 
       expiration: DateTime.Now.AddHours(1), 
       isPersistent: false, 
       userData: role); 

     var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
     var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
     HttpContext.Response.Cookies.Add(cookie); 
    } 

    [Authorize(Roles = "Administrator, User")] 
    private ActionResult LoginRedirect() { 
     if (User.IsInRole("Administrator")) 
     { 
      return RedirectToAction("Index", "Pharmacist"); 
     } 
     else if (User.IsInRole("User")) 
     { 
      return RedirectToAction("Index", "Patient"); 
     } 
     else { 
      return RedirectToAction("Logout", "Authentication"); 
     } 
    } 

のApplication_AuthenticateRequest

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
    { 
     if (HttpContext.Current.User != null) 
     { 
      if (HttpContext.Current.User.Identity.IsAuthenticated) 
      { 
       if (HttpContext.Current.User.Identity is FormsIdentity) 
       { 
        FormsIdentity id = 
         (FormsIdentity)HttpContext.Current.User.Identity; 
        FormsAuthenticationTicket ticket = id.Ticket; 

        // Get the stored user-data, in this case, our roles 
        string userData = ticket.UserData; 
        string[] roles = userData.Split(','); 
        HttpContext.Current.User = new GenericPrincipal(id, roles); 
       } 
      } 
     } 
    } 

答えて

2

のApplication_AuthenticateRequestだけ呼ばれ新しいリソース。あなたのケースでは

、あなたはFormsAuthenticationTicketを作成し、要求にまだあります。その結果、プリンシパルオブジェクトは、現在のスレッドにまだ割り当てられていません。

現在のスレッドからIPrincipalを取得する場合は、明示的に割り当てる必要があります。

var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 
// You need this two lines. 
HttpContext.Current.User = new GenericPrincipal(id, roles); 
Thread.CurrentPrincipal = HttpContext.Current.User; 
.... 

また、あなたがのApplication_AuthenticateRequestの内側にこれら二つのラインを持っていることを確認してください。

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
{ 
    ... 
    HttpContext.Current.User = new GenericPrincipal(id, roles); 
    Thread.CurrentPrincipal = HttpContext.Current.User; <-- Do not forget this. 
    ... 
} 

FYI:あなたはプライベートメソッドにAuthorizeAttributeを必要としません。コントローラまたはアクションメソッドでのみ必要です。

[Authorize(Roles = "Administrator, User")] <-- This is not needed. 
private void CreateTicket(string id, string role) 
{ 
    ... 
} 
関連する問題