Je suis sur le développement d'un contrôle d'authentification pour mes programmes ASP.Net. Jusque là, ça se passe pas trop mal mais je tombe cependant sur un petit problème, je vous expose le fonctionnement..
Lors du Init de mon contrôle, je m'authentifie avec un compte admin qui lui sert à rechercher le nom de l'utilisateur courant de Windows. Si on clique sur le LinkButton dont hérite mon contrôle, on est redirigé vers un formulaire d'authentification, une fois le nom d'utilisateur et mot de passe renseignés et cliqué sur le bouton de connexion, là aussi tout se passe bien sauf que, le Page_Load de la page courante où se trouve l'utilisateur se lance deux fois donc, à la seconde fois, mon contrôle ré-enclenche un Init et donc avec l'utilisateur par défaut (celui de la session Windows) !
Y a t-il un moyen pour que le contrôle garde quand même en mémoire les données saisies du formulaire ? A ce que je vois, il ne garde même pas les ViewState qui contenaient les données de l'utilisateur qui s'est authentifié par le biais du formulaireMon code complet du contrôle en l'état:
Authenticator.vb
LdapAuthenticator
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166 Imports System.Drawing Imports System Imports System.IO Imports System.Reflection Imports System.Collections.Generic Imports System.ComponentModel Imports System.Text Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.SessionState.HttpSessionState Imports System.Security.Principal <DefaultProperty("Text"), ToolboxData("<{0}:Authenticator runat=server></{0}:Authenticator>")> Public Class Authenticator Inherits LinkButton #Region "Membres privés" Private _ldap As LdapAuthentication #End Region #Region "Propriétés" Private Property UserName() As String Get Dim s As String = CType(ViewState("UserName"), String) If s Is Nothing Then Return [String].Empty Else Return s End If End Get Set(value As String) ViewState("UserName") = value End Set End Property <Category("Informations"), Description("Code de l'application dans la base AD")> Public Property AppCode() As Integer Get Return CType(ViewState("AppCode"), Integer) End Get Set(value As Integer) ViewState("AppCode") = value End Set End Property <Category("Informations"), Description("")> Public ReadOnly Property Nom() As String Get Return CType(ViewState("Nom"), String) End Get End Property <Category("Informations"), Description("")> Public ReadOnly Property Prenom() As String Get Return CType(ViewState("Prenom"), String) End Get End Property <Category("Informations"), Description("")> Public ReadOnly Property NomComplet() As String Get Return CType(ViewState("Nom"), String) & " " & CType(ViewState("Prenom"), String) End Get End Property <Category("Informations"), Description("")> Public ReadOnly Property Matricule() As String Get Return CType(ViewState("Matricule"), String) End Get End Property <Category("Informations"), Description("")> Public ReadOnly Property Role() As Integer Get Return CType(ViewState("Role"), Integer) End Get End Property <Category("Informations"), Description("")> Public ReadOnly Property Mail() As String Get Return CType(ViewState("Mail"), String) End Get End Property #End Region #Region "Procédures et fonctions privées" Private Sub Authenticator_Init(sender As Object, e As System.EventArgs) Handles Me.Init _ldap = New LdapAuthentication(AppCode) Dim currentUser As String = System.Web.HttpContext.Current.Request.LogonUserIdentity.Name Dim _name As String = currentUser.Substring(currentUser.IndexOf("\") + 1, currentUser.Length - 5) Me.ToolTip = "Changer d'utilisateur" If String.IsNullOrEmpty(CType(ViewState("Nom"), String)) Or Not CType(ViewState("Nom"), String) <> System.Web.HttpContext.Current.Request.LogonUserIdentity.Name Then If Not IsNothing(_ldap) Then If _ldap.IsAdminAuthenticated() Then If _ldap.UserExists(System.Web.HttpContext.Current.Request.LogonUserIdentity.Name) Then UserName = _ldap.NomComplet ViewState("Nom") = _ldap.Nom ViewState("Prenom") = _ldap.Prenom ViewState("Matricule") = _ldap.Matricule ViewState("Role") = _ldap.Role ViewState("Mail") = _ldap.Mail End If End If End If End If End Sub Public Function SignIn(ByVal _userName_ As String, ByVal _pwd_ As String) As Boolean Dim bRet As Boolean = False If _ldap.IsAuthenticated(_userName_, _pwd_) Then UserName = _ldap.NomComplet ViewState("Nom") = _ldap.Nom ViewState("Prenom") = _ldap.Prenom ViewState("Matricule") = _ldap.Matricule ViewState("Role") = _ldap.Role ViewState("Mail") = _ldap.Mail bRet = True End If Return bRet End Function Public Function FindUser(ByVal _userName_ As String) As Boolean Return _ldap.UserExists(_userName_) End Function Protected Overrides Sub RenderContents(ByVal output As HtmlTextWriter) Dim displayUserName As String = String.Empty output.WriteEncodedText(Text) If Context IsNot Nothing Then If Not String.IsNullOrEmpty(UserName) Then displayUserName = UserName Else displayUserName = "invité" End If End If If Not String.IsNullOrEmpty(Text) Then output.Write(", ") End If output.WriteEncodedText(displayUserName) End Sub Protected Overrides Sub OnClick(e As System.EventArgs) MyBase.Context.Response.Buffer = True MyBase.Context.Response.StatusCode = 401 MyBase.Context.Response.StatusDescription = "Unauthorized" MyBase.Context.Response.AddHeader("WWW-Authenticate", "NTLM") MyBase.Context.Response.End() MyBase.OnClick(e) End Sub #End Region End Class
Login.aspx.vb
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 Imports System Imports System.IO Imports System.Text Imports System.Collections Imports System.Web.Security Imports System.Security.Principal Imports System.DirectoryServices Public Class LdapAuthentication #Region "Constantes" Private Const DEFAULT_USER_NAME As String = "nom.prenom" Private Const DEFAULT_USER_PWD As String = "pwd" Private Const DEFAULT_PATH As String = "LDAP://XXXX.XXXXX" #End Region #Region "Variables privées" Private _idApplication As Integer Private _path As String Private _filterAttribute As String Private _nom As String Private _prenom As String Private _matricule As String Private _role As String Private _mail As String #End Region #Region "Propriétés" Public ReadOnly Property Nom() As String Get Return _nom End Get End Property Public ReadOnly Property Prenom() As String Get Return _prenom End Get End Property Public ReadOnly Property NomComplet() As String Get Return _nom & " " & _prenom End Get End Property Public ReadOnly Property Matricule() As String Get Return _matricule End Get End Property Public ReadOnly Property Role() As Integer Get Return _role End Get End Property Public ReadOnly Property Mail() As String Get Return _mail End Get End Property #End Region #Region "Constructeurs" Public Sub New(ByVal idApplication As Integer) _idApplication = idApplication _path = DEFAULT_PATH End Sub #End Region #Region "Procédures et fonctions publiques" Public Function IsAdminAuthenticated() As Boolean Return IsAuthenticated(DEFAULT_USER_NAME, DEFAULT_USER_PWD) End Function Public Function IsAuthenticated(ByVal _userName_ As String, ByVal _pwd_ As String) As Boolean Dim domainAndUserName As String = "XXXX.XXXXX" & "\" & _userName_ Dim entry As New DirectoryEntry(DEFAULT_PATH, domainAndUserName, _pwd_, AuthenticationTypes.Secure) Try Dim obj As Object = entry.NativeObject Dim search1 As New DirectorySearcher(entry) Dim result1 As SearchResult = Nothing With search1 .Filter = "(userPrincipalName=" & _userName_ & "@XXXX.XXXXX)" .PropertiesToLoad.Add("cn") result1 = .FindOne() End With If IsNothing(result1) Then Dim search2 As New DirectorySearcher(entry) Dim result2 As SearchResult = Nothing With search2 .Filter = "(SAMAccountName=" & _userName_ & ")" .PropertiesToLoad.Add("cn") result2 = .FindOne() End With If IsNothing(result2) Then Return False Else _path = result2.Path _filterAttribute = Convert.ToString(result2.Properties("cn")(0)) GetUserData(_userName_) End If Else _path = result1.Path _filterAttribute = Convert.ToString(result1.Properties("cn")(0)) GetUserData(_userName_) End If Catch ex As Exception Return False End Try Return True End Function Public Function UserExists(ByVal _userName_ As String) Dim bRet As Boolean = False Dim entry = GetAdminDirectoryEntry() If Not IsNothing(entry) Then Dim searcher As New DirectorySearcher() Dim result As SearchResultCollection = Nothing With searcher .SearchRoot = entry .Filter = "(SAMAccountName=" & _userName_ & ")" result = searcher.FindAll() If result.Count > 0 Then GetUserData(_userName_) bRet = True End If End With End If Return bRet End Function #End Region #Region "Procédure et fonctions privées" Private Function GetAdminDirectoryEntry() As DirectoryEntry Return New DirectoryEntry(_path, DEFAULT_USER_NAME, DEFAULT_USER_PWD, AuthenticationTypes.Secure) End Function Private Sub GetUserData(ByVal _userName_ As String) Try Dim _ds As New dsAD Dim _user As New dsADTableAdapters.USERSTableAdapter Dim _droits As New dsADTableAdapters.DROITSTableAdapter If Not IsNothing(_ds) Then _user.FillByUserID(_ds.USERS, _userName_) If _ds.USERS.Rows.Count > 0 Then With _ds.USERS.Rows(0) _nom = .Item("NOM") _prenom = .Item("PRENOM") _matricule = .Item("MATRICULE") _mail = .Item("MAIL") End With _user.Dispose() _user = Nothing Else _nom = "invité" _prenom = String.empty _matricule = String.empty _mail = String.empty End If _droits.Fill(_ds.DROITS, _matricule, _idApplication) If _ds.DROITS.Rows.Count > 0 Then _role = _ds.DROITS.Rows(0).Item("ROLE") _droits.Dispose() _droits = Nothing Else _role = 7 'Lecture seule End If _ds.Dispose() _ds = Nothing End If Catch ex As Exception Dim msg As String = ex.Message End Try End Sub #End Region End Class
Si jamais quelqu'un à une solution à mon problème je l'en remercie d'avance
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 Imports Microsoft.VisualBasic Imports System.IO Partial Class Login Inherits System.Web.UI.Page Protected Sub LoginButton_Click(sender As Object, e As System.EventArgs) Dim auth As Authenticator.Authenticator = CType(Master.FindControl("Authenticator1"), Authenticator.Authenticator) lblMsgAuthentificator.Text = String.Empty If Not String.IsNullOrEmpty(txtUserName.Text) And Not String.IsNullOrEmpty(txtPassword.Text) Then If auth.SignIn(txtUserName.Text, txtPassword.Text) Then FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, False) Else lblMsgAuthentificator.Text = "Nom d'utilisateur ou mot de passe invalide" End If Else If String.IsNullOrEmpty(txtUserName.Text) Then lblMsgAuthentificator.Text = "Nom d'utilisateur manquant<br />" End If If String.IsNullOrEmpty(txtPassword.Text) Then lblMsgAuthentificator.Text = lblMsgAuthentificator.Text & "Mot de passe manquant" End If End If End Sub End Class
![]()
Partager