2009-11-30 20 views
53

Estoy actualizando un sitio para usar MVC y estoy buscando la mejor manera de configurar la autenticación.Almacenar/asignar roles de usuarios autenticados

En este punto, tengo el inicio de sesión funcionando fuera de Active Directory: validar un nombre de usuario y contraseña, y luego configurar la cookie de autenticación.

¿Cómo almaceno la información del rol del usuario en el momento del inicio de sesión, para que mis controladores vean esos roles mientras el usuario navega por el sitio?

[Authorize(Roles = "admin")] 

No tengo ningún problema para obtener una lista de funciones de Active Directory. Simplemente no sé dónde colocarlos para que los controladores los vean.

Respuesta

6

Al autenticar a su usuario, genera una nueva instancia de GenericPrincipal. El constructor toma una matriz de cadenas que son las funciones para el usuario. Ahora configure HttpContext.Current.User igual al principal genérico y escriba la cookie de autenticación, y eso debería hacerlo.

1

¿No podría incluir un authorization store role manager o find (e.g. on Codeplex) o write otro proveedor de funciones que funciona con Active Directory para obtener la información de los grupos?

Esto le ahorrará la molestia de autenticar al usuario, obtener sus roles, y luego repasar esa información en el constructor, y todo sucederá automáticamente para usted como parte del marco.

121

Las funciones se agregan al IPrincipal del HttpContext. Puede crear un GenericPrincipal, analizar la lista de roles en el constructor y configurarlo como HttpContext.User. El GenericPrincipal ello, podrá acceder a través User.IsInRole("role") o la [Authorize(Roles="role")] atribuir

Una forma de hacer esto (en C#) es añadir sus papeles como una cadena separada por comas en el parámetro datos de usuario al crear el vale de autenticación

string roles = "Admin,Member"; 
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1, 
    userId, //user id 
    DateTime.Now, 
    DateTime.Now.AddMinutes(20), // expiry 
    false, //do not remember 
    roles, 
    "/"); 
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, 
            FormsAuthentication.Encrypt(authTicket)); 
Response.Cookies.Add(cookie); 

luego acceder a la lista de funciones del vale de autenticación y crear un GenericPrincipal de su Global.asax.cs

protected void Application_AuthenticateRequest(Object sender, EventArgs e) { 
    HttpCookie authCookie = 
       Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie != null) { 
     FormsAuthenticationTicket authTicket = 
            FormsAuthentication.Decrypt(authCookie.Value); 
     string[] roles = authTicket.UserData.Split(new Char[] { ',' }); 
     GenericPrincipal userPrincipal = 
         new GenericPrincipal(new GenericIdentity(authTicket.Name),roles); 
     Context.User = userPrincipal; 
    } 
    } 
+1

Si Klaus no hubiera respondido bien antes, le habría dado la respuesta correcta. Esta es la forma exacta en que estoy haciendo las cosas también. Gracias por la respuesta detallada. Lo siento, fue un poco tarde. –

+0

Supongo que esto no va a funcionar para los usuarios que tienen las cookies deshabilitadas. – Omu

+1

@Omu Puede admitir la autenticación sin cookies simplemente modificando el método Application_AuthenticationRequest() para buscar el ticket de autenticación en la URL si la cookie no está presente. La parte importante es que los roles se almacenan en el ticket de autenticación cifrado. –

4

Para aquellos de ustedes usando MVC 4 o más tendrá que seguir el consejo de Jaroslaw Waliszko al hacer uso de la respuesta de David Glenn:

"Lo he probado en ASP. NET MVC 4 y yo sugerimos utilizar Application_PostAuthenticateRequest en su lugar. De lo contrario, el principal genérico será anulado ". - Jaroslaw Waliszko 07 de septiembre a las 16:18

Como se indicó anteriormente, todo lo que necesita hacer es reemplazar el nombre del método Application_AuthenticateRequest con Application_PostAuthenticateRequest para que esto funcione. Trabajó como un encanto para mí! Si pudiera votar contra Jaroslaw y David, lo haría.

+3

Lo intenté pero mi reputación de Stack Overflow es inexistente debido a que soy un miembro recién registrado, así que no puedo comentar. Si esto sucede me sorprendería y me sorprendería :) * Choque de sorpresa y sorpresa * – Gareth

Cuestiones relacionadas