none
comment utiliser l'autentification par Formulaire RRS feed

  • Question

  • Bonjour,

     

    voilà j'ai une application développé en ASP.net et j'aimerai pouvoir instaurer une authentification par Formulaire pour accéder à ses differentes pages.

     

    dans mon cas je dois fixer une liste de users avec leurs mots de passes respectifs et ceci de manière définitives(sans email ni question secrète) , c'est à dire que l'utilisateur ne peut pas changer son mot de passe ni créer son compte par lui même.

     

    ci-dessous un exemple de ce que je voudrai avoir : 

     

    exemple

     

    utilisateur1 ------> profileA --------> accès sur la page1.aspx

    utilisateur1 ------> profileB --------> accès sur la page2.aspx

    utilisateur1 ------> profileA --------> accès sur la page3.aspx

    utilisateur2 ------> profileB --------> accès sur la page2.aspx

     

    il faut savoir que là j'aimerai utiliser deux TextBox classique pour refebrencer les champs user et password (c'est à ditre sans utiliser le controle Login depuis VS 2005).

     

    y a t-il un exemple dédié à créer une table contenant une liste de users avec possibilité d'appartenance à des profiles differents :??

     

     

    merci

     

    Alexy..

    mercredi 23 janvier 2008 11:11

Réponses

  • Bonjour,

    Oui quelque soit le mode d'authentification, le username est accessible via HttpContext.Current.User.Identity.Name ou dans une page via this.User.Identity.Name (qui en interne renvoi HttpContext.Current.User).

    En authentification windows, on récupère le login NT de l'utilisateur.

    En authentification par formulaire, on récupère la chaine passé à la méthode "FormsAuthentication.RedirectFromLoginPage" qui en général est le login de l'utilisateur.

     

    Si vous avez des questions sur l'exemple précédent, n'hésitez pas à les poser. J'essayerai d'y répondre au mieux.

     

    Guillaume

    lundi 28 janvier 2008 15:50
  • Bonjour,

    Etant un peu débordé, je vais vous répondre en plusieurs fois. Voila déjà un exemple permettant de créer une page de login, de configurer l'authentification par formulaire, de gérer les autorisations par utilisateur et stockant les données utilisateur dans le fichier de configuration :

     

    Login.aspx

     

    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="txtLogin" runat="server" />
            <br />
            <asp:TextBox ID="txtPwd" runat="server" TextMode="Password" />
            <br />
            <asp:CheckBox ID="cbxPersistent" runat="server" Text="Remember me" />
            <br />
            <asp:Button ID="btnLogin" runat="server" Text="Login" onclick="btnLogin_Click" />
        </div>
    </form>

     

    Rien de bien compliqué, 2 textbox pour le login et le mot de passe, une checkbox pour demander à l'utilisateur s'il veut sauver les infos dans un cookie persistent et un bouton pour valider.

     

    Login.aspx.cs :

     

    Code Snippet

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

     

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            // valide l'utilisateur avec les données du fichier de config
            if (FormsAuthentication.Authenticate(this.txtLogin.Text, this.txtPwd.Text))
            {
                // place le cookie d'authentification et redirige vers la page voulu
                FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text, this.cbxPersistent.Checked);
            }
        }
    }

     

     

    Dans le clic du bouton, on appel la méthode FormsAuthentication.Authenticate qui va valider le login/mot de passe par rapport aux données du fichier de config. Si les données sont correctes, on place un cookie d'authentification contenant le login de l'utilisateur et on le redirige vers la page demandé ou vers la page par défaut s'il est arrivé sur la page de login directement (voir fichier de config).

     

    web.config :

     

    Code Snippet

    <configuration>
     <appSettings/>
     <connectionStrings/>
     <system.web>
      <compilation debug="true"/>

      <!-- authentification par formulaire -->
      <authentication mode="Forms">
       <forms loginUrl="Login.aspx" defaultUrl="Default.aspx">
        <!-- liste des login/mot de passe -->
        <credentials passwordFormat="Clear">
         <user name="GR" password="GRpwd"/>
         <user name="AL" password="ALpwd"/>
        </credentials>
       </forms>
      </authentication>
      
      <!-- par défaut aucun utilisateur non authentifié ne peut accéder au site -->
      <authorization>
       <deny users="?"/>
      </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise l'utilisateur GR et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>
    </configuration>

     

     

     

    Le fichier de config contient tout le reste, le type d'authentification, les login/mot de passe et les autorisations. Lors qu'asp.net parcours les autorisations, il part de la première ligne et les descend jusqu'a en trouver une applicable, c'est pourquoi il faut toujours terminer par un qui interdit l'accès a tout le monde (sauf si une règle est trouvé avant).

     

    Voila, dès que j'ai le temps je vous envoi un exemple utilisant une base SQL (c'est ce que vous voulez utiliser si j'ai bien compris) et ajoutant des roles. Pour la base, il faudra 3 tables :

    1. User : Id, Login, Pwd
    2. Role : Id, Nom
    3. UserInRole : IdUser, IdRole

    Il faudra remplacer la méthode FormsAuthentication.Authenticate par une fonction custom vérifiant en base et pour les roles, il faudra faire notre propre IPrincipal.

     

    Guillaume

    jeudi 24 janvier 2008 06:29
  • Merci Guillaume,

     

    je trouve l'exemple assez interessant, j'attendrai ton retour concernant l'utilisation de la base Sql server, en attendant je vais essayer cette première méthode utilisant le fichier web.config (xml).

     

    merci à toi

     

    Alexy...

    jeudi 24 janvier 2008 09:59
  • Bonjour,

    Voila la 2ème partie de l'exemple. Je l'ai décomposé en 2 parties :

    • Utilisation d'une base SQL pour authentifier les utilisateurs.
    • Ajout de la notion de roles.

    Pour l'authentification via des données dans une base, il faut dans une table USER contenant 2 colonnes :

    • Login (varchar) : l'identifiant de l'utilisateur, c'est la clé primaire.
    • Pwd (varchar) : le mot de passe de l'utilisateur, il est stocké en clair pour plus de simplicitée.

    Il faut modifier le fichier de config et supprimer le noeud credentials.

    Puis modifier le fichier Login.aspx.cs pour avoir :

     

    Code Snippet

    protected void btnLogin_Click(object sender, EventArgs e)
    {
        // valide l'utilisateur avec les données du fichier de config
        if (this.Authenticate())
        {
            // place le cookie d'authentification et redirige vers la page voulu
            FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text, this.cbxPersistent.Checked);
        }
    }

     

    bool Authenticate()
    {

        using (cnx = new SqlConnexion("votre chaine de connexion"))

        {

            using (cmd = new SqlCommand("SELECT COUNT(*) FROM USER WHERE Login = @Login AND Pwd = @Pwd", cnx))

            {

                // parametres

                cmd.Parameters.Add("@Login", this.txtLogin.Text);

                cmd.Parameters.Add("@Pwd", this.txtPwd.Text);

     

                // si les données sont correctes, COUNT(*) renvoi 1 sinon 0

                return (1 == (int)cmd.ExecuteScalar());

            }

        }
        return (this.txtLogin.Text == this.txtPwd.Text);
    }

     

     

    A ce point, l'authentification passe par vos données en base mais la gestion des droits est toujours sur des utilisateurs et non des roles.

     

    Pour utiliser des roles, il faut ajouter 2 tables dans la base :

    1. ROLE qui va contenir les roles existant et ayant comme colonne :
      • Id (int autoincrement) : l'identifiant du role, c'est la clé primaire.
      • Nom (varchar) : le nom du role
    2. USER_IN_ROLE qui va associer des roles a des utilisateurs :
      • User (varchar) : l'identifiant de l'utilisateur, clé étrangère vers la table USER
      • RoleId (int) : l'identifiant du role, clé étrangère vers la table ROLE
      • La clé primaire est le couple (User, RoleId)

    Il faut modifier le fichier de config pour prendre en compte des roles plutot que des user, pour cela il suffit de changer les noeud en .

     

    Maintenant il faut associer à l'utilisateur authentifier ces roles et ceux la ou ASP.Net va les chercher. ASP.Net va verifier les droits dans la classe IPrincipal via la methode IsInRole. L'objet implementant IPrincipal est un System.Security.Principal.GenericPrincipal et peut être accédé via HttpContext.Current.User. Il va donc falloir mettre à jour cette objet pour en avoir un contenant les rôles de l'utilisateur.

    Pour cela il faut rajouter au site web un fichier Global.asax (c'est une entrée à par dans l'ajout de fichier). On va la modifier pour obtenir le code suivant :

     

    Code Snippet

    <%@ Application Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Security.Principal" %>

    <script runat="server">

        // cette fonction est appelee automatiquement a chaque requete une fois l'authentification effectuee.

        void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.IsAuthenticated)
            {
                GenericPrincipal gp = HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] as GenericPrincipal;
                if (null == gp)
                {
                    using (SqlConnection cnx = new SqlConnection("votre chaine de connexion"))
                    {
                        using (SqlCommand cmd = new SqlCommand("SELECT ROLE.Nom FROM USER_IN_ROLE INNER JOIN ROLE ON ROLE.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.User = @Login"))
                        {
                            // parametres
                            cmd.Parameters.Add("@Login", HttpContext.Current.User.Identity.Name);

                            // recupere les roles
                            using (SqlDataReader dr = cmd.ExecuteReader())
                            {
                                List<string> roles = new List<string>();
                                while (dr.Read())
                                {
                                    roles.Add(dr.GetString(0));
                                }

                                // cree le GenericPrincipal avec les roles lus
                                gp = new GenericPrincipal(
                                    HttpContext.Current.User.Identity
                                    , roles.ToArray()
                                    );
                               
                                // ajoute au cache
                                HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] = gp;
                            }
                        }
                    }
                }

                // on met à jour l'utilisateur courant par le notre.
                if (null != gp)
                {
                    HttpContext.Current.User = gp;
                }
            }
        }
          
    </script>

     

     


    Voila avec tout ca vous avez une authentification utilisant une DB, et une gestion des droits par roles dans la DB aussi.

     

    Guillaume

    dimanche 27 janvier 2008 18:52
  • Bonjour Guillaume,

     

    merci pour ton second envoi, ce n'est pas très claire pour moi mais je vais quand même essayer de le comprendre petit à petit.

     

    dis moi, dans les deux cas c'est à dire soit en utilisant le web.config (ton 1er envoi) soit la base SQL (ton 2ème envoi), comment capturer le username pour biensûr l'enregistrer sur ma base SQL prod.

     

    dois-je utiliser un user.identity.name ?? 

     

    merci à toi

     

    Alexy ..

    lundi 28 janvier 2008 14:42
  • Merci Guillaume,

     

    je vais essayer d'utiliser tout ça sur ma petite application en suivant minutieusement des recommandation, je te rendrai la réponse après.

     

    je te reviendrai aussi par rapport au 2ème point concernant la création de table SQL pour l'authentification avec profile.

     

    merci encore

     

    Alexy..

    mardi 29 janvier 2008 15:36
  •  

    Bonjour Guillaume,

     

    en attendant que je teste la manip avec la BDD concernant l'authentification par formulaire avec profil, je reviens avec toi un peu en arrière et ce pour te demander deux petites choses:

     

    1 - Supposons que j'utilise le fichier web.config pour paramétrer l'ensemble des accès (user/passw), à quelle partie je dois introduire l'URL qui renvoi vers la page qui affiche par exemple "Accès refusé" pour tel ou tel user.

     

    Code Snippet

    <configuration>
     <appSettings/>
     <connectionStrings/>
     <system.web>
      <compilation debug="true"/>

      <!-- authentification par formulaire -->
      <authentication mode="Forms">
       <forms loginUrl="Login.aspx" defaultUrl="Default.aspx">
        <!-- liste des login/mot de passe -->
        <credentials passwordFormat="Clear">
         <user name="GR" password="GRpwd"/>
         <user name="AL" password="ALpwd"/>
        </credentials>
       </forms>
      </authentication>
      
      <!-- par défaut aucun utilisateur non authentifié ne peut accéder au site -->
      <authorization>
       <deny users="?"/>
      </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise l'utilisateur GR et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>
    </configuration>

     

     

    2 - Le second point concerne la captrure du user de chaque utilisateur comme tu me l'as montré avant en utilisant user.identity.name

     

    donc si j'ai bien compris supposons qu'au niveau de ma requete SQL je met :

     

    "INSERT INTO [Table] (champ1) VALUES ('" + user.identity.name + "')"    est-ce correct comme syntaxe ??

     

    en sachant que j'utilise une authentification par formulaire.

     

    merci à toi

     

    Alexy...  

    mercredi 30 janvier 2008 14:21
  • Bonjour,

    Désole pour la réponse tardive.

    • Le mécanisme d'authentification par formulaire d'ASP.Net fait que automatiquement lorsqu'un utilisateur n'a pas les droits sur une page, il est redirigé vers la page de Login (loginUrl). Si vous voulez rediriger un utilisateur déjà identifier vers une page d'accès refusé vous devez le coder vous même dans la page de Login :

    Code Snippet

    protected void Page_Load(object sender, EventArgs e)
    {

    // si l'utilisateur est déjà authentifié, on le redirige vers la page d'accès refusé

    if (this.User.Identity.IsAuthenticated)

    {

    Response.Redirect("~/AccessDenied.aspx");

    }

    }

     

     

    • Pour éviter des problèmes de sécurité (injection SQL), utilisez plutot la syntaxe par paramètre :

    Code Snippet

    SqlCommand cmd = new SqlCommand("INSERT INTO [Table] (champ1) VALUES (@Name)", "<cnx sql>")

    cmd.Parameters.Add(new SqlParameter("@Name", SqlDbType.VarChar));

    cmd.Parameters["@Name"].Value = this.User.Identity.Name;

    cmd.ExecuteNonQuery();

     

     

    Cette syntaxe est correcte quelque soit le mécanisme d'authentification (la votre aussi mais sans la sécurité).

     

    Guillaume

     

    vendredi 1 février 2008 14:12
  • Salut Guillaume,

     

    merci pour ton retour, effectivement l'utilisation des requêtes paramétrée est vbien plus securisant pour le code.

     

    je te reviens là par rapport à la redirection vers une page contenant un text du genre "ACCESS DENIED", là j'ai pas bien compris le fait de programmer tout celà, je m'explique:

     

    supposons dans notre precedent exemple là où tu m'a montré comment donner un accès pour tel ou tel user sur telle ou telle page comme sur le bout de code qui suit:

    -------------------------------------------------------------------------------------------------------------------------------------------

    <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

    -------------------------------------------------------------------------------------------------------------------------------------------

    comment puis-je exprimer le  <deny users="*"/> par une redirection vers une page appelée "accessdenied.aspx", sur le code ci-dessus c'est bien marqué que seuls les users "GR" et "AL" ont le droit d'accès à la "Page1.aspx" et pas les autres users donc tous les autres n'auront pas accès mais sans préciser la nature du message qu'ils auront une fois qu'ils tenteront d'y accéder.

     

    j'attendrai ta réponse

     

    merci ancore

     

    Alexy..  

    vendredi 1 février 2008 19:29
  • Bonjour,

    En fait en authentification forms, on ne peut pas préciser la page vers laquelle on redirige l'utilisateur s'il n'a pas les droits car cette page est automatiquement la page de login. En gros, si un utilisateur n'est pas connecté ou est connecté mais n'a pas les droits nécessaire, il est dans tout les cas redirigé vers la page de login.

    C'est pour cela que tu dois ajouter toi même du code dans la page de login pour rediriger un utilisateur déjà connecté voulant voir la page de login vers une page accessdenied.aspx. En effet si un utilisateur déjà authentifier arrive sur la page de login c'est qu'il a essayé d'accéder à une page dont il n'avait pas les droits.

     

    Guillaume

     

    dimanche 3 février 2008 18:41
  •  

    Bonjour Guillaume,

     

    donc tout se joue au niveau de la page Login si jamais je veux rediriger un utilisateur qui n'as pas de droits d'accès sur telle ou telle page.

     

    je vais tester ça dès que possible et je te reviendrai par un feedback

     

    merci encore

     

    Alexy..

    lundi 4 février 2008 16:00
  • Bonjour,

    Il vaut mieux créer un nouveau post, cela sera plus simple si quelqu'un rencontre le même problème.

     

    Guillaume

     

    dimanche 17 février 2008 20:46

