2017-07-28 2 views
0

J'authentification d'un utilisateur:MVC FormsAuthentication IsInRole dans la vue ne fonctionne pas

 [Route("Login"), HttpPost, AllowAnonymous] 
     public LoginViewModelResponse Login(LoginViewModelRequest data) 
     { 

      if(!Membership.ValidateUser(data.Username, data.Password)) 
      { 
       return new LoginViewModelResponse 
       { 
        DisplayMessage = "Invalid Username/Password!", 
        IsSuccess = false, 
        RedirectUrl = "/Home/" 
       }; 
      } 


      FormsAuthentication.SetAuthCookie(data.Username, false); 
      ClaimsIdentity identity = new GenericIdentity(data.Username); 


      var roles = "Administrator,User".Split(','); 
      // var client = AuthorisationService.instance.GetAuthenticatedUser();// new ClientService().GetClientById(1); 
      var principle = new GenericPrincipal(identity, roles); 

      HttpContext.Current.User = principle; 
      System.Threading.Thread.CurrentPrincipal = principle; 

      if (User.IsInRole("Administrator")) 
      { 
       var b = 1; 
      } 
      return new LoginViewModelResponse 
      { 
       IsSuccess = true, 
       DisplayMessage = "OK", 
       RedirectUrl = "/Home/" 
      }; 
     } 

et le test 'IsInRole' fonctionne.

Cependant, j'ai les éléments suivants dans ma vue (_layout), et la vérification de l'administrateur échoue.

if (ViewContext.HttpContext.User.IsInRole("Administrator")) 
{ 
    <li class="dropdown"> 
... 

Y at-il quelque chose que je dois faire pour permettre à la vue de comprendre "IsInRole"?

Cela fonctionne:

@if (ViewContext.HttpContext.User.Identity.IsAuthenticated == false) 

Mais 'IsInRole' toujours évalué à false.

Répondre

1

Puisque vous définissez vous-même FormsAuthentication cookies, vous devez créer un objet Principe et l'assigner à thread courant à chaque demande à l'intérieur AuthenticateRequest événement.

Global.asax.cs

public class Global : HttpApplication 
{ 
    protected void Application_AuthenticateRequest(object sender, EventArgs e) 
    { 
     HttpCookie decryptedCookie = 
      Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     if (decryptedCookie != null) 
     { 
      FormsAuthenticationTicket ticket = 
       FormsAuthentication.Decrypt(decryptedCookie.Value); 

      var identity = new GenericIdentity(ticket.Name); 
      var roles = ticket.UserData.Split(','); 
      var principal = new GenericPrincipal(identity, roles); 

      HttpContext.Current.User = principal; 
      Thread.CurrentPrincipal = HttpContext.Current.User; 
     } 
    } 
} 

méthode Sign-In

public void SignIn(string username, bool createPersistentCookie) 
{ 
    var now = DateTime.UtcNow.ToLocalTime(); 
    TimeSpan expirationTimeSpan = FormsAuthentication.Timeout; 

    var ticket = new FormsAuthenticationTicket(
     1 /*version*/, 
     username, 
     now, 
     now.Add(expirationTimeSpan), 
     createPersistentCookie, 
     "" /*userData*/, 
     FormsAuthentication.FormsCookiePath); 

    var encryptedTicket = FormsAuthentication.Encrypt(ticket); 

    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, 
     encryptedTicket) 
    { 
     HttpOnly = true, 
     Secure = FormsAuthentication.RequireSSL, 
     Path = FormsAuthentication.FormsCookiePath 
    }; 

    if (ticket.IsPersistent) 
    { 
     cookie.Expires = ticket.Expiration; 
    } 
    if (FormsAuthentication.CookieDomain != null) 
    { 
     cookie.Domain = FormsAuthentication.CookieDomain; 
    } 

    Response.Cookies.Add(cookie); 
} 
+0

grâce, cela ressemble à quelque chose que je vais essayer. Est-ce que je mets le cookie dans le mauvais sens? Y a-t-il un meilleur moyen d'y parvenir? – Craig

+0

Il semblerait que je devrais aller chercher mes rôles de la base de données sur chaque authentification, et cette méthode se déclenche pour chaque vue qu'il semble. – Craig

+1

Vous devrez sauvegarder les rôles dans UserData pour éviter d'interroger les données pour chaque requête. J'ai mis à jour la réponse. – Win