asp.net-mvc - individual - mvc 5 login example in c#
MVC custom roleprovider cómo conectarlo a HttpContext.Current.User.IsInRole("myrole") (2)
Tengo una aplicación MVC y escribí un proveedor de roles personalizado como se muestra:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using VectorCheck.Models;
namespace VectorCheck.Security
{
public class MyRoleProvider : RoleProvider
{
private VectorCheckRepository<User> _repository { get; set; }
public MyRoleProvider()
{
_repository = new VectorCheckRepository<User>();
}
public MyRoleProvider(VectorCheckRepository<User> repository)
{
_repository = repository;
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
public override string[] GetRolesForUser(string username)
{
var user = _repository.GetUser(username);
return new string[] { user.Role.Name };
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
var user = _repository.GetUser(username);
return string.Compare(user.Role.Name, roleName, true) == 0;
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
}
Esto funciona muy bien al restringir el acceso a controladores y acciones usando:
[Authorize(Roles = "Administrator")]
encima del controlador o acción.
También quiero acceso restringido a algunas cosas en la vista usando:
HttpContext.Current.User.IsInRole("Administrator")
Aunque este método no forma parte de mi proveedor de roles, no se anula.
¿Alguien sabe cómo hacerlo por este método también?
Si ha enganchado su RoleProvider como el proveedor de roles para la aplicación en web.config, entonces esto debería funcionar automáticamente; el marco creará un RolePrincipal
para un usuario autenticado al inicio de la solicitud que llamará al método GetRolesForUser
en su proveedor de IIdentity
, pasando el nombre de IIdentity
como nombre de usuario.
La implementación del marco del RolePrincipal
IsInRole(string role)
es algo como esto (he agregado comentarios)
public bool IsInRole(string role)
{
if (_Identity == null)
throw new ProviderException(SR.GetString(SR.Role_Principal_not_fully_constructed));
if (!_Identity.IsAuthenticated || role == null)
return false;
role = role.Trim();
if (!IsRoleListCached) {
_Roles.Clear();
// here the RoleProvider is used to get the roles for the user
// and are cached in a collection on the RolePrincipal so that
// they are only fetched once per request
string[] roles = Roles.Providers[_ProviderName].GetRolesForUser(Identity.Name);
foreach(string roleTemp in roles)
if (_Roles[roleTemp] == null)
_Roles.Add(roleTemp, String.Empty);
_IsRoleListCached = true;
_CachedListChanged = true;
}
return _Roles[role] != null;
}
Establezca un punto de interrupción dentro de su método RoleProvider GetRolesForUser
para asegurarse de que se está llamando correctamente y también inspeccione el IPrincipal
( HttpContext.Current.User
) para asegurarse de que sea del tipo RolePrincipal
para un usuario autenticado.
Lamento llegar tarde a la fiesta aquí;
Para el beneficio de otras personas con el mismo problema, la respuesta de Russ Cam es perfecta para encontrar la respuesta.
En mi caso, mi roleManager personalizado no tenía ''enabled = "true" y cacheRolesInCookie = "true". Esto pareció detener el llamado a GetRolesForUser.
Código de trabajo para web.config:
<roleManager defaultProvider="CustomUserRolesMVCRoleProvider" enabled="true" cacheRolesInCookie="true">
Really Good Tutorial sobre este tema en http://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx