From 12417e1425cd92e24b0273d6652904953bb7a6cc Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 3 Nov 2017 17:41:25 -0300 Subject: [PATCH 1/2] Modificaciones Usuarios --- SireCu/Paneles/ABMEgresos.vb | 4 ++-- SireCu/Paneles/ABMUsuarios.vb | 24 +++++++++++++++++------- SireCu/Paneles/VerReporte.vb | 8 +++++++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/SireCu/Paneles/ABMEgresos.vb b/SireCu/Paneles/ABMEgresos.vb index 96ef2d4..ef79fef 100644 --- a/SireCu/Paneles/ABMEgresos.vb +++ b/SireCu/Paneles/ABMEgresos.vb @@ -681,7 +681,7 @@ Public Class ABMEgresos Private Sub cbSeccional_Validating(sender As Object, e As CancelEventArgs) Handles cbSeccional.Validating If (sender.Text = "") Or (exist("Seccionales", "nombre", sender.Text) = False) Then Principal.ErrorProvider.SetError(sender, "Debe ingresar una Seccional correcta." & vbCrLf & - "Puede agregar una nueva en la seccion Administrar") + "Puede configurarlo desde el Menú Editar") If Not ControlesConErroresAgregar.Contains(sender) Then ControlesConErroresAgregar.Add(sender) End If @@ -823,7 +823,7 @@ Public Class ABMEgresos Private Sub ComboBoxSeccional_Validating(sender As Object, e As CancelEventArgs) Handles ComboBoxSeccional.Validating If (sender.Text = "") Or (exist("Seccionales", "nombre", sender.Text) = False) Then Principal.ErrorProvider.SetError(sender, "Debe ingresar una Seccional correcta." & vbCrLf & - "Puede agregar una nueva en la seccion Administrar") + "Puede configurarlo desde el Menú Editar") If Not ControlesConErroresModificar.Contains(sender) Then ControlesConErroresModificar.Add(sender) End If diff --git a/SireCu/Paneles/ABMUsuarios.vb b/SireCu/Paneles/ABMUsuarios.vb index 25de988..d9dce13 100644 --- a/SireCu/Paneles/ABMUsuarios.vb +++ b/SireCu/Paneles/ABMUsuarios.vb @@ -71,15 +71,18 @@ Public Class ABMUsuarios Exit Sub End If - 'Si existe el usuario, preguntamos por modificarlo - Dim modificar As Boolean = 0 - If (exist("Usuarios", "usuario", tb_Usuario.Text) = True) Then - modificar = 1 - End If - Select Case btn_Guardar.Text Case "Actualizar" - If (MsgBox("Quiere Modificar al usuario " & tb_Usuario.Text & "?", + + If (exist("Usuarios", "usuario", tb_Usuario.Text) = True) Then + If LCase(tb_Usuario.Text) <> LCase(DGVAdmin.CurrentRow.Cells(1).Value) Then + MsgBox("El nombre de usuario ingresado ya se encuentra utilizado." & + vbCrLf & "Por favor, intentelo con otro nuevamente.", MsgBoxStyle.Exclamation, "Usuario Inválido") + Exit Sub + End If + End If + + If (MsgBox("Quiere Modificar al usuario " & DGVAdmin.CurrentRow.Cells(1).Value & "?", MsgBoxStyle.OkCancel, "Modificar?") = MsgBoxResult.Ok) Then Principal.query = "UPDATE [Usuarios] SET " & @@ -94,6 +97,13 @@ Public Class ABMUsuarios Exit Sub End If Case "Guardar" + + If (exist("Usuarios", "usuario", tb_Usuario.Text) = True) Then + MsgBox("El nombre de usuario ingresado ya se encuentra utilizado." & + vbCrLf & "Por favor, intentelo con otro nuevamente.", MsgBoxStyle.Exclamation, "Usuario Inválido") + Exit Sub + End If + If (MsgBox("Guardar nuevo usuario?", MsgBoxStyle.OkCancel, "Guardar?") = MsgBoxResult.Ok) Then Principal.query = "INSERT INTO [Usuarios] (usuario,contraseña, rol) diff --git a/SireCu/Paneles/VerReporte.vb b/SireCu/Paneles/VerReporte.vb index b899172..fdc9160 100644 --- a/SireCu/Paneles/VerReporte.vb +++ b/SireCu/Paneles/VerReporte.vb @@ -49,7 +49,7 @@ Public Class VerReporte End If - Else + Else MsgBox("No se pudo establecer la conexción con el servidor." & vbCrLf & "Por favor, intentelo mas tarde.", MsgBoxStyle.Exclamation, "No se estableció conexión") Exit Sub @@ -122,6 +122,12 @@ Public Class VerReporte End If End Sub + Private Sub VerReporte_Load(sender As Object, e As EventArgs) Handles Me.Load + Select Case tipoDeUsuario(Principal.userLogueado) + Case "Usuario" + btn_Subir.Enabled = False + End Select + End Sub #End Region From 52cdeafd711e728a30907e5406cdaaeea22627d0 Mon Sep 17 00:00:00 2001 From: Mauricio Parra Casado Date: Wed, 6 Dec 2017 01:27:11 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Contrase=C3=B1as=20Usuarios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit En lugar de guardar las contraseñas de usuario en texto plano se guarda el hash sha512 de la misma y el salt utilizado el cual es distinto y aleatorio para cada usuario. --- SireCu/Clases/Usuario.vb | 134 +++++++++++++++++++++- SireCu/DBSireCu.sdf | Bin 360448 -> 360448 bytes SireCu/My Project/Application.Designer.vb | 18 +-- SireCu/My Project/Application.myapp | 4 +- SireCu/Paneles/ABMUsuarios.vb | 23 +++- SireCu/Paneles/Login.vb | 17 ++- SireCu/Principal.vb | 3 + 7 files changed, 171 insertions(+), 28 deletions(-) diff --git a/SireCu/Clases/Usuario.vb b/SireCu/Clases/Usuario.vb index 7c60d07..6fc1cd2 100644 --- a/SireCu/Clases/Usuario.vb +++ b/SireCu/Clases/Usuario.vb @@ -1,17 +1,139 @@ Module Usuario - Public Function verificarUsuario(ByVal user As String, ByVal pass As String) + Public Class SampleIPrincipal + Implements System.Security.Principal.IPrincipal - Dim sql As String = "SELECT * FROM Usuarios WHERE usuario = '" & user & "'" + Private identityValue As SampleIIdentity + + Public ReadOnly Property Identity() As System.Security.Principal.IIdentity Implements System.Security.Principal.IPrincipal.Identity + Get + Return identityValue + End Get + End Property + + Public Function IsInRole(ByVal role As String) As Boolean Implements System.Security.Principal.IPrincipal.IsInRole + Return role = identityValue.Role.ToString + End Function + + Public Sub New(ByVal name As String, ByVal password As String) + identityValue = New SampleIIdentity(name, password) + End Sub + + End Class + + Public Class SampleIIdentity + Implements System.Security.Principal.IIdentity + + Private nameValue As String + Private authenticatedValue As Boolean + Private roleValue As ApplicationServices.BuiltInRole + + Public ReadOnly Property AuthenticationType As String Implements System.Security.Principal.IIdentity.AuthenticationType + Get + Return "SqlCEDatabase" + End Get + End Property + + Public ReadOnly Property IsAuthenticated As Boolean Implements System.Security.Principal.IIdentity.IsAuthenticated + Get + Return authenticatedValue + End Get + End Property + + Public ReadOnly Property Name As String Implements System.Security.Principal.IIdentity.Name + Get + Return nameValue + End Get + End Property + + Public ReadOnly Property Role() As ApplicationServices.BuiltInRole + Get + Return roleValue + End Get + End Property + + Public Sub New(ByVal name As String, ByVal password As String) + ' Contraseña es Case Sensitive, el Usuario no lo es + If IsValidNameAndPassword(name, password) Then + nameValue = name + authenticatedValue = True + Else + nameValue = "" + authenticatedValue = False + End If + + End Sub + + Private Function IsValidNameAndPassword(ByVal username As String, ByVal password As String) As Boolean + + ' Look up the stored hashed password and salt for the username. + Dim storedHashedPW As String = GetHashedPassword(username) + Dim salt As String = GetSalt(username) + + 'Create the salted hash. + Dim rawSalted As String = salt & Trim(password) + Dim saltedPwBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(rawSalted) + Dim sha512 As New System.Security.Cryptography.SHA512CryptoServiceProvider + Dim hashedPwBytes() As Byte = sha512.ComputeHash(saltedPwBytes) + Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes) + + ' Compare the hashed password with the stored password. + Return hashedPw = storedHashedPW + + End Function + + + End Class + + Friend Function GetHashedPassword(ByVal username As String) As String + ' Code that gets the user's hashed password + + Dim sql As String = "SELECT contraseña FROM Usuarios WHERE usuario = '" & username & "'" Dim dt As DataTable = consultarReader(sql) If dt.Rows.Count = 0 Then - Return False - ElseIf dt.Rows(0).Item("contraseña") = pass Then - Return True - Else Return False + Return "" + Else + Return dt.Rows(0).Item("contraseña") End If + End Function + + Friend Function GetSalt(ByVal username As String) As String + ' Code that gets the user's salt + + Dim sql As String = "SELECT salt FROM Usuarios WHERE usuario = '" & username & "'" + Dim dt As DataTable = consultarReader(sql) + + If dt.Rows.Count = 0 Then + Return "" + Else + Return dt.Rows(0).Item("salt") + End If + End Function + + Public Function CreateRandomSalt() As String + 'the following is the string that will hold the salt charachters + Dim mix As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+=][}{<>" + Dim salt As String = "" + Dim rnd As New Random + Dim sb As New System.Text.StringBuilder + For i As Integer = 1 To 100 'Length of the salt + Dim x As Integer = rnd.Next(0, mix.Length - 1) + salt &= (mix.Substring(x, 1)) + Next + Return salt + End Function + + Public Function CreateHashedPassword(ByVal contraseña As String, ByVal salt As String) As String + + 'Create the hashed password. + Dim rawSalted As String = salt & Trim(contraseña) + Dim saltedPwBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(rawSalted) + Dim sha512 As New System.Security.Cryptography.SHA512CryptoServiceProvider + Dim hashedPwBytes() As Byte = sha512.ComputeHash(saltedPwBytes) + Dim hashedPw As String = Convert.ToBase64String(hashedPwBytes) + Return hashedPw End Function Public Function tipoDeUsuario(ByVal user As String) diff --git a/SireCu/DBSireCu.sdf b/SireCu/DBSireCu.sdf index 3eddd897be49dc451df3f41f42a1324541eeeb10..ac60451e0c8c94a9d307e3be8364a31fafddecf3 100644 GIT binary patch delta 3727 zcmeHJdrVu`89(RT>&G?tMF0o$vIB(1=Hbi3kS1Cx&?xIyOLkX_4RnZ7|*>e0>C*$-Em!5vh_igIR{spby2(4<2wYNMc-ClWx>PltYsC}L0CFzsVQ1{-SF$|CeLNZFlxiU`sGNx`W%cS52djcR`fdrce7eM3JIp)xx7V0G?5@1 zkkgT$s2FV?O3`{LuMBMbwYkR~C;CU-!0i|s1MIGL^o)>PSP&xS%28BCnLqrZpqA_e z3#>9i+?M-0#j`6K>eZyZ!*Yx{ho!8dW9J!DiFTi5EVr_vM{A<{jYhg*Qr9tH zcAqhqx{c1BhLP5G^Kt#;fU|MDQGcp=|KX9E$4ie^4ezkG*d94p)oP*p2b($^l|wCE zdE4p9ZiB~l^1x92@srlv9WBOw4#oyRT5nMtP^EQv%-&bg*Vfh6*W5nwg~6uMiW6f^ z21oU%>C@o!{HH)S$JyZ>h~sP;DK8(V%UXtOhr0$G`v)p*r>g75t;a151Gds$y`yI0 zME$-~&BwlU&|c=YS6e)_`;6mlJ1ZtEwqq@O>qhnCClAp(i(8CCRfDG-Ekl=fPIz)K%|@p?YE-PoNkrsxX6RL&ek}4PM=T+C zZn!0pkpyT>{hU}h0LnLU`ldej$cQ(b686E{5E`g4;p~s}*u#|!HIM3G4HM9yESSSM z=TQ(5CjOBjeu$FUwjlbhY)*j`y??uU?$-!tKqDDHl|(R4036{on1Uc504>l!kODv| z@IsIUfD#xGNB}rJtl-pz6FBHZ;1K`{fC2z10BT?bKn%d6z>I(q0Q_1Aw)kx+N(59m z&4UO5(&Jk(Pa7c3v7r=1Fn!A9qSE*T`=A&>h3@u~=XUl%y%<9V+=Qg-i5<5h+aEXW^ z0A3Rx!@g4Rs>!)_8>bMr9sdInSI$CvW2aTIF!w-j3Z zzfnlMN+B?}h!o1M`avFe(JFBLI`9ZGP!sPi>=NR5xiC#F=0kIcUR=fkZ;15(RM;L?i-R)_xZRvIC$ja$e+wg^>TZY5w<=xbNTi8&3Spa#F*CaA&8onKR0>MMtT znw)}VHWSwZ`H(SKkQGvx^&Z)r6|b->enV>Tite=)b51<`gh{@Is})!*&PYYXD}w8Z zx*MZjCl?x>{CTY3^#6^}kgSKsXNUji2#>;Ndx9RPhr_+vp6F3u`;r~*_th`eDeEk? z{u-s({HU|6vmo}+?El5<9V1!TnMc?C2*8R3Y+rpA@~Htb`O9cNHSeFpR)xbhp9|Zq z?6Y0uZb+tIl+7`Le3;J6yo36ff;)snK;R6K$&~&Q4KPDJ`g4dPiPZYs)Yv2a}-ECi5lI2@WbO zvIxUCe$`X+NhJ2g#A+Q5Rtd!g5a$mr=j!l(Hn!z+FXWSN9z*M4Dl@!{20j}eVy;BU zzdW2GY(jfJ*Ju2%b3J4Fh)8C#u9Ff^38xC8YEiY6kP?QN>-V-Bwhv-gE$_kQz~$&A z?HhrGC`+@B*Mr}q=R04u&PHcq7qu6oFZ;i-^pfjE`i1DUZ;F04_;lcW@Lcq(OJ8<9 z74rqWjJ2;F94JONq*V lEG4Fhhb<*wDf`#!gh-)$m!0G#K({IZrZow8iu|^~`*+I$-!%XL delta 2218 zcmZ8h4QyN06+ZXJKQFGI-^-t4$GFdF(x$9w?S;@Rp(75>Ry0at2vkKt9QwCaq;Y6j zHPDt9_ERblO%~W?>I5zm4nnAk@v_ICQiqYWgKc#t4Z6ZsmuVZI0!dY9L8IAu&u*%6 zrF-AG=R4=#bH01t(e+AQuWZ=2^XyT;(Ll@BF~> zNPRm%V>Q6TXdJ=0;XM`3DgWmPiw?pKh`9HrOvDg{>eSBciYz zmFSlX3+8pM(SdZe$nR&R#@aGAfk7G{S1=!QHWhHsWxUnLIvHs-9tp7fS^2W&gRM?H zcj`_nYVh)LVw5N72Of9RIHA98sK3gKvE6A%I^9idPPB4}Bb?S{hSeFC&bE<^Ue_%> zGp9*=X3Bn9#pBQ;4mqgT(6Th|S#v(Kxs0PSP^1%-8?1{kL8!s0C{ef$zw0?b2XLY1 zc$K(*j$S=6U_0OmhHg9g8U+p3AZ!j7Xap$05*Q}n7QsAS!DRr|xG_%+PpXaR-dkI@ zY%al!iXKpkGRafn)ktHeBA)TkBsCU}6B1T8ZQe)-C{S-kgQILhWuJOd3RR>;``;c@ z(epQ>()d4}l?4_{7g@{%(lVp;^USK>36NGePf z=M%A+@(LtV#18NZ;Oj|i@p5n4br)GsY+ zMV8ZAtjT_lUFRCpiE;61ibQPtPi4tBFp6uRkmz>_9X&K2B;OH#oN?&mw5ji z|J-56a_9gm4$RX^vEe+eBz`e>jPEcW|B~O!h%DBPu_|$(j}M6cK0YFXV=O5C*vFfN zcZ}7U(poXt$A?6wk8c!*`gl)?m7k2~R*U(QSX>uUY<TYIXVe-;Oj7d{bM~yE0sx4kjzrir%ucG9`yy zz0#~BYMBzE4D(wH*Xz1p#N8NNkXk=YPW*zDs=tesizb7mb6 z_Y|u6v;!8Kmjz-yTmhPUb6BAHd(M6DHcMf8Uiw`v&{`&+zk3n2SyIu}++4aekFHmM zb_C}ppSSGa|9V8YU-Uff5WRWo!wNhrM@Mpm?!mbUC)$_^k;5oIb$YkMYzH-FL^!N= zP+_)%IJN_T5M+s&k0Ms)X`t5Z3}_8?06ypf!0uHB2`legC{*G%97>lOGaUtP^Wph$bW>6 zpKRy%h?}SRUNjG)`J2;xhs!TZ?wZ0?qH~(piwDneS=@96?H`!o-3(2|>Tb0;l@_0YRA@XaE2J diff --git a/SireCu/My Project/Application.Designer.vb b/SireCu/My Project/Application.Designer.vb index 51b924b..004906c 100644 --- a/SireCu/My Project/Application.Designer.vb +++ b/SireCu/My Project/Application.Designer.vb @@ -1,10 +1,10 @@ '------------------------------------------------------------------------------ ' -' This code was generated by a tool. -' Runtime Version:4.0.30319.42000 +' Este código fue generado por una herramienta. +' Versión de runtime:4.0.30319.42000 ' -' Changes to this file may cause incorrect behavior and will be lost if -' the code is regenerated. +' Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si +' se vuelve a generar el código. ' '------------------------------------------------------------------------------ @@ -14,16 +14,16 @@ Option Explicit On Namespace My - 'NOTE: This file is auto-generated; do not modify it directly. To make changes, - ' or if you encounter build errors in this file, go to the Project Designer - ' (go to Project Properties or double-click the My Project node in - ' Solution Explorer), and make changes on the Application tab. + 'NOTA: este archivo se genera de forma automática; no lo modifique directamente. Para realizar cambios, + ' o si detecta errores de compilación en este archivo, vaya al Diseñador de proyectos + ' (vaya a Propiedades del proyecto o haga doble clic en el nodo My Project en el + ' Explorador de soluciones) y realice cambios en la pestaña Aplicación. ' Partial Friend Class MyApplication _ Public Sub New() - MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows) + MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.ApplicationDefined) Me.IsSingleInstance = false Me.EnableVisualStyles = true Me.SaveMySettingsOnExit = true diff --git a/SireCu/My Project/Application.myapp b/SireCu/My Project/Application.myapp index 1572e1e..7fecdff 100644 --- a/SireCu/My Project/Application.myapp +++ b/SireCu/My Project/Application.myapp @@ -1,10 +1,10 @@ - + true Principal false 0 true - 0 + 1 true \ No newline at end of file diff --git a/SireCu/Paneles/ABMUsuarios.vb b/SireCu/Paneles/ABMUsuarios.vb index d9dce13..d1e5d84 100644 --- a/SireCu/Paneles/ABMUsuarios.vb +++ b/SireCu/Paneles/ABMUsuarios.vb @@ -63,7 +63,9 @@ Public Class ABMUsuarios End If Else Principal.ErrorProvider.SetError(cb_Rol, "") - ControlesConErrores.Remove(cb_Rol) + If ControlesConErrores.Contains(cb_Rol) Then + ControlesConErrores.Remove(cb_Rol) + End If End If If ControlesConErrores.Count > 0 Then @@ -85,9 +87,16 @@ Public Class ABMUsuarios If (MsgBox("Quiere Modificar al usuario " & DGVAdmin.CurrentRow.Cells(1).Value & "?", MsgBoxStyle.OkCancel, "Modificar?") = MsgBoxResult.Ok) Then + Dim contraseña As String = "" + If tb_Contraseña.Text = Usuario.GetHashedPassword(DGVAdmin.CurrentRow.Cells(1).Value) Then + contraseña = tb_Contraseña.Text + Else + contraseña = Usuario.CreateHashedPassword(tb_Contraseña.Text, Usuario.GetSalt(DGVAdmin.CurrentRow.Cells(1).Value)) + End If + Principal.query = "UPDATE [Usuarios] SET " & "usuario = '" & tb_Usuario.Text & - "' ,contraseña = '" & tb_Contraseña.Text & + "' ,contraseña = '" & contraseña & "' ,rol = '" & cb_Rol.Text & "' WHERE id= '" & DGVAdmin.CurrentRow.Cells(0).Value & "'" consultarNQ(Principal.query, Principal.command) @@ -106,10 +115,13 @@ Public Class ABMUsuarios If (MsgBox("Guardar nuevo usuario?", MsgBoxStyle.OkCancel, "Guardar?") = MsgBoxResult.Ok) Then - Principal.query = "INSERT INTO [Usuarios] (usuario,contraseña, rol) + Dim salt As String = Usuario.CreateRandomSalt() + Dim contraseña As String = Usuario.CreateHashedPassword(tb_Contraseña.Text, salt) + + Principal.query = "INSERT INTO [Usuarios] (usuario, contraseña, rol, salt) VALUES ('" & - tb_Usuario.Text & "', '" & tb_Contraseña.Text & - "', '" & cb_Rol.Text & "')" + tb_Usuario.Text & "', '" & contraseña & + "', '" & cb_Rol.Text & "', '" & salt & "')" consultarNQ(Principal.query, Principal.command) MsgBox("Guardado Correctamente!", MsgBoxStyle.Information, "Guardado") @@ -224,6 +236,7 @@ Public Class ABMUsuarios DGVAdmin.Columns.Item("usuario").HeaderText = "Usuario" DGVAdmin.Columns.Item("contraseña").HeaderText = "Contraseña" DGVAdmin.Columns.Item("rol").HeaderText = "Rol" + DGVAdmin.Columns.Item("salt").Visible = False End Sub diff --git a/SireCu/Paneles/Login.vb b/SireCu/Paneles/Login.vb index d738df9..c0ef5fa 100644 --- a/SireCu/Paneles/Login.vb +++ b/SireCu/Paneles/Login.vb @@ -8,11 +8,18 @@ Public Class Login Private Sub btn_Login_Click(sender As Object, e As EventArgs) Handles btn_Login.Click - 'Validaciones - If verificarUsuario(tb_Usuario.Text, tb_Contraseña.Text) Then + Dim samplePrincipal As New Usuario.SampleIPrincipal(Me.tb_Usuario.Text, Me.tb_Contraseña.Text) + Me.tb_Contraseña.Text = "" + If (Not samplePrincipal.Identity.IsAuthenticated) Then + ' The user is still not validated. + Principal.ErrorProvider.SetError(tb_Contraseña, "Usuario y/o Contraseña Inválido/s") + Else + ' Update the current principal. + My.User.CurrentPrincipal = samplePrincipal + Principal.bttn_Login.Text = "Desloguear" - Principal.stat_Label.Text = "Logueado como: " & tb_Usuario.Text - Principal.userLogueado = tb_Usuario.Text + Principal.stat_Label.Text = "Logueado como: " & My.User.Name + Principal.userLogueado = My.User.Name ActualizarSaldo() permisosUsuarios(tb_Usuario.Text) @@ -20,8 +27,6 @@ Public Class Login ' Limpiamos todas las pantallas Principal.SplitContainerPrincipal.Panel2.Controls.Clear() Principal.AdminPantallas("Home") - Else - Principal.ErrorProvider.SetError(tb_Contraseña, "Usuario y/o Contraseña Inválido/s") End If End Sub diff --git a/SireCu/Principal.vb b/SireCu/Principal.vb index 1ddb261..e77f6a0 100644 --- a/SireCu/Principal.vb +++ b/SireCu/Principal.vb @@ -110,6 +110,9 @@ Public Class Principal End Sub Private Sub desloguear() + ' Se borra la identidad auntenticada en la aplicación + My.User.CurrentPrincipal = Nothing + ' Limpiamos todas las pantallas SplitContainerPrincipal.Panel2.Controls.Clear()