Ciao a tutti, vorrei chiedere una cosa riguardante il framework Identity di Asp .Net 4.5.
Sto sviluppando un'applicazione che per motivi commerciali deve accettare un solo login per account alla volta.
Ho effettuato diverse ricerche su internet per avere idee su come risolvere la questione e l'opzione più plausibile è quella di generare un token in fase di login salvarlo nel database e creare un cookie all'utente; se un altro utente provasse a collegarsi con le stesse credenziali verrebbe generato un nuovo token che non corrisponderebbe con quello nel database rilevando così il doppio-login.
Il problema principale che ho riscontrato con questo metodo è che si può facilmente copiare i cookies dell'utente già loggato su un altro browser/macchina e questo verrebbe accettato dall'applicazione come utente valido.
Per ovviare a questo problema sono giunto quindi alla conclusione di creare un token, salvarlo nel database e creare un cookie all'utente ad ogni richiesta... utilizzando un ActionFilter in questo modo:
public class UserActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
IIdentity userIdentity = filterContext.RequestContext.HttpContext.User.Identity;
if (!userIdentity.IsAuthenticated) return;
ApplicationUserManager userManager = filterContext.RequestContext.HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
ApplicationUser user = userManager.FindByNameAsync(userIdentity.Name).Result;
if (user != null)
{
// Ottengo il token da un cookie già presente
string getSvt = filterContext.HttpContext.Request.Cookies["__SessionVerificationToken"].Value.ToString();
// Controllo che il token del cookie sia uguale a quello salvato nel db
if (user.SessionToken == getSvt || user.SessionToken == null)
{
// Genero un nuovo token...
string setSvt = Guid.NewGuid().ToString();
// ...lo mando all'utente
HttpCookie svtCookie = new HttpCookie("__SessionVerificationToken", setSvt);
svtCookie.HttpOnly = true;
filterContext.HttpContext.Response.Cookies.Add(svtCookie);
// ....lo salvo nel db
user.SessionToken = setSvt;
}
else
{
// Se i tokens non coincidono forzo il SignOut e reindirizzo alla pagina di Login filterContext.RequestContext.HttpContext.GetOwinContext().Authentication.SignOut();
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary {
{ "controller", "Account" },
{ "action", "Login" }
});
}
// Aggiorno i dati dell'utente nel db con il nuovo token
userManager.UpdateAsync(user).Wait();
}
}
}
La cosa sembra funziona ma mi sembra forse un po' troppo impegnativa in fatto di risorse... quindi vorrei chiedere a voi, sicuramente più esperti di me, cosa ne pensate e come potrei risolvere il problema.