web-dev-qa-db-fra.com

Authentification par formulaire comprenant context.user.identity

Étant donné que la documentation sur ce processus est très vague et déroutante (ou ancienne), je voulais vérifier que je le faisais correctement et que je ne manquais aucune étape.

J'essaie de créer un système de connexion sécurisé, qui expire à la fermeture du navigateur.

- dans mon web.config j'ai les éléments suivants -

<authentication mode="Forms">
      <forms loginUrl="~/Login.aspx" defaultUrl="Index.aspx" name=".ASPXFORMSAUTH" timeout="100" />
    </authentication>
    <authorization>
      <allow users="?" />
    </authorization>
    <machineKey decryption="AES" validation="SHA1" validationKey.......... />

J'ai donc un formulaire de connexion avec la zone de texte nom d'utilisateur/mot de passe et ce bouton:

<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" />

Dans Login_Authenticate, je fais ce qui suit:

protected void Login_Authenticate(object sender, EventArgs e){
string userName = UserName.Text;
string password = Password.Text;

bool Authenticated = false;

// Here's code that makes sure that Username and Password is CORRECT
if(AuthClass.Authenticate(userName, password)){
 Authenticated = true;
}
// error checking does happen here.

if (Authenticated)
{
  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), rememberUserName, String.Empty, FormsAuthentication.FormsCookiePath);
  string encryptedCookie = FormsAuthentication.Encrypt(ticket);
  HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
  cookie.Expires = DateTime.Now.AddMinutes(30);
  Response.Cookies.Add(cookie);
  //FormsAuthentication.RedirectFromLoginPage(userName, false);

  Response.Redirect("MainPage.aspx");
}
}

--- dans le MasterPage.master.cs j'ai la vérification suivante dans▶Init () ---

if (Context.User.Identity.IsAuthenticated)
    {
      int userid = (int)Session["userid"];
      if (userid == null)
      {
        userid = GetUserID(Context.User.Identity.Name);
        if (userid != null)
        {
          Session["userid"] = userid;
        }
      }
    }

EDIT: --- GLOBAL.ASAX; du code dont je ne suis pas sûr qu'il soit correct ou sache ce qu'il fait

protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        // look if any security information exists for this request
        if (HttpContext.Current.User != null)
        {
            // see if this user is authenticated, any authenticated cookie (ticket) exists for this user
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                // see if the authentication is done using FormsAuthentication
                if (HttpContext.Current.User.Identity is FormsIdentity)
                {
                    // Get the roles stored for this request from the ticket
                    // get the identity of the user
                    FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
                    //Get the form authentication ticket of the user
                    FormsAuthenticationTicket ticket = identity.Ticket;
                    //Get the roles stored as UserData into ticket
                    string[] roles = { };
                    //Create general prrincipal and assign it to current request

                    HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity, roles);
                }
            }
        }
    }

--- à partir de là, sur chaque page, j'utilise l'ID utilisateur de session pour rassembler les informations et le contenu de l'utilisateur et m'assurer que l'utilisateur dispose des autorisations d'authentification et de rôle de groupe appropriées.

Est-ce que tout est correct? Ou dois-je décrypter quelque chose quelque part?

Est-ce suffisant pour établir une connexion utilisateur sécurisée? Ou ne devrais-je pas me soucier de l'authentification par formulaires et trouver ma propre façon de créer mes propres cookies et de les gérer moi-même?

18
Dexter

La façon dont votre code est écrit, les connexions persisteront entre les sessions du navigateur. Cela pourrait aider à comprendre les bases de ce qui se passe.

Pour les méthodes d'authentification basées sur les cookies, il y a vraiment trois actions:

1) Connexion - valide les informations d'identification de l'utilisateur et crée et stocke un cookie sur son navigateur.

2) Déconnexion - supprime simplement le cookie du navigateur (en expirant le cookie ou en le supprimant)

3) Validation par demande (la partie qui est votre Application_AuthenticateRequest) - vérifiez si un cookie existe, et si c'est le cas, obtenez l'identité et les rôles de l'utilisateur et définissez HttpContext.Current.User.

