Utilizzo di ASP .NET adesione e profilo con MVC, come posso creare un utente e impostarlo su HttpContext.Current.User?

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

Domanda

Ho implementato un oggetto profilo personalizzato in codice come descritto da Joel qui:

Come assegnare i valori del profilo?

Non riesco a farlo funzionare quando Sto creando un nuovo utente, tuttavia. Quando faccio questo:

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

l'utente viene creato e aggiunto a un ruolo nel database, ma HttpContext.Current.User è ancora vuoto, e Membership.GetUser() restituisce null, quindi questo (dal codice di Joel) non funziona:

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

AccountProfile.CurrentUser.FullName = "Snoopy";

Ho provato a chiamare Membership.GetUser(userName) e impostazione delle proprietà del profilo in quel modo, ma le proprietà impostate rimangono vuoti, e chiamando AccountProfile.CurrentUser(userName).Save() non mettere nulla nel database. Ho anche provato ad indicare che l'utente è valido e registrato, chiamando Membership.ValidateUser, FormsAuthentication.SetAuthCookie, ecc, ma l'utente attuale è ancora nullo o anonima (a seconda dello stato dei miei cookie del browser).

RISOLTO (a cura ULTERIORI, vedi sotto): Sulla base di spiegazione di Franci Penov e ancora un po 'di sperimentazione, ho capito il problema. il codice di Joel e le variazioni ho provato funziona solo con un profilo esistente. Se non esiste alcun profilo, ProfileBase.Create(userName) restituirà un nuovo oggetto vuoto ogni volta che si chiama; è possibile impostare le proprietà, ma non lo faranno "bastone", perché una nuova istanza viene restituita ogni volta che vi si accede. Impostazione HttpContext.Current.User ad un nuovo GenericPrincipal vi darà un oggetto d'uso, ma non un oggetto Profilo, e ProfileBase.Create(userName) e HttpContext.Current.Profile saranno ancora puntare a nuovi, oggetti vuoti.

Se si desidera creare un profilo per un utente appena creato nella stessa richiesta, è necessario chiamare HttpContext.Current.Profile.Initialize(userName, true). È quindi possibile popola il profilo inizializzato e salvarlo, e sarà accessibile sul future richieste in base al nome, quindi il codice di Joel funzionerà. Io sono solo usando HttpContext.Current.Profile internamente, quando ho bisogno di creare / accedere al profilo immediatamente al momento della creazione. Su tutte le altre richieste, io uso ProfileBase.Create(userName), e ho esposto solo la versione in pubblico.

Si noti che Franci è corretta: Se si è disposti a creare l'utente (e ruoli) e impostarlo come autenticato sul primo di andata e ritorno, e chiedere all'utente di quindi accedere, si sarà in grado di accedere al profilo molto più semplicemente tramite il codice di Joel sulla successiva richiesta. Ciò che mi ha gettato è che i ruoli sono immediatamente accessibili al momento della creazione dell'utente senza alcuna inizializzazione, ma il profilo non è.

Il mio nuovo codice 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; }
}

creazione Nuovo utente:

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

l'accesso successivo:

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

Ulteriori grazie a Franci per spiegare il ciclo di vita di autenticazione - Sto chiamando FormsAuthentication.SetAuthCookie nella mia funzione di validazione, ma sto tornando un bool per indicare il successo, perché User.Identity.IsAuthenticated non sarà vero fino al successivo richiesta.

REVISIONE: che sono un idiota. La spiegazione di cui sopra funziona nel caso stretta, ma non risolve il problema centrale: Chiamare CurrentUser restituisce una nuova istanza dell'oggetto di volta in volta, se si tratta di un profilo esistente oppure no. Perché è definita come una proprietà, non stavo pensando a questo, e ha scritto:

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

che (ovviamente) non funziona. Dovrebbe essere:

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

E 'colpa mia per completamente affacciata questo punto fondamentale, ma io credo che dichiara CurrentUser come una proprietà implica che si tratta di un oggetto che può essere manipolato. Al contrario, dovrebbe essere dichiarato come GetCurrentUser().

È stato utile?

Soluzione

La creazione di un utente solo aggiunge alla lista degli utenti. Tuttavia, questo non autentica o autorizzare il nuovo utente per la richiesta corrente. È inoltre necessario autenticare l'utente nel contesto richiesta corrente o per le richieste successive.

Membership.ValidateUser convaliderà solo le credenziali, ma non è autenticare l'utente per le richieste attuali o successive. FormsAuthentication.SetAuthCookie imposterà il ticket di autenticazione nel flusso di risposta, in modo che la richiesta successiva verrà autenticato, ma non influenzare lo stato della richiesta corrente.

Il modo più semplice per autenticare l'utente potrebbe essere quella di chiamare FormsAuthentication.RedirectFromLoginPage (supponendo che si sta utilizzando l'autenticazione di form nel vostro app). Tuttavia, questo sarebbe effettivamente causare una nuova richiesta HTTP, che sarà autenticare l'utente.

In alternativa, se avete bisogno di continuare la logica per l'elaborazione della richiesta corrente, ma desidera che l'utente sia autenticato, è possibile creare un GenericPrincipal, assegnare l'identità del nuovo utente e impostare la HttpContext.User a quella principale.

Altri suggerimenti

Si sta per incorrere in problemi con questo approccio se si attiva anonymousIdentification. Piuttosto che Membership.GetUser (). UserName, vi suggerirei di usare HttpContext.Profile.UserName.

Ti piace questa ...

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

Punta di cappello: SqlProfileProvider - si può utilizzare Profile.GetProfile () in un progetto?

Prima di tutto, grazie per la condivisione @Jeremy i risultati. Lei mi ha aiutato andare avanti nella giusta direzione. In secondo luogo, mi spiace per urtare questo vecchio post. Speriamo che questo vi aiuterà qualcuno unire i puntini.

Il modo in cui ho finalmente ottenuto questo lavoro è stato quello di utilizzare il seguente metodo statico all'interno del mio profilo classe:

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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top