Toutes les réponses

  • Bonjour,

    Etant un peu débordé, je vais vous répondre en plusieurs fois. Voila déjà un exemple permettant de créer une page de login, de configurer l'authentification par formulaire, de gérer les autorisations par utilisateur et stockant les données utilisateur dans le fichier de configuration :

     

    Login.aspx

     

    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="txtLogin" runat="server" />
            <br />
            <asp:TextBox ID="txtPwd" runat="server" TextMode="Password" />
            <br />
            <asp:CheckBox ID="cbxPersistent" runat="server" Text="Remember me" />
            <br />
            <asp:Button ID="btnLogin" runat="server" Text="Login" onclick="btnLogin_Click" />
        </div>
    </form>

     

    Rien de bien compliqué, 2 textbox pour le login et le mot de passe, une checkbox pour demander à l'utilisateur s'il veut sauver les infos dans un cookie persistent et un bouton pour valider.

     

    Login.aspx.cs :

     

    Code Snippet

    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

     

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            // valide l'utilisateur avec les données du fichier de config
            if (FormsAuthentication.Authenticate(this.txtLogin.Text, this.txtPwd.Text))
            {
                // place le cookie d'authentification et redirige vers la page voulu
                FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text, this.cbxPersistent.Checked);
            }
        }
    }

     

     

    Dans le clic du bouton, on appel la méthode FormsAuthentication.Authenticate qui va valider le login/mot de passe par rapport aux données du fichier de config. Si les données sont correctes, on place un cookie d'authentification contenant le login de l'utilisateur et on le redirige vers la page demandé ou vers la page par défaut s'il est arrivé sur la page de login directement (voir fichier de config).

     

    web.config :

     

    Code Snippet

    <configuration>
     <appSettings/>
     <connectionStrings/>
     <system.web>
      <compilation debug="true"/>

      <!-- authentification par formulaire -->
      <authentication mode="Forms">
       <forms loginUrl="Login.aspx" defaultUrl="Default.aspx">
        <!-- liste des login/mot de passe -->
        <credentials passwordFormat="Clear">
         <user name="GR" password="GRpwd"/>
         <user name="AL" password="ALpwd"/>
        </credentials>
       </forms>
      </authentication>
      
      <!-- par défaut aucun utilisateur non authentifié ne peut accéder au site -->
      <authorization>
       <deny users="?"/>
      </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise l'utilisateur GR et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>
    </configuration>

     

     

     

    Le fichier de config contient tout le reste, le type d'authentification, les login/mot de passe et les autorisations. Lors qu'asp.net parcours les autorisations, il part de la première ligne et les descend jusqu'a en trouver une applicable, c'est pourquoi il faut toujours terminer par un qui interdit l'accès a tout le monde (sauf si une règle est trouvé avant).

     

    Voila, dès que j'ai le temps je vous envoi un exemple utilisant une base SQL (c'est ce que vous voulez utiliser si j'ai bien compris) et ajoutant des roles. Pour la base, il faudra 3 tables :

    1. User : Id, Login, Pwd
    2. Role : Id, Nom
    3. UserInRole : IdUser, IdRole

    Il faudra remplacer la méthode FormsAuthentication.Authenticate par une fonction custom vérifiant en base et pour les roles, il faudra faire notre propre IPrincipal.

     

    Guillaume

    jeudi 24 janvier 2008 06:29
  • Merci Guillaume,

     

    je trouve l'exemple assez interessant, j'attendrai ton retour concernant l'utilisation de la base Sql server, en attendant je vais essayer cette première méthode utilisant le fichier web.config (xml).

     

    merci à toi

     

    Alexy...

    jeudi 24 janvier 2008 09:59
  • Bonjour,

    Voila la 2ème partie de l'exemple. Je l'ai décomposé en 2 parties :

    • Utilisation d'une base SQL pour authentifier les utilisateurs.
    • Ajout de la notion de roles.

    Pour l'authentification via des données dans une base, il faut dans une table USER contenant 2 colonnes :

    • Login (varchar) : l'identifiant de l'utilisateur, c'est la clé primaire.
    • Pwd (varchar) : le mot de passe de l'utilisateur, il est stocké en clair pour plus de simplicitée.

    Il faut modifier le fichier de config et supprimer le noeud credentials.

    Puis modifier le fichier Login.aspx.cs pour avoir :

     

    Code Snippet

    protected void btnLogin_Click(object sender, EventArgs e)
    {
        // valide l'utilisateur avec les données du fichier de config
        if (this.Authenticate())
        {
            // place le cookie d'authentification et redirige vers la page voulu
            FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text, this.cbxPersistent.Checked);
        }
    }

     

    bool Authenticate()
    {

        using (cnx = new SqlConnexion("votre chaine de connexion"))

        {

            using (cmd = new SqlCommand("SELECT COUNT(*) FROM USER WHERE Login = @Login AND Pwd = @Pwd", cnx))

            {

                // parametres

                cmd.Parameters.Add("@Login", this.txtLogin.Text);

                cmd.Parameters.Add("@Pwd", this.txtPwd.Text);

     

                // si les données sont correctes, COUNT(*) renvoi 1 sinon 0

                return (1 == (int)cmd.ExecuteScalar());

            }

        }
        return (this.txtLogin.Text == this.txtPwd.Text);
    }

     

     

    A ce point, l'authentification passe par vos données en base mais la gestion des droits est toujours sur des utilisateurs et non des roles.

     

    Pour utiliser des roles, il faut ajouter 2 tables dans la base :

    1. ROLE qui va contenir les roles existant et ayant comme colonne :
      • Id (int autoincrement) : l'identifiant du role, c'est la clé primaire.
      • Nom (varchar) : le nom du role
    2. USER_IN_ROLE qui va associer des roles a des utilisateurs :
      • User (varchar) : l'identifiant de l'utilisateur, clé étrangère vers la table USER
      • RoleId (int) : l'identifiant du role, clé étrangère vers la table ROLE
      • La clé primaire est le couple (User, RoleId)

    Il faut modifier le fichier de config pour prendre en compte des roles plutot que des user, pour cela il suffit de changer les noeud en .

     

    Maintenant il faut associer à l'utilisateur authentifier ces roles et ceux la ou ASP.Net va les chercher. ASP.Net va verifier les droits dans la classe IPrincipal via la methode IsInRole. L'objet implementant IPrincipal est un System.Security.Principal.GenericPrincipal et peut être accédé via HttpContext.Current.User. Il va donc falloir mettre à jour cette objet pour en avoir un contenant les rôles de l'utilisateur.

    Pour cela il faut rajouter au site web un fichier Global.asax (c'est une entrée à par dans l'ajout de fichier). On va la modifier pour obtenir le code suivant :

     

    Code Snippet

    <%@ Application Language="C#" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Security.Principal" %>

    <script runat="server">

        // cette fonction est appelee automatiquement a chaque requete une fois l'authentification effectuee.

        void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.IsAuthenticated)
            {
                GenericPrincipal gp = HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] as GenericPrincipal;
                if (null == gp)
                {
                    using (SqlConnection cnx = new SqlConnection("votre chaine de connexion"))
                    {
                        using (SqlCommand cmd = new SqlCommand("SELECT ROLE.Nom FROM USER_IN_ROLE INNER JOIN ROLE ON ROLE.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.User = @Login"))
                        {
                            // parametres
                            cmd.Parameters.Add("@Login", HttpContext.Current.User.Identity.Name);

                            // recupere les roles
                            using (SqlDataReader dr = cmd.ExecuteReader())
                            {
                                List<string> roles = new List<string>();
                                while (dr.Read())
                                {
                                    roles.Add(dr.GetString(0));
                                }

                                // cree le GenericPrincipal avec les roles lus
                                gp = new GenericPrincipal(
                                    HttpContext.Current.User.Identity
                                    , roles.ToArray()
                                    );
                               
                                // ajoute au cache
                                HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] = gp;
                            }
                        }
                    }
                }

                // on met à jour l'utilisateur courant par le notre.
                if (null != gp)
                {
                    HttpContext.Current.User = gp;
                }
            }
        }
          
    </script>

     

     


    Voila avec tout ca vous avez une authentification utilisant une DB, et une gestion des droits par roles dans la DB aussi.

     

    Guillaume

    dimanche 27 janvier 2008 18:52
  • Bonjour Guillaume,

     

    merci pour ton second envoi, ce n'est pas très claire pour moi mais je vais quand même essayer de le comprendre petit à petit.

     

    dis moi, dans les deux cas c'est à dire soit en utilisant le web.config (ton 1er envoi) soit la base SQL (ton 2ème envoi), comment capturer le username pour biensûr l'enregistrer sur ma base SQL prod.

     

    dois-je utiliser un user.identity.name ?? 

     

    merci à toi

     

    Alexy ..

    lundi 28 janvier 2008 14:42
  • Bonjour,

    Oui quelque soit le mode d'authentification, le username est accessible via HttpContext.Current.User.Identity.Name ou dans une page via this.User.Identity.Name (qui en interne renvoi HttpContext.Current.User).

    En authentification windows, on récupère le login NT de l'utilisateur.

    En authentification par formulaire, on récupère la chaine passé à la méthode "FormsAuthentication.RedirectFromLoginPage" qui en général est le login de l'utilisateur.

     

    Si vous avez des questions sur l'exemple précédent, n'hésitez pas à les poser. J'essayerai d'y répondre au mieux.

     

    Guillaume

    lundi 28 janvier 2008 15:50
  • Merci Guillaume,

     

    je vais essayer d'utiliser tout ça sur ma petite application en suivant minutieusement des recommandation, je te rendrai la réponse après.

     

    je te reviendrai aussi par rapport au 2ème point concernant la création de table SQL pour l'authentification avec profile.

     

    merci encore

     

    Alexy..

    mardi 29 janvier 2008 15:36
  •  

    Bonjour Guillaume,

     

    en attendant que je teste la manip avec la BDD concernant l'authentification par formulaire avec profil, je reviens avec toi un peu en arrière et ce pour te demander deux petites choses:

     

    1 - Supposons que j'utilise le fichier web.config pour paramétrer l'ensemble des accès (user/passw), à quelle partie je dois introduire l'URL qui renvoi vers la page qui affiche par exemple "Accès refusé" pour tel ou tel user.

     

    Code Snippet

    <configuration>
     <appSettings/>
     <connectionStrings/>
     <system.web>
      <compilation debug="true"/>

      <!-- authentification par formulaire -->
      <authentication mode="Forms">
       <forms loginUrl="Login.aspx" defaultUrl="Default.aspx">
        <!-- liste des login/mot de passe -->
        <credentials passwordFormat="Clear">
         <user name="GR" password="GRpwd"/>
         <user name="AL" password="ALpwd"/>
        </credentials>
       </forms>
      </authentication>
      
      <!-- par défaut aucun utilisateur non authentifié ne peut accéder au site -->
      <authorization>
       <deny users="?"/>
      </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise l'utilisateur GR et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>
    </configuration>

     

     

    2 - Le second point concerne la captrure du user de chaque utilisateur comme tu me l'as montré avant en utilisant user.identity.name

     

    donc si j'ai bien compris supposons qu'au niveau de ma requete SQL je met :

     

    "INSERT INTO [Table] (champ1) VALUES ('" + user.identity.name + "')"    est-ce correct comme syntaxe ??

     

    en sachant que j'utilise une authentification par formulaire.

     

    merci à toi

     

    Alexy...  

    mercredi 30 janvier 2008 14:21
  • Bonjour,

    Désole pour la réponse tardive.

    • Le mécanisme d'authentification par formulaire d'ASP.Net fait que automatiquement lorsqu'un utilisateur n'a pas les droits sur une page, il est redirigé vers la page de Login (loginUrl). Si vous voulez rediriger un utilisateur déjà identifier vers une page d'accès refusé vous devez le coder vous même dans la page de Login :

    Code Snippet

    protected void Page_Load(object sender, EventArgs e)
    {

    // si l'utilisateur est déjà authentifié, on le redirige vers la page d'accès refusé

    if (this.User.Identity.IsAuthenticated)

    {

    Response.Redirect("~/AccessDenied.aspx");

    }

    }

     

     

    • Pour éviter des problèmes de sécurité (injection SQL), utilisez plutot la syntaxe par paramètre :

    Code Snippet

    SqlCommand cmd = new SqlCommand("INSERT INTO [Table] (champ1) VALUES (@Name)", "<cnx sql>")

    cmd.Parameters.Add(new SqlParameter("@Name", SqlDbType.VarChar));

    cmd.Parameters["@Name"].Value = this.User.Identity.Name;

    cmd.ExecuteNonQuery();

     

     

    Cette syntaxe est correcte quelque soit le mécanisme d'authentification (la votre aussi mais sans la sécurité).

     

    Guillaume

     

    vendredi 1 février 2008 14:12
  • Salut Guillaume,

     

    merci pour ton retour, effectivement l'utilisation des requêtes paramétrée est vbien plus securisant pour le code.

     

    je te reviens là par rapport à la redirection vers une page contenant un text du genre "ACCESS DENIED", là j'ai pas bien compris le fait de programmer tout celà, je m'explique:

     

    supposons dans notre precedent exemple là où tu m'a montré comment donner un accès pour tel ou tel user sur telle ou telle page comme sur le bout de code qui suit:

    -------------------------------------------------------------------------------------------------------------------------------------------

    <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

    -------------------------------------------------------------------------------------------------------------------------------------------

    comment puis-je exprimer le  <deny users="*"/> par une redirection vers une page appelée "accessdenied.aspx", sur le code ci-dessus c'est bien marqué que seuls les users "GR" et "AL" ont le droit d'accès à la "Page1.aspx" et pas les autres users donc tous les autres n'auront pas accès mais sans préciser la nature du message qu'ils auront une fois qu'ils tenteront d'y accéder.

     

    j'attendrai ta réponse

     

    merci ancore

     

    Alexy..  

    vendredi 1 février 2008 19:29
  • Bonjour,

    En fait en authentification forms, on ne peut pas préciser la page vers laquelle on redirige l'utilisateur s'il n'a pas les droits car cette page est automatiquement la page de login. En gros, si un utilisateur n'est pas connecté ou est connecté mais n'a pas les droits nécessaire, il est dans tout les cas redirigé vers la page de login.

    C'est pour cela que tu dois ajouter toi même du code dans la page de login pour rediriger un utilisateur déjà connecté voulant voir la page de login vers une page accessdenied.aspx. En effet si un utilisateur déjà authentifier arrive sur la page de login c'est qu'il a essayé d'accéder à une page dont il n'avait pas les droits.

     

    Guillaume

     

    dimanche 3 février 2008 18:41
  •  

    Bonjour Guillaume,

     

    donc tout se joue au niveau de la page Login si jamais je veux rediriger un utilisateur qui n'as pas de droits d'accès sur telle ou telle page.

     

    je vais tester ça dès que possible et je te reviendrai par un feedback

     

    merci encore

     

    Alexy..

    lundi 4 février 2008 16:00
  • Salut Guillaume,

     

    désolé pour ce retard, c'est que j'étais très très occupé et pas le moindre temps pour venir sur le Forum.

     

    je tiens à te remercier pour tes lumières, j'ai pu tester tout ce qui concerne l'authentification (par XML) et ça fonctionne Nikel  alors je te dit merci Bcpppp.

     

    là j'ai un petit souci avec l'affichage de la Date sur une TextBox (la date est lu depuis ma BD) là je ne sais pas si je poste ici ou bien j'ouvre un autre ticket.

     

    merci encore

     

    Alexy ..

    dimanche 17 février 2008 15:17
  • Bonjour,

    Il vaut mieux créer un nouveau post, cela sera plus simple si quelqu'un rencontre le même problème.

     

    Guillaume

     

    dimanche 17 février 2008 20:46
  • Pas de souci Guillaume

     

    rendez-vous alors sur un autre post.


    Merci

     

    Alexy .. 

    lundi 18 février 2008 07:46
  • Bonjour Guillaume,

     

    Sorry si je te reviens sur ce poste, je voudrai te demander dès qu'on utilise l'authentification par formulaire utilisant un fichier XML (web.config), est-il possible d'instaurer un mécanisme de changement de mot de passe pour les utilisateurs ?? ou bien cette procédure n'est valable qu'en utilisant une BD??

     

    merci à toi

     

    Alexy.. 

    jeudi 6 mars 2008 10:38
  • Bonjour,

    Il est toujours possible de changer le mot de passe mais celui-ci se trouvant dans le fichier de configuration (web.config), cela veut dire mettre à jour le fichier web.config.

    Si tu veux voir comment le faire, voila un post parlant de la mise à jour du fichier de configuration via le code :

     

    http://forums.microsoft.com/MSDN-FR/ShowPost.aspx?PostID=2867913&SiteID=12

     

    Mais en règle générale, il faut éviter de modifier le fichier de configuration car sur un site ASP.Net en marche, cela entraine un reboot du worker process et donc la perte des données (sessions, application, cache, ...).

     

    Guillaume

    jeudi 6 mars 2008 11:00
  • Merci Guillaume,

     

    donc si j'ai bien compris, il vaut mieu de faire en utilisant la deuxième méthode (BDD Sql Server)

     

    Alexy..

     

    jeudi 6 mars 2008 11:19
  • Bonjour,

    Effectivement la gestion des droits via une base de données est quand même plus souple et évolutive qu'en dure dans le fichier de configuration.

    Si vous pouvez mettre en place une solution à base d'un BDD, je vous la recommande.

     

    Guillaume

    jeudi 6 mars 2008 11:41
  • merci guillome pour ton aide.c'est la première fois que je me lance dans ce genre de discussion.je viens de me lancer dans mon projet de fin d'étude en utilisant asp.net sans y avoir aucune idée, bon j'ai appris beaucoup de chose mais bon,j'ai toujours des difficultés.
    je veux utiliser ta deuxième méthode(l'utilisation de la base sql server) mais il y a des trucs que j'ai pas compris:
    - quesque tu veux dire par "
    supprimer le noeud credentials"   et par "suffit de changer les noeud en "

    encore une chose si c'est possible,je vais créer une application avec plusieurs pages,la navigation entre ces pages sera en utilisant un menu,chaque groupe d'utilisateur aura accès à certaines pages et pas d'autres,comment je peux gerér ça.

    s'il vous pouvez m'envoyer des documents qui pourront m'aider je serai vraiment ravi. mon msn est: mr.sayfoun@hotmail.com

    j'attenndrai ta réponse avec impatience

    merci pour tout
    lundi 14 avril 2008 23:24
  • Bonjour,

    Si vous utilisez une authentification basée sur une base, votre fichier de configuration doit ressembler à cela :

     

    Code Snippet

    <configuration>
     <appSettings/>
     <connectionStrings/>
     <system.web>
      <compilation debug="true"/>

      <!-- authentification par formulaire -->
      <authentication mode="Forms">
       <forms loginUrl="Login.aspx" defaultUrl="Default.aspx">

       </forms>
      </authentication>
      
      <!-- par défaut aucun utilisateur non authentifié ne peut accéder au site -->
      <authorization>
       <deny users="?"/>
      </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
      <system.web>
       <!-- pour la Page1.aspx on autorise les roles Admins et Members et on refuse tous les autres -->
       <authorization>
        <allow roles="Admins,Members"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise le role Admins et on refuse tous les autres -->
       <authorization>
        <allow roles="Admins"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>
    </configuration>

     

     

    Il n'y a plus dans ce fichier de noeuds "credentials" comme pour la première méthode.

    Concernant le 2ème points, il y a eu un problème lors du post, la phrase voulait dire qu'il faut remplacer les noeuds allow users="..." par allow roles="..." (c'est ce que j'ai fait dans l'exemple ci dessus).

     

    Comme vous pouvez le voir dans l'exemple ci dessus la gestion des droits peut se faire page par page. Vous pouvez aussi utiliser la même syntaxe pour donner des droits sur toutes pages d'un répertoire, par exemple AdminPages, en utilisant la syntaxe suivante :

     

    location path="AdminPages"

     

    mardi 15 avril 2008 08:34
  • merci énormément pour ton aide et surtout pour avoir répondre si vite.c'est assez clair,je vais suivre tes conseils et l'exemple que tu as posté.
    en fait je suis un jeune étudiant tunisien,j'ai fait expret de choisir la plateforme dot.net pour mon projet de fin d'étude sans la connaitre pour prouver à mes prof que les mauvaises notes que j'ai eu cette année ne refléte pas mes moyen.

    encore 1000 merci
    mardi 15 avril 2008 08:52
  •  mr.sayfoun A écrit:
    merci énormément pour ton aide et surtout pour avoir répondre si vite.c'est assez clair,je vais suivre tes conseils et l'exemple que tu as posté.
    en fait je suis un jeune étudiant tunisien,j'ai fait expret de choisir la plateforme dot.net pour mon projet de fin d'étude sans la connaitre pour prouver à mes prof que les mauvaises notes que j'ai eu cette année ne refléte pas mon niveau et ce que je peux faire.

    encore 1000 merci
    mardi 15 avril 2008 08:55
  • me revoilà si vite.je veux que l'administrateur de cette application gére l'autorisation des rôles pour les pages dans une page  que je créerai au lieu de le faire dans le fichier de configuration,il me parait que c'est possible.
    je mexplique:

    si j'ai dans le fichier de configuration cette autorisation
    <location path="Page1.aspx">
      <system.web>
       <authorization>
        <allow roles="Members"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>


    et qu'un jour l'administrateur de site veut retirer cette autorisation à ce rôle et l'attribuer à un autre rôle?!!!
    comment je peux le faire
    mardi 15 avril 2008 09:43
  • Bonjour,

    Si vous voulez pouvoir gérer de manière programmatique les authorisations, il faut laisser tomber le fichier de configuration et développer le tout vous même en ajoutant en base les rôles, les pages et les relations indiquant quels roles on accès à quelles pages. Puis dans votre code, dans la méthode Application_AuthenticateRequest par exemple, tester si l'utilisateur courant à le droits d'accéder à la page demandée.

    Dans ce cas je vous conseillerai, si vous le pouvez, d'utiliser la notion de Membership ajoutée dans le Framework .Net 2.0 :

     

    http://msdn2.microsoft.com/fr-fr/library/system.web.security.membership(VS.80).aspx

    http://msdn2.microsoft.com/fr-fr/library/5k850zwb(VS.80).aspx

    mardi 15 avril 2008 13:32
  • j'ai lu ces deux articles et même d'autre article de la bibliothèque de microsoft,mais malheureusement j'ai pas compris grande chose,j'ai compris l'idée mais j'ai pas pu appliquer,est ce que tu peux me fournir un exemple à suivre,une documentation sur les memberships,un cours ou n'importe quoi qui peut m'aider. j'ai passé beaucoup de temps à chercher et à lire sur ce sujet mais rien d'intéressant et je veux vraiment l'utiliser dans mon projet. j'espère que t'as d'autre chose à me fournir.
    mardi 15 avril 2008 13:47
  • Bonjour,

    Scott Mitchell a écrit une série de post sur son blog sur l'utilisation des Membership :

     

    http://aspnet.4guysfromrolla.com/articles/120705-1.aspx

    mardi 15 avril 2008 14:34
  • Merci de me répondre si vite mais franchement l'anglais c'est pas mon truc.
    y a-t-il d'autres solutions????????????????????????????????????????

    j'espère que je te dérange pas trop,mais j'ai pas d'autre choix.

    merci Monsieur.
    mardi 15 avril 2008 14:42
  • Bonjour,

    Malheureusement je ne connais pas de tutoriel en français autre que les bout de code que l'on trouve dans la MSDN sur les différentes classes du système de Membership.

    mardi 15 avril 2008 15:34
  • salut,

    Merci quand meme guillaume,t'as déja beaucoup fait.
    si tu retombes par hasard sur quelque chose qui peut m'aider n'hésite pas à la poster ou si tu trouves une autre chose fais moi signe.

    encore merci et bonne soirée
    mardi 15 avril 2008 16:47
  • Bonjour guillaume,

    je veux que tu me vérifies le code que j'ai utilisé car j'ai changé un peu ce que tu m'as dit de faire.ça fonctionne mais parfois ça marche pas du 1er coup,il faut un 2ème essai (je parle de ma page Login.aspx.cs:
    j'ai fait cela:

    protected void btnLogin_Click(object sender, EventArgs e)
        {
            if (this.Authenticate())
            {
               FormsAuthentication.SetAuthCookie(this.txtLogin.Text,true);
      //  redirection selon le role :
                if (this.User.IsInRole("actel"))
                    Response.Redirect("page1.aspx");
                else
                {
                    if (this.User.IsInRole("noc"))
                        Response.Redirect("page2.aspx");
                }
            }
        }


    1-  j'ai remplacé :
       FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text,false);
         par :
       FormsAuthentication.SetAuthCookie(this.txtLogin.Text,true);
    pour choisir la redirection.
    est-ce que c'est juste?(si non,qu'elle est la différence?)

    2-parfois ça marche dès le 1er coup,et parfois j'ai celà:

    http://localhost/TTFR05C/Login.aspx?ReturnUrl=%2fTTFR05C%2fpage1.aspx
    alors que je dois me rediriger vers la page "page2.aspx" (il a le role noc)



    encore une chose,supposons que je m'authentifie et que je passe à ma page suivante,puis j'utilise le flèche du navigateur pour revenir à la page précédente qui est la page de connexion(je pense pas que c'est un load de la page login):
    l'utilisateur n'est pas déconnecté,non?
    comment tu me conseilles de gérer cette situation?

    j'attendrai tes commentaires qui me seront précieux et ta correction si c'est possible.



    mardi 22 avril 2008 08:54
  • Bonjour,

    Votre problème vient du fait que la méthode Authenticate vérifie juste si les données d'authentification sont correctes mais elle ne crée pas l'utilisateur. C'est la méthode Application_AuthenticateRequest qui charge effectivement les données de l'utilisateur enregistrée et ceux en début de traitement de la page.

    Dans votre cas, ce traitement est déjà passé et n'a pas chargé des données. Les tests sur this.User.IsInRole ne vont donc pas être correcte.

    Si vous voulez utiliser la logique que vous exposé, il faudrait externaliser le code la méthode  Application_AuthenticateRequest dans une classe et appeler cette nouvelle méthode aussi dans le Authenticate si l'authentification à réussi.

     

    mardi 22 avril 2008 12:39
  • salut,

    Merci pour ta réponse.
    En fait j'ai externalisé le code la méthode Application_AuthenticateRequest  dans le fichier global.asax:

    void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.IsAuthenticated)
            {
                System.Security.Principal.GenericPrincipal gp = HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] as System.Security.Principal.GenericPrincipal;
                if (null == gp)
                {
                    using (System.Data.SqlClient.SqlConnection cnx = new System.Data.SqlClient.SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
                    {
                        cnx.Open();
                        using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT AROLE.Nom FROM USER_IN_ROLE INNER JOIN AROLE ON AROLE.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.AUser = @Login",cnx))
                        {
                            // parametres
                            cmd.Parameters.Add("@Login", HttpContext.Current.User.Identity.Name);

                            // recupere les roles
                            using (System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader())
                            {
                                System.Collections.Generic.List<string> roles = new System.Collections.Generic.List<string>();
                                while (dr.Read())
                                {
                                    roles.Add(dr.GetString(0));
                                }

                                // cree le GenericPrincipal avec les roles lus
                                gp = new System.Security.Principal.GenericPrincipal(
                                    HttpContext.Current.User.Identity
                                    , roles.ToArray()
                                    );
                              
                                // ajoute au cache
                                HttpContext.Current.Cache[HttpContext.Current.User.Identity.Name] = gp;
                            }
                        }
                    }
                }

                // on met à jour l'utilisateur courant par le notre.
                if (null != gp)
                {
                    HttpContext.Current.User = gp;
                }
            }
        }


    est ce que tu peux me dire comment l'utiliser dans le fichier login.aspx.cs?

    et à propos de mon utilisation de :
                FormsAuthentication.SetAuthCookie(this.txtLogin.Text, true);
    au lieu de :
          FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text,false);*/
      c'est juste???

    j'espère que je demande pas trop,mais si c'est le cas réponds moi sur ce que tu peux.
    encore merci
    bonne soirée
    mardi 22 avril 2008 16:25
  • Bonjour,

    Vous pouvez effectivement utiliser FormsAuthentication.SetAuthCookie au lieu de FormsAuthentication.RedirectFromLoginPage. En fait la méthode RedirectFromLoginPage fait en interne un SetAuthCookie mais aussi bien plus (vérification que le navigateur supporte les cookies, sinon la méthode passe par un autre mécanisme que les cookies et redirection vers la page d'ou l'utilisateur vient).

     

    Sinon voila un exemple de comme vous pouvez sortir la récupération de l'utilisateur et l'utiliser :

     

    Classe AuthenticationHelper : permet de charger les données utilisateur

     

    Code Snippet

    using System.Collections.Generic;
    using System.Data.SqlClient
    using System.Security.Principal;

    using System.Web;


    public static class AuthenticationHelper
    {
        public static GenericPrincipal SetCurrentUser(string userId)
        {
            GenericPrincipal gp = HttpContext.Current.Cache[userId] as GenericPrincipal;
            if (null == gp)
            {
                using (SqlConnection cnx = new SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
                {
                    cnx.Open();
                    using (SqlCommand cmd = new SqlCommand("SELECT AROLE.Nom FROM USER_IN_ROLE INNER JOIN AROLE ON AROLE.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.AUser = @Login",cnx))
                    {
                        // parametres
                        cmd.Parameters.Add("@Login", userId);

                        // recupere les roles
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {
                            List roles = new List();
                            while (dr.Read())
                            {
                                roles.Add(dr.GetString(0));
                            }

                            // cree le GenericPrincipal avec les roles lus
                            gp = new GenericPrincipal(
                                new GenericIdentity(userId)
                                , roles.ToArray()
                                );

                            // ajoute au cache
                            HttpContext.Current.Cache[userId] = gp;
                        }
                    }
                }
            }

            // on met à jour l'utilisateur courant par le notre.
            if (null != gp)
            {
                HttpContext.Current.User = gp;
            }
        }
    }

     

    Ensuite dans le global.asax :

     

    Code Snippet
    void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.IsAuthenticated)
        {
            AuthenticationHelper.SetCurrentUser(HttpContext.Current.User.Identity.Name);
        }
    }

     

     

    Puis dans votre page de login dans la méthode Authenticate :

     

    Code Snippet

    bool Authenticate()
    {
        using (SqlConnexion cnx = new SqlConnexion("votre chaine de connexion"))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM USER WHERE Login = @Login AND Pwd = @Pwd", cnx))
            {
                // parametres
                cmd.Parameters.Add("@Login", this.txtLogin.Text);
                cmd.Parameters.Add("@Pwd", this.txtPwd.Text);

                // si les données sont correctes, COUNT(*) renvoi 1 sinon 0
                if (0 == (int)cmd.ExecuteScalar())
                {
                    return false;
                }
               
                // charge les données de l'utilisateur authentifié
                AuthenticationHelper.SetCurrentUser(this.txtLogin.Text);
               
                return true;
            }
        }
    }

     

     

    mercredi 23 avril 2008 08:14
  •  

    bonjour guillaume,

     

    merci pour tout.

     

    bonne journée

    mercredi 23 avril 2008 08:28
  • roles.add(dr.GetString(0));

     'System.Web.UI.MobileControls.List' ne contient pas de définition pour 'add' 

    roles.ToArray()

     'System.Web.UI.MobileControls.List' ne contient pas de définition pour 'ToArray' 
    mercredi 23 avril 2008 09:12
  • Petite erreur du forum lors du post (passage en code snippet). La ligne :

     

    List roles = new List();

     

    est en fait

     

    List<string> roles = new List<string>();

    mercredi 23 avril 2008 11:10
  •  public static System.Security.Principal.GenericPrincipal SetCurrentUser(string userId)
    génère l'erreur suivante:

    'ASP.global_asax.AuthenticationHelper.SetCurrentUser(string)' : tous les chemins de code ne retournent pas nécessairement une valeur  

    mercredi 23 avril 2008 12:08
  • Oups, ça m'apprendra à mettre des exemples sans les tester avant :

     

    Code Snippet

    public static class AuthenticationHelper
    {
        public static void SetCurrentUser(string userId)
        {
            GenericPrincipal gp = HttpContext.Current.Cache[userId] as GenericPrincipal;
            if (null == gp)
            {
                using (SqlConnection cnx = new SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
                {
                    cnx.Open();
                    using (SqlCommand cmd = new SqlCommand("SELECT AROLE.Nom FROM USER_IN_ROLE INNER JOIN AROLE ON AROLE.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.AUser = @Login",cnx))
                    {
                        // parametres
                        cmd.Parameters.Add("@Login", userId);

                        // recupere les roles
                        using (SqlDataReader dr = cmd.ExecuteReader())
                        {
                            List roles = new List();
                            while (dr.Read())
                            {
                                roles.Add(dr.GetString(0));
                            }

                            // cree le GenericPrincipal avec les roles lus
                            gp = new GenericPrincipal(
                                new GenericIdentity(userId)
                                , roles.ToArray()
                                );

                            // ajoute au cache
                            HttpContext.Current.Cache[userId] = gp;
                        }
                    }
                }
            }

            // on met à jour l'utilisateur courant par le notre.
            if (null != gp)
            {
                HttpContext.Current.User = gp;
            }
        }
    }

     

     

     

    mercredi 23 avril 2008 12:15
  • ça maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarche

    je te remercie cher guillaume,t'es vraiment génial.

    j'apprends de toi et ça me fait plaisir

    bye
    mercredi 23 avril 2008 12:24
  • slt,

    1-quand je ferme une fenetre de mon application l'utilisateur n'est pas déconnecté(logique).
    j'ai fait quelque recherche et j'ai trouvé qu'on doit gérer ça avec du javascript pour déconnecter l'utilisateur.est elle la meilleur solution?y a-t-il d'autres solutions (je connais pas javascript).

    samedi 3 mai 2008 13:31
  • Bonjour,

    Si vous voulez que dès que l'utilisateur ferme son navigateur il soit déconnecté, il faut utiliser la méthode SetAuthCookie avec les paramètres suivant :

     

    Code Snippet

    FormsAuthentication.SetAuthCookie(this.txtLogin.Text, false);

     

     

    Le dernier paramètre spécifie si le cookie est gardé par le navigateur lorsque celui-ci est fermé, false indique que le cookie n'est disponible que jusqu'à la fermeture du navigateur.

    dimanche 4 mai 2008 05:47
  • Re Bonjour Guillaume,

     

    je reviens vers toi au niveau de ce post et comme tu le vois cette fois-ci ça concerne l'authentification Windows et pas celle par formulaire,

     

    en effet je viens de faire un test sur de mes pages en inscrivant ce qui suit:

     

    Code Snippet

    Lbluser.Text = this.User.Identity.Name; ou encore

    Lbluser.Text = HttpContext.Current.User.Identity.Name;

     

     

     

    en sachant que la case "Authentification Windows intégrée" est bien activé au niveau du serveur IIS.

     

    après tout celà je n'ai rien eu comme affichage, le label Lbluser n'affiche rien.

     

    ai-je oublié quelque chose??

     

    merci à toi

     

    Alexy

    jeudi 22 mai 2008 15:12

  • Tout d'abord je vous remercie pour cette discussion et ces réponses enrichissantes qui ont éclaircit mes idées surtout que je suis débutant dans le développement en asp.net

    j'ai suivi les réponses. j'ai instauré une authentification par formulaire et elle marche parfaitement.

    J'ai ajouté le fichier Global.asax, comme a dit Guillaume

    Mon problème maintenant est comment tester si l'utilisateur a le droit d'accéder à la page demandée

    Bref je veux avoir l'equivalent du résultat de ce code mais en le programmant moi même et en utilisant ma base de données.

    Code Snippet

    <authorization>
       <deny users="?"/>
    </authorization>
     </system.web>

     <!-- on personnalise les autorisations par page -->
     <location path="Page1.aspx">
     <system.web>
       <!-- pour la Page1.aspx on autorise les utilisateurs GR et AL et on refuse tous les autres -->
     authorization>
        <allow users="GR"/>
        <allow users="AL"/>
        <deny users="*"/>
    </authorization>
     </system.web>
     </location>

     <location path="Page2.aspx">
      <system.web>
       <!-- pour la Page2.aspx on autorise l'utilisateur GR et on refuse tous les autres -->
       <authorization>
        <allow users="GR"/>
        <deny users="*"/>
       </authorization>
      </system.web>
     </location>


    J'espère que je me suis bien exprimé, je serai très recannaissant si vous pourriez m'aider
    jeudi 22 mai 2008 17:17
  • slt,

    guillaume l'a déja expliqué dans la première page:

    Pour utiliser des roles, il faut ajouter 2 tables dans la base :

    1. ROLE qui va contenir les roles existant et ayant comme colonne :
      • Id (int autoincrement) : l'identifiant du role, c'est la clé primaire.
      • Nom (varchar) : le nom du role
    2. USER_IN_ROLE qui va associer des roles a des utilisateurs :
      • User (varchar) : l'identifiant de l'utilisateur, clé étrangère vers la table USER
      • RoleId (int) : l'identifiant du role, clé étrangère vers la table ROLE
      • La clé primaire est le couple (User, RoleId

    bien sur sans oublier la table des user.
    ensuite tu affectes à chaque user un role
    et le reste dans la page 3,bon je vais vous passer mon code final qui marche pour vous faire gagner du temps:

    Global.asax:

    <%@ Application Language="C#" %>
    <script runat="server">
       public static class AuthenticationHelper
        {
            public static void SetCurrentUser(string userId)
            {
                System.Security.Principal.GenericPrincipal gp = HttpContext.Current.Cache[userId] as System.Security.Principal.GenericPrincipal;
                if (null == gp)
                {
                    using (System.Data.SqlClient.SqlConnection cnx = new System.Data.SqlClient.SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
                    {
                        cnx.Open();
                        using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT Arole.nom FROM USER_IN_ROLE INNER JOIN Arole ON Arole.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.Auser = @Login", cnx))
                        {
                            // parametres
                            cmd.Parameters.Add("@Login", userId);

                            // recupere les roles
                           
                            using (System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader())
                            {
                                //System.Collections.Generic.List<string>;
                                System.Collections.Generic.List<string> roles = new System.Collections.Generic.List<string>();
                                while (dr.Read())
                                {
                                    roles.Add(dr.GetString(0));
                                }

                               
                               
                                // cree le GenericPrincipal avec les roles lus
                                gp = new System.Security.Principal.GenericPrincipal(
                                    new System.Security.Principal.GenericIdentity(userId)
                                    , roles.ToArray()
                                    );

                                // ajoute au cache
                                HttpContext.Current.Cache[userId] = gp;
                            }
                        }
                    }
                }

                // on met à jour l'utilisateur courant par le notre.
                if (null != gp)
                {
                    HttpContext.Current.User = gp;
                }
            }
        }
        void Application_Start(object sender, EventArgs e)
        {
            // Code that runs on application startup

        }
       
        void Application_End(object sender, EventArgs e)
        {
            //  Code that runs on application shutdown

        }
           
        void Application_Error(object sender, EventArgs e)
        {
            // Code that runs when an unhandled error occurs

        }
       
        void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (HttpContext.Current.Request.IsAuthenticated)
            {
                AuthenticationHelper.SetCurrentUser(HttpContext.Current.User.Identity.Name);
            }
        }

     

        void Session_Start(object sender, EventArgs e)
        {
            // Code that runs when a new session is started

        }

        void Session_End(object sender, EventArgs e)
        {
            // Code that runs when a session ends.
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer
            // or SQLServer, the event is not raised.

        }
          
    </script>

    Login.aspx.cs:
    public static class AuthenticationHelper
        {
     
            public static void SetCurrentUser(string userId)
            {
               
                System.Security.Principal.GenericPrincipal gp = HttpContext.Current.Cache[userId] as System.Security.Principal.GenericPrincipal;
                if (null == gp)
                {
                    using (System.Data.SqlClient.SqlConnection cnx = new System.Data.SqlClient.SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
                    {
                        cnx.Open();
                        using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("SELECT Arole.nom FROM USER_IN_ROLE INNER JOIN Arole ON Arole.Id = USER_IN_ROLE.RoleId WHERE USER_IN_ROLE.Auser = @Login", cnx))
             ///Arole est ma table role

                        {
                            // parametres
                            cmd.Parameters.Add("@Login", userId);
                           
                            // recupere les roles
                           
                            using (System.Data.SqlClient.SqlDataReader dr = cmd.ExecuteReader())
                            {
                                //System.Collections.Generic.List<string>;
                                System.Collections.Generic.List<string> roles = new System.Collections.Generic.List<string>();
                                while (dr.Read())
                                {
                                    roles.Add(dr.GetString(0));
                                }

                               
                               
                                // cree le GenericPrincipal avec les roles lus
                                gp = new System.Security.Principal.GenericPrincipal(
                                    new System.Security.Principal.GenericIdentity(userId)
                                    , roles.ToArray()
                                    );

                                // ajoute au cache
                                HttpContext.Current.Cache[userId] = gp;
                            }
                        }
                    }
                }

                // on met à jour l'utilisateur courant par le notre.
                if (null != gp)
                {
                    HttpContext.Current.User = gp;
                }
            }
        }
    public partial class Login : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            FormsAuthentication.SignOut();
            txtLogin.Focus();
        }
        protected void btnLogin_Click(object sender, EventArgs e)
        {
            // valide l'utilisateur avec les données du fichier de config
            //Authenticate est une méthode de FormsAuthentication:Essaie de valider les informations d'authentification
            //à partir du magasin des informations d'authentification configurées, compte tenu des informations d'authentification fournies.
            if (this.Authenticate())
            {
               FormsAuthentication.SetAuthCookie(this.txtLogin.Text, true);
                if (this.User.IsInRole("ractel"))  ///ractel:est un role
                    Response.Redirect("Actel/NI.aspx");
                else
                {
                    if (this.User.IsInRole("rnoc"))   ///rnoc est un role
                        Response.Redirect("Noc/NIP.aspx");
                    else
                        if (this.User.IsInRole("rnos"))
                            Response.Redirect("Ionos/NIP.aspx");
                }
            }
        }
        bool Authenticate()
        {
           
            IDataReader dr;
         
            using (SqlConnection cnx = new SqlConnection("server=IND_PC\\TTSQLSERVER;database=TTFR;uid=sa;pwd=TTFR"))
            {
                cnx.Open();
                using (SqlCommand cmd = new SqlCommand("SELECT agence FROM AGENT WHERE Login=@Login AND Pwd =@Pwd",cnx))//SELECT COUNT(*) FROM AGENT WHERE Login = @Login AND Pwd = @Pwd", cnx))
        ////Agent est ma table user
                {
                    // parametres
                    cmd.Parameters.Add("@Login", this.txtLogin.Text);
                    cmd.Parameters.Add("@Pwd", this.txtPwd.Text);
                    dr = cmd.ExecuteReader();
                    // si les données sont correctes, COUNT(*) renvoi 1 sinon 0
                    //if (0 == (int)cmd.ExecuteScalar())
                    if (!dr.Read())
                    {
                        return false;
                    }

                    // charge les données de l'utilisateur authentifié
                    ASP.global_asax.AuthenticationHelper.SetCurrentUser(this.txtLogin.Text);
                    Session["agence"] = dr.GetString(0);
                   
                    return true;
                }
            }
        }
    }

    je suis encore débutant,voici mon msn:  mr.sayfoun@hotmail.fr
    bon courage et bonne chance
    jeudi 22 mai 2008 19:28

  • Merci beaucoup mr.sayfoun

    mais j'ai quelques questions pour toi

    Code Snippet

    protected void Page_Load(object sender, EventArgs e)
    {
      FormsAuthentication.SignOut();
      txtLogin.Focus();

    }


    pouquoi t'as ajouté ces lignes dans page_load?

    et dans ton application les roles sont fixes? et le jour où on veut ajouter ou supprimer un role ou modifier l'accès authorisé d'un role
    qu'est-ce qu'on fait?

    en faite c'est ça  mon problème, dans mon application j'ai l'administrateur qui peut affecter des roles à des utilisateurs et peut ajouter,modifier ou supprimer un role et doit encore affecter à chaque role la ou les pages qu'il a le droit d'y accéder.

    donc en plus des deux tables USER et USER_IN_ROLE j'ai une table qui contient (ID_ROLE, ID_PAGE) et une autre table contenant (ID_PAGE,PAGE.ASPX)

    ça peut paraitre un peut compliqué mais il me faut juste une methode qui teste si l'utilisateur authentifié a le droit d'accéder à la page qu'il vient de demander ( car même si je dirige l'utilisateur dès son authanetification  il peut demander après l'accès à une autre page qu'il n'a pas le droit d'y accéder)

    j'espère que vous m'avez compris et que quelqu'un puisse m'aider
    jeudi 22 mai 2008 21:13
  • désolé mais ces lignes je les ai utilisées pour un test,tu peux les supprimer.par contre tu dois modifier le true par false dans cette ligne   FormsAuthentication.SetAuthCookie(this.txtLogin.Text, true); de la fonction :
    protected void btnLogin_Click(object sender, EventArgs e)
    pour que si l'utilisateur ferme la fenetre sans se déconnecter il sera obligé de s'identifier à nouveau.

    en ce qui concerne le problème de gérer les roles je t'ai bien compris,d'ailleur c'est ce que j'ai voulu faire mais c'est un peu compliqué (pour un débutant),tu dois gérer la classe membership.Bon,personnellement puisque j'ai préféré avec ma méthode gérér,au moins,les roles pour les utilisateurs.
    j'ai demandé à guillaume de m'aider en ce sujet,il m'a envoyé des liens (dans la page 2),j'ai compris de quoi il s'agit mais franchement quand on veut appliquer c'est une autre chose.

    si tu arrives à faire ce que tu veux ça me fera plaisir de me faire un signe,si tu veux bien,sur mon msn:
    mr.sayfoun@hotmail.com
    je ferai le dépot de mon projet le 3 juin (j'ai encore du travail à faire donc j'aurai pas le temps de modifier)mais j'aimerai bien savoir gérér cette classe.
    jeudi 22 mai 2008 21:33
  • Bonjour,

    Pour utiliser l'authentification Windows il faut :

    1. mettre dans le fichier web.config <authentication mode="Windows" />
    2. sous IIS cocher la case "Authentification Windows intégrée"
    3. sous IIS décocher l'authentification anonyme.

    Je pense que votre problème vient du point 3. En effet si vous laissez l'authentification anonyme, elle sera toujours utilisée par défaut.

     

    vendredi 23 mai 2008 07:02
  • slt guillaume,

    j'ai besoin de ton aide.
    j'ai fait un menu dans lequel il ya un lien de déconnexion qui me ramène vers la page de login.j'ai mis dans dans la page de login ce code:
    protected void Page_Load(object sender, EventArgs e)
        {
                FormsAuthentication.SignOut();
                txtLogin.Focus();
           
        }
    mais aparament ça fait rien car je peux quand meme accéder sans s'authentifé.
    comment faire????? j'ai pas fait un bouton de déconnexion,je voulais quand l'utilisateur clique sur l'élément de menu il se redirige vers la page de login et se déconnecte.


    merci
    samedi 31 mai 2008 22:25
  • Bonjour,

    Désolé pour la réponse tardive mais je suis un peu (beaucoup) débordé par le boulot en ce moment.

    De ce que j'ai compris votre code devrait marcher. J'ai fait un mini test et cela marche bien :

     

    Code Snippet

    web.config

     

    <?xml version="1.0"?>

    <configuration>

    <appSettings/>

    <connectionStrings/>

    <system.web>

    <compilation debug="true"/>

    <authentication mode="Forms">

    <forms loginUrl="~/Login.aspx"/>

    </authentication>

    <authorization>

    <deny users="?"/>

    </authorization>

    </system.web>

    </configuration>

     

    Login.aspx

     

    <form id="form1" runat="server">

    <div>

    <asp:TextBox ID="txtLogin" runat="server" />

    <br />

    <asp:TextBox ID="txtPwd" runat="server" />

    <br />

    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Login" />

    </div>

    </form>

     

    Login.aspx.cs

     

    protected void Page_Load(object sender, EventArgs e)

    {

    FormsAuthentication.SignOut();

    }

    protected void Button1_Click(object sender, EventArgs e)

    {

    FormsAuthentication.RedirectFromLoginPage(this.txtLogin.Text, false);

    }

     

    Default.aspx

     

    <form id="form1" runat="server">

    <div>

    <asp:Label ID="lbUser" runat="server" /><br />

    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="~/Login.aspx">Logout</asp:HyperLink>

    </div>

    </form>

     

    Default.aspx.cs

     

    protected void Page_Load(object sender, EventArgs e)

    {

    this.lbUser.Text = HttpContext.Current.User.Identity.Name;

    }

     

     

    Si vous essayé d'accéder à Default.aspx vous êtes redirigé vers la page de login. Une fois authentifié et sur la page Default.aspx en cliquant sur Logout on retourne bien vers la page de Login et si l'on essaye à ce moment d'aller sur Default.aspx on est renvoyé vers Login.aspx.
    jeudi 5 juin 2008 08:18
  • slt guillaume,

    j'ai pas su comment récupérer les roles de l'utilisateur identifié. jusque là je travaille avec  isinrole mais là j'ai besoin de récupérer tous ses roles.

    comment faire????????????
    merci
    mercredi 11 juin 2008 01:28
  • Bonjour,

    Si vous êtes en authentification windows, vous avez sur l'objet WindowsIdentity la propriété Groups qui renvoi la liste des groupes de l'utilisateur.

    Vous pouvez accéder au WindowsIdentity en castant Thread.CurrentPrincipal.Identity en WindowsIdentity ou en castant HttpContext.Current.User.Identity en WindowsIdentity.

    mercredi 11 juin 2008 16:03
  • en fait g pas utilisé l'authentification windows. g fait cela:
    System.Collections.Generic.List<string> roles = new System.Collections.Generic.List<string>();
    ..............
    gp = new System.Security.Principal.GenericPrincipal(  new System.Security.Principal.GenericIdentity(userId)    , roles.ToArray()

    et g pas su récupérer la liste de roles?
    help
    mercredi 11 juin 2008 21:24
  • Bonjour,

    Si vous utilisez un GenericPrincipal, vous ne pouvez plus accéder aux rôles passé en paramètre au constructeur.

    Une solution serait d'écrire votre propre classe héritant de GenericPrincipal et ajoutant une propriété Roles :

     

    Code Snippet

    public class MyGenericPrincipal : GenericPrincipal

    {

    private string[] m_roles;

     

    public MyGeneriquePrincipal(IIdentity identity, string[] roles)

    : base(identity, roles)

    {

    // copie les roles

    if (null != roles)

    {

    this.m_roles = new string[roles.Length];

    for (int i = 0 ; i < roles.Length ; ++i)

    {

    this.m_roles[i] = roles[i];

    }

    }

    }

     

    public string[] Roles

    {

    get

    {

    // renvoi une copie (pour qu'on ne modifie pas la liste interne)

    if (null != this.m_roles)

    {

    string[] roles = new string[this.m_roles.Length];

    for (int i = 0 ; i < this.m_roles.Length ; ++i)

    {

    roles[i] = this.m_roles[i];

    }

     

    return roles;

    }

     

    return null;

    }

    }

    }

     

     

    Il faut par contre faire attention aux performances car chaque appel à la propriété Roles fait une copie du tableau interne.

    jeudi 12 juin 2008 10:30