asp.net - tutorial - HttpContext.Current.User!=HttpContext.User?
using mvc (1)
Las etiquetas de pregunta dicen "aspnet-mvc (3 y 4)", ¿así que tienes la opción de usar lo siguiente para hacerte la vida más fácil? Si usa membresía simple de la plantilla MVC 4 Internet Application en VS2012, esto funcionará de la mejor manera):
-
WebSecurity.CreateUserAndAccount(name, password)
- para crear un usuario -
Roles.AddUserToRole
(yAddUserToRoles
): agrega un usuario a un rol -
Roles.IsUserInRole
: prueba si un usuario tiene un rol -
[Authorize(Roles = "admin")]
-[Authorize]
puede imponer roles en un controlador completo, o en una acción
CreateUserAndAccount
tiene la ventaja de que también es fácil establecer propiedades para UserProfile, por ejemplo:
WebSecurity.CreateUserAndAccount(newUser.UserName, newUser.Password,
new { FullName = newUser.FullName, Email = newUser.Email, Timezone = newUser.TZ });
Roles.AddUserToRoles(newUser.UserName, new[] {"admin", "user"});
Editar , me doy cuenta de que lo anterior no responde a su pregunta original sobre la equivalencia de la propiedad del .User
.
HttpContext
en un controlador es una propiedad: Controller.HttpContext
. HttpContext
en global.asax.cs es la clase estática, por eso usa HttpContext.Current
. Se refieren a lo mismo.
Si ejecuta el siguiente código, puede ver que aparentemente son el "mismo principal". Entonces, la pregunta es: ¿qué pasó con los roles que asignaste?
protected void Application_AuthenticateRequest(object sender, EventArgs e) {
...
FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
string[] roles = new string[] { "admin", "user" };
identity.Label = "test label";
System.Security.Principal.GenericPrincipal ppl = new System.Security.Principal.GenericPrincipal(identity, roles);
HttpContext.Current.User = ppl;
... }
public ActionResult Index() {
bool isAdmin = HttpContext.User.IsInRole("admin");
bool isAdmin2 = System.Web.HttpContext.Current.User.IsInRole("admin");
System.Web.Security.FormsIdentity identity = (System.Web.Security.FormsIdentity)HttpContext.User.Identity;
// The label is carried through from Application_AuthenticateRequest to Index.
string label = identity.Label;
}
El problema es que asignó un GenericPrincipal
a .User
. Dependiendo del RoleProvider
, esto puede ser sobrescrito (por ejemplo, por el RoleManagerModule
) durante PostAuthenticateRequest
y (por ejemplo) convertido en un RolePrincipal
. Esto luego puede diferir a la base de datos (una vez más, según el proveedor) para obtener los roles, por lo que debe sobrescribir sus roles. Si haces el trabajo en Application_OnPostAuthenticateRequest
es posible que estés bien.
¿ HttpContext.Current.User en global asax no es lo mismo que HttpContext.User en un método de acción? Le asigné algunos roles al usuario, pero parece que se pierden.
El siguiente código muestra lo que está sucediendo. Ambos Asserts se activan cuando un usuario inicia sesión, primero en asax global y luego en el método de acción. Sin embargo, dan diferentes resultados.
Primero esto:
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
// ... omitted some code to check user is authenticated
FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
string[] roles = new string[] { "admin", "user" };
HttpContext.Current.User =
new System.Security.Principal.GenericPrincipal(identity, roles);
Assert(HttpContext.User.IsInRole("admin"));
}
Entonces esto en mi método de acción:
public ActionResult Index()
{
bool isAdmin = HttpContext.User.IsInRole("admin");
Assert(isAdmin); // this fails, isAdmin is false
// ...
}
Usé los siguientes recursos
Esta respuesta SO
http://csharpdotnetfreak.blogspot.com/2009/02/formsauthentication-ticket-roles-aspnet.html