2013-09-24 13 views
8

Sto tentando di estendere le funzionalità di autenticazione e registrazione di Service Stack. Ho l'autenticazione e la registrazione che funzionano bene, tuttavia ho bisogno di aggiungere alcuni dati personalizzati per ogni utente. Dalla documentazione di Service Stack e da vari altri post che ho trovato è possibile aggiungere i propri dati utilizzando la colonna MetaData incorporata nella tabella UserAuth.Estensione dell'autenticazione dello stack di servizi - popolamento della sessione utente con meta dati utente personalizzati

Ho creato un CustomAuthRepository in modo da poter impostare la proprietà dei metadati di userauth, qui è il mio repo personalizzato:

public class CustomAuthRepository : OrmLiteAuthRepository, IUserAuthRepository 
{ 
    public UserAuth CreateUserAuth(UserAuth newUser, string password) 
    { 
     newUser.Set(new LoginInfo 
     { 
      IsActive = false, 
      PasswordNeedsReset = true 
     }); 
     return base.CreateUserAuth(newUser, password); 
    } 
} 

Questo sta lavorando molto per impostare i metadati, io alla fine con una versione serializzata l'oggetto LoginInfo nella colonna dei metadati della tabella UserAuth.

Ora quello che sto cercando di fare è quando un utente autentica ho bisogno di cambiare AuthResponse basato su alcuni di questi metadati. Ad esempio, se un utente non è ancora attivato, desidero restituire AuthResponse con una proprietà IsActive = get value from custom meta data

Immagino di poterlo fare se riesco a ottenere i miei metadati personalizzati in AuthSession. In questo modo nel fornitore mie credenziali personalizzati auth ho potuto cambiare l'oggetto di risposta in base a ciò che è nel AuthSession:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider 
{ 
    public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request) 
    { 
     var customUserAuthSession = (CustomUserAuthSession)session; 

     if (!customUserAuthSession.LoginInfo.IsActive) 
     { 
      return new 
      { 
       UserName = customUserAuthSession.UserName, 
       IsActive = customUserAuthSession.LoginInfo.IsActive 
      }; 
     } 

     var isAuthenticated = base.Authenticate(authService, session, request); 

     return isAuthenticated; 
    } 
} 

Sto andando su questo nel modo giusto, o c'è un modo migliore per memorizzare e recuperare metadati personalizzati dati ?

Come posso modificare AuthResponse in base ai metadati personalizzati dell'utente?

Come posso ottenere i miei metadati personalizzati in AuthSession?

Modifica Mi sto avvicinando a quello che sto cercando di fare. Nel mio metodo CustomAuthSession OnAuthenticated():

public override void OnAuthenticated(IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo) 
    { 
     var customUserAuthSession = (CustomUserAuthSession) session; 

     var userAuth = authService.ResolveService<IUserAuthRepository>().GetUserAuth(session, null); 
     customUserAuthSession.LoginInfo = userAuth.Get<LoginInfo>(); 

     authService.SaveSession(customUserAuthSession); 

     base.OnAuthenticated(authService, session, tokens, authInfo); 
    } 

sto refetching l'userauth e popolando la sessione con i dati che ho bisogno. In base allo stack di servizio documentation per una sessione utente personalizzata, è necessario salvare la sessione dopo averla popolata con alcuni dati personalizzati. Lo sto facendo, ma non sembra che stia salvando. Nel mio CustomCredentialsAuthProvider, metodo Authenticate, non vedo i dati personalizzati che ho aggiunto alla sessione.

Modifica Il problema con la mia prima modifica sopra è che l'utente viene autenticato, quindi arriviamo al codice di CustomAuthSession Dove posso controllare se sono attivi o meno. Nel caso in cui non sono attivi avrei bisogno di registrarli, non ideale.

Ho trovato invece che posso fare tutto questo nel metodo di autenticazione delle mie credenziali personalizzateAuthProvider.

public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request) 
    { 
     var userAuthRepo = authService.ResolveService<IUserAuthRepository>(); 
     var userAuth = userAuthRepo.GetUserAuthByUserName(request.UserName); 
     var loginInfo = userAuth.Get<LoginInfo>(); 

     if (!loginInfo.IsActive) 
     { 
      return new CustomAuthResponse 
      { 
       UserName = userAuth.UserName, 
       ResponseStatus = new ResponseStatus("500"), 
       IsActive = loginInfo.IsActive 
      }; 
     } 

     var authResponse = (AuthResponse)base.Authenticate(authService, session, request); 

     return authResponse; 
    } 

