El uso de ASP .NET Composición y perfil con MVC, ¿cómo puedo crear un usuario y ponerlo a HttpContext.Current.User?

StackOverflow https://stackoverflow.com/questions/2547290

Pregunta

Me puso en marcha un objeto personalizado del perfil en el código como se describe por Joel aquí:

Cómo asignar los valores del perfil?

No se puede conseguir que funcione cuando estoy creando un nuevo usuario, sin embargo. Cuando hago esto:

Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyRole");

Se crea el usuario y se añade a un papel en la base de datos, pero HttpContext.Current.User todavía está vacío, y vuelve Membership.GetUser() nula, por lo que este (a partir del código de Joel) no funciona:

static public AccountProfile CurrentUser
{
    get { return (AccountProfile)
                     (ProfileBase.Create(Membership.GetUser().UserName)); }
}

AccountProfile.CurrentUser.FullName = "Snoopy";

He intentado llamar Membership.GetUser(userName) y configuración de propiedades del perfil de esa manera, pero las propiedades del conjunto de permanecer vacío, y llamando AccountProfile.CurrentUser(userName).Save() no ponga nada en la base de datos. También he intentado que indica que el usuario es válido y cerrar sesión, llamando Membership.ValidateUser, FormsAuthentication.SetAuthCookie, etc., pero el usuario actual sigue siendo nula o anónima (dependiendo del estado de mis cookies del navegador).

SOLUCIONADO (a editar, ver más abajo): Sobre la base de la explicación de Franci Penov y algunos más experimentación, me di cuenta de la cuestión. Código de Joel y las variaciones que probé sólo funcionará con un perfil existente. Si no existe el perfil, ProfileBase.Create(userName) devolverá un nuevo objeto vacío cada vez que se llama; puede establecer las propiedades, pero no se "pegue" debido a una nueva instancia se volvió cada vez que se acceda al mismo. Configuración HttpContext.Current.User a un nuevo GenericPrincipal le dará un objeto de usuario, pero no un objeto Perfil, y ProfileBase.Create(userName) y HttpContext.Current.Profile seguirá siendo elija nuevo, objetos vacíos.

Si desea crear un perfil para un usuario recién creado en la misma petición, tiene que HttpContext.Current.Profile.Initialize(userName, true) llamada. A continuación, puede rellenar el perfil inicializado y lo guarda, y será accesible en futuras solicitudes de nombre, por lo que el código de Joel va a funcionar. Estoy solamente usando HttpContext.Current.Profile internamente, cuando necesito para crear / acceder al perfil inmediatamente después de la creación. En cualquier otra solicitud, utilizo ProfileBase.Create(userName), y he expuesto esta versión la única como públicos.

Tenga en cuenta que Franci es correcta: Si usted está dispuesto a crear el usuario (y funciones) y configurarlo como autenticados en la primera de ida y vuelta, y pedir al usuario que inicie sesión en, usted será capaz de acceder al perfil mucho más simple a través de código de Joel en la solicitud posterior. Lo que me tiró es que los roles es inmediatamente accesible a la creación de usuarios sin ningún tipo de inicialización, pero no es el perfil.

Mi nuevo código AccountProfile:

public static AccountProfile CurrentUser
{
    get
    {
        if (Membership.GetUser() != null)
            return ProfileBase.Create(Membership.GetUser().UserName) as AccountProfile;
        else
            return null;
    }
}

internal static AccountProfile NewUser
{
    get { return System.Web.HttpContext.Current.Profile as AccountProfile; }
}

Nueva creación del usuario:

MembershipUser user = Membership.CreateUser(userName, password);
Roles.AddUserToRole(userName, "MyBasicUserRole");
AccountProfile.NewUser.Initialize(userName, true);
AccountProfile.NewUser.FullName = "Snoopy";
AccountProfile.NewUser.Save();

El acceso posterior:

if (Membership.ValidateUser(userName, password))
{
    string name = AccountProfile.CurrentUser.FullName;
}

adicionales gracias a Franci para explicar el ciclo de vida de autenticación - Voy a llamar a mi FormsAuthentication.SetAuthCookie en función de validación, pero estoy devolviendo un bool para indicar el éxito, porque User.Identity.IsAuthenticated no va a ser verdad hasta la siguiente solicitud.

REVISADO: que soy un idiota. La explicación anterior funciona en el caso estrecho, pero no resuelve el problema de fondo: Llamada CurrentUser devuelve una nueva instancia del objeto cada vez, si se trata de un perfil existente o no. Debido a que se define como una propiedad, no estaba pensando en esto, y escribió:

AccountProfile.CurrentUser.FullName = "Snoopy";
AccountProfile.CurrentUser.OtherProperty = "ABC";
AccountProfile.CurrentUser.Save();

, que (por supuesto) no funciona. Debe ser:

AccountProfile currentProfile = AccountProfile.CurrentUser;
currentProfile.FullName = "Snoopy";
currentProfile.OtherProperty = "ABC";
currentProfile.Save();

Es mi propia culpa por pasar por alto por completo este punto básico, pero yo creo CurrentUser declarar como una propiedad implica que se trata de un objeto que puede ser manipulada. En cambio, debería ser declarado como GetCurrentUser().

¿Fue útil?

Solución

Creación de un usuario simplemente lo añade a la lista de usuarios. Sin embargo, esto no quiere autenticar o autorizar el nuevo usuario de la solicitud actual. También es necesario para autenticar al usuario en el contexto de la petición actual o de las solicitudes posteriores.

Membership.ValidateUser sólo validar las credenciales, pero no es la autenticación del usuario para las solicitudes actuales o futuras. FormsAuthentication.SetAuthCookie fijará el vale de autenticación en la secuencia de respuesta, por lo que será autenticado la siguiente petición, pero no afecta el estado de la solicitud actual.

La forma más fácil de autenticar al usuario sería FormsAuthentication.RedirectFromLoginPage llamada (si se asume que está utilizando la autenticación de formularios en su aplicación). Sin embargo, éste podría llegar a causar una nueva petición HTTP, que autenticar al usuario.

Por otra parte, si usted necesita para continuar su lógica para procesar la solicitud actual, pero desea que el usuario sea autenticado, puede crear un GenericPrincipal, asignarlo a la identidad del nuevo usuario y establecer el HttpContext.User a ese principio.

Otros consejos

Usted va a tener problemas con este enfoque si se habilita anonymousIdentification. En lugar de Membership.GetUser (). NombreUsuario, sugeriría usando HttpContext.Profile.UserName.

Al igual que este ...

private UserProfile _profile;
private UserProfile Profile
{
    get { return _profile ?? (_profile = (UserProfile)ProfileBase.Create(HttpContext.Profile.UserName)); }
}

Sombrero de punta: SqlProfileProvider - se puede utilizar Profile.GetProfile () en un proyecto?

En primer lugar, @Jeremy gracias por compartir sus hallazgos. Usted me ayudó a ponerse en marcha en la dirección correcta. En segundo lugar, lo siento por chocar este antiguo puesto. Esperamos que esto ayudará a alguien a conectar los puntos.

La forma finalmente conseguí este trabajo fue utilizar el siguiente método estático dentro de mi clase de perfil:

internal static void InitializeNewMerchant(string username, Merchant merchant)
{
    var profile = System.Web.HttpContext.Current.Profile as MerchantProfile;
    profile.Initialize(username, true);
    profile.MerchantId = merchant.MerchantId;
    profile.Save();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top