Necesidad de suplantar al usuario para acceder al recurso de la red, cuenta Asp.Net
-
04-07-2019 - |
Pregunta
Necesito acceder a un recurso de red al que solo tiene acceso una cuenta de dominio determinada. Estoy usando la llamada LogonUser, pero obtengo un "Usuario no ha requerido privilegio" excepción, ya que la aplicación web se ejecuta con la cuenta asp.net y no tiene los permisos adecuados para realizar esta llamada.
¿Hay alguna forma de evitarlo? Cambiar la identidad o los permisos de la cuenta ASP.Net no es una opción, ya que es una máquina de producción con muchos proyectos en ejecución. ¿Hay una mejor manera de lograr esto?
Usando Asp.Net 2.0, Autenticación de formularios.
Saludos cordiales.
Solución
Simplemente llamar a LogonUser no es suficiente. Necesitas suplantar a ese usuario. Puede hacerse pasar solo por el acceso al recurso de red.
El código de muestra se puede encontrar en MSDN .
Otros consejos
Puede agregar un
<identity impersonate="true" userName=""/>
etiqueta a tu web.config pero eso podría no ser ideal ya que probablemente no quieras ejecutar todo el sitio como ese usuario ...
¿Puede asignar el recurso compartido de red como una unidad local con DomainName & amp; Contraseña ... y luego extraer archivos al sitio web a través de la unidad asignada?
NET USE Z: \\SERVER\Share password /USER:DOMAIN\Username /PERSISTENT:YES
Solo he tenido una experiencia íntima con esto en 1.1, por lo que las cosas podrían haber cambiado en los 2.0 días, pero ... Tenemos una aplicación que se implementa en escenarios de intranet, y descubrimos lo mismo. Corremos con la suplantación de identidad activada, autenticación de modo de formularios, acceso anónimo desactivado. La forma más fácil de controlar esto (que he encontrado) es poner las credenciales del usuario que tiene acceso en web.config. Se dirigen al nodo donde se activa la suplantación de identidad. ¡Si es información de super scret, no lo haría de esta manera! Solo accedemos a gráficos compartidos en un entorno de impresión, por lo que la mayoría de los sitios se complacen en configurar una cuenta limitada para que podamos colocarla en la web.confit. LogonUser realmente necesita puentes elevados. Msdn tiene algunos buenos artículos sobre cómo hacerse pasar por un usuario específico en el código. Me gustaría descargar algunos enlaces, pero este teléfono no hace copiar y pegar.
¿Puede cambiar la ACL que protege el recurso de red? Un truco que he usado en el pasado es crear un grupo de Active Directory y luego colocar el objeto de computadora en ese grupo. Luego uso ese grupo en la Lista de control de acceso del objeto (archivo, recurso compartido, etc.) al que necesito acceder.
Esto me ha permitido ejecutar Servicios de Windows como sistema local y obtener acceso a los recursos de red protegidos. Y este truco también parece funcionar para el proceso ASP.NET que se ejecuta como servicio de red.
- Con esta WebPart y conectarse a un recurso de red con acceso restringido, pongo un archivo y cierro la conexión con el recurso (como usuario con acceso concedido), no necesita hacer una nueva conexión compartida, eso fue solo una restricción que me hace mi departamento de sistemas. Puede ser que haya muchas importaciones que sean necesarias, pero las hago para muchas pruebas y no tengo tiempo para limpiar el código. Espero que te ayude. (perdón por mi pobre inglés).
Sistema de importaciones Imports System.ComponentModel Importaciones System.Web.UI Importaciones System.Web.UI.WebControls Importaciones System.IO Importaciones System.IO.File Sistema de importaciones. Diagnósticos. Importaciones System.Xml.Serialization Importa Microsoft.SharePoint Importa Microsoft.SharePoint.Utilities Importa Microsoft.SharePoint.WebPartPages Importa Microsoft.SharePoint.WebControls Importa Microsoft.SharePoint.Administration Importaciones System.Security.Principal Importaciones System.Security.Permissions Importa System.Runtime.InteropServices Sistema de importaciones. Entorno Importaciones System.Net.Sockets Importa System.Web.UI.HtmlControls
Clase pública de impersonalización Const privado LOGON32_PROVIDER_DEFAULT Como entero = 0 Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2
<DllImport("advapi32.dll", SetLastError:=True)> _
Public Shared Function LogonUser(ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean
End Function
<DllImport("advapi32.dll", EntryPoint:="DuplicateToken", ExactSpelling:=False, CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function DuplicateToken(ByVal ExistingTokenHandle As IntPtr, ByVal ImpersonationLevel As Integer, ByRef DuplicateTokenHandle As IntPtr) As Integer
End Function
Public Shared Function WinLogOn(ByVal strUsuario As String, ByVal strClave As String, ByVal strDominio As String) As WindowsImpersonationContext
Dim tokenDuplicate As New IntPtr(0)
Dim tokenHandle As New IntPtr(0)
If LogonUser(strUsuario, strDominio, strClave, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, tokenHandle) Then
If DuplicateToken(tokenHandle, 2, tokenDuplicate) <> 0 Then
Return (New WindowsIdentity(tokenDuplicate)).Impersonate()
End If
End If
Return Nothing
End Function
clase final 'Descripción para WebPart1. "), XmlRoot (espacio de nombres: = " SPSCopiarFichero ") > _ Public Class WebPart1 Hereda Microsoft.SharePoint.WebPartPages.WebPart
Protected WithEvents File1 As HtmlInputFile
Dim vdestino As String = "\\centappd20nd01\uploads_avisos"
Dim vtemporal As String = "c:\pdf"
Protected WithEvents boton1 As Button
Protected WithEvents usuario As TextBox
Protected WithEvents contra As TextBox
Protected WithEvents dominio As TextBox
Protected WithEvents destino As TextBox
Protected WithEvents origen As TextBox
Protected WithEvents temporal As TextBox
Protected WithEvents log As TextBox
'Render this Web Part to the output parameter specified.
Protected Overrides Sub RenderWebPart(ByVal output As System.Web.UI.HtmlTextWriter)
log.RenderControl(output)
output.Write("<br><font>Ruta Origen</font><br>")
File1.RenderControl(output)
output.Write("<br><font>Ruta Temporal </font><br>")
temporal.RenderControl(output)
output.Write("<br><font>Ruta Destino </font><br>")
destino.RenderControl(output)
output.Write("<br><font>Usuario </font><br>")
usuario.RenderControl(output)
output.Write("<br><font>Contraseña </font><br>")
contra.RenderControl(output)
output.Write("<br><font>Dominio </font><br>")
dominio.RenderControl(output)
output.Write("<br><br><center>")
boton1.RenderControl(output)
output.Write("</center>")
End Sub
Protected Overrides Sub CreateChildControls()
dominio = New TextBox
With dominio
.Text = "admon-cfnavarra"
.Width = Unit.Pixel("255")
End With
Controls.Add(dominio)
boton1 = New Button
With boton1
.Text = "Copiar Fichero"
End With
Controls.Add(boton1)
File1 = New HtmlInputFile
With File1
End With
Controls.Add(File1)
usuario = New TextBox
With usuario
.Text = "SVCWSINCPre_SNS"
.Width = Unit.Pixel("255")
End With
Controls.Add(usuario)
contra = New TextBox
With contra
.Text = "SVCWSINCPre_SNS"
.Width = Unit.Pixel("255")
End With
Controls.Add(contra)
destino = New TextBox
With destino
.Text = vdestino
.Width = Unit.Pixel("255")
End With
Controls.Add(destino)
log = New TextBox
With log
.Width = Unit.Percentage(100)
.BackColor = System.Drawing.Color.Black
.ForeColor = System.Drawing.Color.White
End With
Controls.Add(log)
temporal = New TextBox
With temporal
.Text = vtemporal
.Width = Unit.Pixel("255")
End With
Controls.Add(temporal)
End Sub
Private Sub boton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles boton1.Click
If File1.PostedFile.FileName <> "" Then
Dim _objContext As WindowsImpersonationContext = Nothing
log.Text = QuienSoy()
CopyFile(File1.PostedFile.FileName, temporal.Text)
_objContext = Impersonalizacion.WinLogOn(usuario.Text, contra.Text, dominio.Text)
CopyFile(temporal.Text & "\" & System.IO.Path.GetFileName(File1.PostedFile.FileName), destino.Text)
_objContext.Undo()
Else
log.Text = "Se debe introducir un fichero"
End If
End Sub
Friend Shared Function QuienSoy() As String
Return WindowsIdentity.GetCurrent().Name
End Function
Public Function CopyFile(ByVal StartPath As String, ByVal EndPath As String)
Try
Dim fn As String = System.IO.Path.GetFileName(StartPath)
System.IO.File.Copy(StartPath, EndPath & "\" & fn, False)
log.Text = "Fichero Copiado Correctamente"
Catch ex As Exception
log.Text = ex.Message
End Try
End Function
Clase final