Quando la richiesta arriva posso usare il nome utente nella richiesta per andare a prendere l'userauth, e verificare se l'IsActive utente o meno. In caso contrario, posso restituire qualche errore prima che Service Stack li autentica.

Penso che questo funzioni abbastanza bene per quello che sto cercando di fare. Dovrei essere in grado di restituire un errore al client dicendo che l'utente non è attivo.

Se qualcuno ha un modo più pulito per farlo, sarebbe fantastico.

+0

forse questo collegamento può aiutarti [Personalizzazione di IAuthProvider per ServiceStack.net - Procedura dettagliata] (http://enehana.nohea.com/general/customizing-iauthprovider-for-servicest-net-step-by-step/) – stefan2410

+0

grazie per il collegamento non aveva letto quello. sfortunatamente non mostra come ottenere/impostare metadati personalizzati dalla colonna di metadati nella tabella UserAuth. Aggiunge alcuni dati personalizzati a una sessione utente personalizzata, nel metodo OnAuthenticated del suo CustomCredentialsAuthProvider, ma il suo esempio dice 'some_firstname_from_db'. Se riesco a capire come recuperare di nuovo l'utente dal database, potrei popolare la sessione con questo metodo. Non sembra molto pulito però perché nel momento in cui questo metodo è chiamato lo stack di servizio ha già recuperato il mio utente ha verificato i loro crediti e chiamato questo metodo post auth – officert

+0

Ci sono anche altri collegamenti. se non li hai trovati, [qui] (https://github.com/ServiceStack/ServiceStack/wiki/Authentication-and-authorization#custom-authentication-and-authorization) e [qui] (http: // rossipedia. com/blog/2013/03/simple-api-key-authentication-with-servicestack /), [qui] (http://dylanbeattie.blogspot.gr/2013/08/building-servicestack-based-oauth2.html) , [qui] (http://joeriks.com/2013/01/12/cors-basicauth-on-servicestack-with-custom-authentication/) La maggior parte dei ragazzi sono attivi in ​​SO-servicestack, quindi forse più tardi per rispondere la tua domanda. – stefan2410

risposta

8

Ecco la mia risposta finora. Funziona e posso fare quello che sto cercando di fare, ma mi piacerebbe sapere da alcuni dei ragazzi del Service Stack se questo è il modo migliore per farlo.

Per salvare i metadati personalizzati

Creare una nuova classe che le sottoclassi il OrmLiteAuthRepository. Nel mio caso voglio solo usare la persistenza del database Sql integrata nel Service Stack e far sì che crei le tabelle necessarie.

re-implementare il metodo CreateUserAuth di salvare qualsiasi metadati personalizzati:

public UserAuth CreateUserAuth(UserAuth newUser, string password) 
    { 
     newUser.Set(new AccountStatus 
     { 
      IsActive = false, 
      PasswordNeedsReset = true 
     }); 
     return base.CreateUserAuth(newUser, password); 
    } 

Recupero personalizzato metadati

Creare una nuova classe che le sottoclassi il CredentialsAuthProvider. Sostituisci il metodo di autenticazione.

public override object Authenticate(IServiceBase authService, IAuthSession session, Auth request) 
    { 
     var userAuthRepo = authService.ResolveService<IUserAuthRepository>(); 
     var userAuth = userAuthRepo.GetUserAuthByUserName(request.UserName); 
     var accountStatus= userAuth.Get<AccountStatus>(); 

     if (!accountStatus.IsActive) 
     { 
      throw new InvalidOperationException(string.Format("User {0} is not activated.", request.UserName)); 
     } 
     if (!accountStatus.PasswordNeedsReset) 
     { 
      throw new InvalidOperationException("Your password needs to be reset before you can login."); 
     } 

     var authResponse = (AuthResponse)base.Authenticate(authService, session, request); 

     return authResponse; 
    } 

Quando una richiesta di autenticazione arriva in questo metodo, recupera UserAuth e i metadati personalizzati. Se l'utente è inattivo o se è necessario reimpostare la password, lanciare InvalidOperationException con un messaggio di errore.

Nel controller di accesso dell'applicazione del mio client posso controllare il messaggio di errore proveniente dal servizio e reindirizzare l'utente in una pagina che dice che l'account non è ancora attivo, o che la password deve essere ripristinata prima di poter essere autenticata.

Problemi correlati