9

Ich versuche, FormsAuthentication zu verwenden und es funktioniert im Moment mit Benutzername und Kennwort. Ich muss dem Forms-Authentifizierungsticket eine Benutzerrolle hinzufügen und verwende keine ASP.NET-Mitgliedschaft.FormsAuthentication-Rollen ohne Mitgliedschaft

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

Welchen Mechanismus verwenden Sie jetzt für die Arbeit mit Rollen? –

+0

@HuseinRoncevic In meiner Datenbanktabelle habe ich UserName, Password und Role für einen Benutzer. Ich möchte die aus der Datenbanktabelle abgerufene Rolle an das Authentifizierungsticket übergeben. – chamara

+0

Nicht sicher, dass es so funktioniert. Sie geben den Benutzernamen nur in den Authentifizierungs-Cookie ein und dann lesen Sie für jede eingehende Anfrage den Benutzernamen aus dem Authentifizierungs-Cookie und laden andere Details aus der Datenbank. Das kann in einem 'ActionFilter' gemacht werden. – Suhas

Antwort

20

FormsAuthenticationTicket Konstruktor (die mit den meisten Parametern) hat userData Parameter, der eine Zeichenfolge erfolgt. Hier können Sie Ihre Rollen hinzufügen, getrennt durch ein Zeichen wie Pipe (|) oder Hash. Wie Sie planen zu verwenden, bleibt Ihnen überlassen. Normalerweise würden Sie das Ereignis AuthenticateRequest registrieren. So könnten Sie ein Ticket erstellen war:

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); 
} 

Danach in global.asax Sie so etwas tun würde:

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; 
    } 
} 

Jetzt haben Sie Rollen in IPrincipal Objekt (HttpContext.Current.User) und wenn Sie Abfrage mit HttpContext.Current.User.IsUserInRole("RoleName") werden Sie wahr oder falsch erhalten. Auf diese Weise sollten Sie vermeiden können, Roles Provider zu verwenden.

UPDATE: Ein besseres Ereignis, das aufgerufen werden muss, um die Neuerstellung des Benutzerprinzipals zu verarbeiten, ist Application_AuthenticateRequest anstelle von BeginRequest. Ich habe den Code aktualisiert, um dies zu berücksichtigen.

+3

Gute Antwort, obwohl dies eine Nullreferenzausnahme auslöst, wenn der Benutzer nicht authentifiziert ist. Verwenden Sie 'base.PostAuthenticateRequest + = OnAfterAuthenticateRequest;' stattdessen – Burjua

+1

Gute Antwort. Aber wenn Sie Standard FormsAuthorization verwenden, dann müssen Sie Ticket nicht erneut entschlüsseln ... Sie können einfach sagen: "var decodedTicket = ((FormsIdentity) HttpContext.Current.User.Identity) .Ticket;' – kape123

+0

Ich habe es nicht versucht das hauptsächlich, weil ich das Ticket verschlüsselt habe. Aber ich werde es versuchen. Vielen Dank. –