En règle générale, le module FormsAuthentication vous en cache la majeure partie. Il semble que votre code essaie d'utiliser certains des éléments de FormAuthentication (comme FormsAuthenticationTicket et FormsIdentity. C'est très bien tant que vous obtenez ce que vous voulez.

Votre méthode Login_Authenticate semble correcte SAUF que vous définissez une expiration sur le cookie. Cela fera persister le cookie même si vous fermez et rouvrez le navigateur. Étant donné que ce n'est pas le comportement que vous souhaitez, je ne définirais pas d'expiration de cookie. Définir cela revient à cocher la case "Se souvenir de moi".

Le code dans Application_AuthenticateRequest est exécuté chaque fois qu'une page est servie à partir de votre application. Son travail principal consiste à définir HttpContext.Current.User. En règle générale, si aucun utilisateur n'est connecté, l'utilisateur est nul ou un utilisateur anonyme. Si un utilisateur est connecté, cela devrait représenter votre utilisateur.

Si vous faites ces trois choses, alors n'importe où dans votre code, vous pouvez référencer HttpContext.Current.User pour décider du niveau d'informations que vous souhaitez afficher. Par exemple, si vous souhaitez restreindre une page aux administrateurs uniquement, vous pouvez appeler HttpContext.Current.Users.IsInRole ("Administrateurs") et les rediriger hors de la page si l'appel renvoie false.

J'espère que cela t'aides.

12
Joe Enzminger

Je suis un peu en retard sur le sujet, mais pour ceux qui essaient d'implémenter l'authentification par formulaires tout en gardant les choses simples (comme j'essayais de le faire), voici la documentation la plus récente que j'ai trouvée sur msdn: http: // msdn .Microsoft.com/en-us/library/xdt4thhy (v = vs.100) .aspx

En bref, ne vous trompez pas avec la configuration des cookies, leur vérification, l'instanciation des tickets ou du principal, ... Laissez-le à la classe FormsAuthentication.

Lorsque vous vous connectez, lorsque votre code contient des informations d'identification et si elles sont valides, appelez simplement

FormsAuthentication.RedirectFromLoginPage(yourUserId, false);

Il définit le cookie d'authentification pour vous, ce qui, combiné à la redirection, est suffisant. Le "false" est pour ne pas persister l'autorisation: il sera perdu à la fermeture du navigateur (ou timeout d'autorisation).

Sur demande déjà authentifiée, il n'y a rien à vérifier par code pour s'assurer que votre authentification est valide. Utilisation Context.User.Identity.Name pour savoir qui est connecté (serait la chaîne yourUserId ci-dessus).

En cas de déconnexion explicite, appelez

FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();

Et avoir l'authentification par formulaire configurée dans web.config.

<system.web>
  <authentication mode="Forms">
    <forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin">
    </forms>
  </authentication>
  <authorization>
    <deny users="?" />
  </authorization>
</system.web>

Notez que pour les applications MVC, la partie autorisation doit être supprimée de la configuration et gérée avec AuthorizeAttribute enregistré comme attribut de filtre global, avec l'utilisation de AllowAnonymousAttribute sur les contrôleurs ou les actions qui en ont besoin. (MVC 4; avant celui-ci, il était nécessaire de créer ses propres attributs pour gérer cela.)

6
Frédéric

Il y a un problème dans votre balise d'autorisation, devrait être:

<authorization>
  <deny users="?" />
  <allow users="*" />
</authorization>

parce que vous souhaitez refuser les utilisateurs anonymes. Si vous corrigez ce problème, vous pouvez supprimer en toute sécurité tous les éléments de la page principale et de global.asax - vous n'avez pas à remapper l'identité des formulaires à votre propre identité personnalisée stockée dans la session. C'est le gaspillage de ressources et je ne pense pas que cela augmente la sécurité de votre solution de manière significative. Vous pouvez compter sur le cookie de formulaires.

2
Wiktor Zychla

Le flux de travail complet pour Remember Me nécessite: 1. Écrivez des données personnalisées dans le cookie. 2. Lisez ces données personnalisées.

Même si vous pouvez authentifier une demande via un cookie, cela ne signifie pas qu'un objet HttpSession peut être repris pour cette demande.

http://www.codeproject.com/Articles/779844/Remember-Me

enter image description here

1
Believe2014