9

Sto cercando di utilizzare FormsAuthentication e al momento funziona correttamente con nome utente e password. Devo aggiungere il ruolo utente al ticket di autenticazione dei moduli e non sto utilizzando l'abbonamento a ASP.NET.FormsAgent di autenticazione senza appartenenza

if (rep.CheckUser(model.UserName, model.Password,out UserRole))//Check User 
    { 

    FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe); 

// Roles.AddUserToRole(model.UserName, UserRole);//This Requires Membership 

    return Redirect(FormsAuthentication.DefaultUrl); 

} 
+0

Quale meccanismo stai utilizzando ora per lavorare con i ruoli? –

+0

@HuseinRoncevic Nella mia tabella di database ho UserName, Password e Role per un utente. Desidero passare il ruolo recuperato dalla tabella del database al ticket di autenticazione – chamara

+0

Non sono sicuro che funzioni in questo modo. Metti solo il nome utente nel cookie auth e quindi per ogni richiesta in arrivo leggi il nome utente da auth cookie e carica altri dettagli dal database. Questo può essere fatto in un 'ActionFilter'. – Suhas

risposta

20

FormsAuthenticationTicket costruttore (quello con il maggior numero di parametri) viene userData parametro che prende una stringa. È qui che puoi aggiungere i tuoi ruoli, separati da qualche carattere come pipe (|) o hash. Come pensi di usare dipende da te. Quello che dovresti fare normalmente è registrare l'evento AuthenticateRequest. Quindi, è possibile creare un biglietto di questo è stato:

private void CreateTicket() 
{ 
    var ticket = new FormsAuthenticationTicket(
      version: 1, 
      name: UserName, 
      issueDate: DateTime.Now, 
      expiration: DateTime.Now.AddSeconds(httpContext.Session.Timeout), 
      isPersistent: false, 
      userData: String.Join("|", arrayOfRoles)); 

    var encryptedTicket = FormsAuthentication.Encrypt(ticket); 
    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket); 

    httpContext.Response.Cookies.Add(cookie); 
} 

Dopo che nel global.asax si farebbe qualcosa di simile:

public override void Init() 
{ 
    base.AuthenticateRequest += OnAuthenticateRequest; 
} 

private void OnAuthenticateRequest(object sender, EventArgs eventArgs) 
{ 
    if (HttpContext.Current.User.Identity.IsAuthenticated) 
    { 
     var cookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName]; 
     var decodedTicket = FormsAuthentication.Decrypt(cookie.Value); 
     var roles = decodedTicket.UserData.Split(new[] {"|"}, StringSplitOptions.RemoveEmptyEntries); 

     var principal = new GenericPrincipal(HttpContext.Current.User.Identity, roles); 
     HttpContext.Current.User = principal; 
    } 
} 

Ora avete ruoli in oggetto IPrincipal (HttpContext.Current.User) e quando si query con HttpContext.Current.User.IsUserInRole("RoleName") si otterrà vero o falso. In questo modo dovresti essere in grado di evitare di utilizzare il provider Roles.

AGGIORNAMENTO: un evento migliore da chiamare per gestire l'utente principale ricreato è Application_AuthenticateRequest anziché BeginRequest. Ho aggiornato il codice per riflettere questo.

+3

Buona risposta, anche se questo genera un'eccezione di riferimento null se l'utente non è autenticato. Usa 'base.PostAuthenticateRequest + = OnAfterAuthenticateRequest;' invece – Burjua

+1

Buona risposta. Ma se stai usando FormsAuthorization standard allora non hai più bisogno di decodificare il ticket ... puoi semplicemente dire 'var decodedTicket = ((FormsIdentity) HttpContext.Current.User.Identity) .Ticket;' – kape123

+0

Non ho provato questo principalmente perché ho crittografato il biglietto. Comunque, darò un colpo. Grazie. –

Problemi correlati