Mentioned
In
|
 |
 |
 |
 |
Microsoft Knowledge Base Article
This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved. Terms
of Use |
Trademarks
Article ID: 842789 - Last Review: April 3, 2007 - Revision: 3.4 You receive a "logon failure: unknown user name or bad" error message while accessing remote security-enhanced resources from an ASP.NET applicationThis article discusses the behavior of accessing a remote security-enhanced resource from a Microsoft ASP.NET application. The article contains the following workarounds for this behavior: In the Machine.config file, change the userName attribute and the password attribute of the processModel element. Run the application under the identity of a user who has permissions to the remote security-enhanced resource by using the impersonation element in the Web.config file. Change the password of the ASPNET user account to some known value, and then create the same ASPNET user account that uses the same password on the remote computer. Access the remote security-enhanced resource by using a COM component that is running under the security context of a user account that has permissions to the remote security-enhanced resource. Run the part of the code that is accessing the remote security-enhanced resource under the identity of a user who has permissions to the remote security-enhanced resource. Call the WNetAddConnection2 function to open the connection to the remote security-enhanced
resource, and then map the local drive to the remote security-enhanced resource
in the code.
This article also includes detailed steps to reproduce the behavior. When you access remote security-enhanced resources from an
ASP.NET application, you may receive the following error message: Logon failure: unknown user name or bad
password. By default, an ASP.NET application runs under the security
context of an ASPNET user account. The ASP.NET application accesses the remote
security-enhanced resource by using the ASPNET user account when the following
conditions are true:
- When the impersonation feature is not turned on for the
ASP.NET application
- When the authentication method in Microsoft Internet
Information Services (IIS) is set to anonymous access
However, the ASPNET user account may not have permissions to
access the remote security-enhanced resource. To work
around this behavior, use one of the following methods:
Use the Machine.config fileChange the userName attribute and the password attribute in the processModel element of the Machine.config file to the credentials of a user
who has access to the remote security-enhanced resource. After you make this
change, restart the computer.
<processModel enable="true"
userName="<UserName>"
password="<Password>" . . ./>
Note <UserName> and
<Password> are placeholders for the
credentials of a user who has access to the remote security-enhanced
resource. Important Do not to store clear-text passwords in the Machine.config file.
Instead, use the Aspnet_setreg.exe utility to store encrypted passwords in the
registry.
For additional information about how to use the
Aspnet_setreg utility, click the following article number to view the article
in the Microsoft Knowledge Base: 329290Â
(http://kbalertz.com/Feedback.aspx?kbNumber=329290/
)
How to use the ASP.NET utility to encrypt credentials and session state connection strings
When you use this method, the change is global.
This is a drawback because other Web applications and other Web services that
are running on the computer where you make the change will also run in this new
security context. However, this is not the case for Microsoft Internet
Information Services (IIS) 6.0 on Microsoft Windows Server 2003 because IIS
uses application pools for Web applications and for Web services. Each
application can run in its own application pool. Each application pool can be
configured for the user name field and the password field. You can set this
configuration under the security context of the worker process in the
application pool where the application runs. If you change the user
account under the security context that the ASP.NET worker process is running
in, you may also have to grant the correct permissions to that user account on
some folders on the Web server to make the worker process run successfully.
For more information about how to create a custom account to run
ASP.NET applications, visit the following Microsoft Developer Network (MSDN)
Web site: Use the impersonation feature in the Web.config fileYou can set fixed identities that have access to the remote
security-enhanced resource for specific virtual directories by using the
following setting in the Web.config file for your application. <identity impersonate="true"
userName="<UserName>"
password="<Password>"/> Note <UserName> and
<Password> are placeholders for the
credentials of a user who has access to the remote security-enhanced
resource. Important Do not to store clear-text passwords in the Machine.config file.
Instead, use the Aspnet_setreg.exe utility to store encrypted passwords in the
registry.
For additional information about how to use the
Aspnet_setreg utility, click the following article number to view the article
in the Microsoft Knowledge Base: 329290Â
(http://kbalertz.com/Feedback.aspx?kbNumber=329290/
)
How to use the ASP.NET utility to encrypt credentials and session state connection strings
You can use one of the following accounts for
impersonation:
- A domain account
- A "mirrored" local account
A "mirrored" local account has a matching user name and a
matching password on two computers. You must use this account if the computers
are in separate domains and do not have a trust
relationship. Change the password of the ASPNET user accountBy default, the ASP.NET worker process (Aspnet_wp.exe) runs under
the ASPNET user account. The ASPNET user account is located under Local
Users and Groups. This account has a strong password that is secured
in the Local System Authority (LSA). To use this method, follow these
steps:
- In Local Users and Groups on the Web server, change the
ASPNET account password to a known value.
- Replace the credentials in the processModel element in the Machine.config file with the following.
<processModel enable="true"
userName="ASPNET"
password="<Password>" . . ./> Note <Password> is the placeholder for
the password that you have assigned to the ASPNET user account. - On the remote computer, create an account that is named
ASPNET and that has the same password as the ASPNET user account on the Web
server.
- Add the ASPNET account on the remote computer to the Access
Control List (ACL) of the security-enhanced resource.
Use a COM component to access the remote security-enhanced resource- Create an ActiveX component:
- Start Microsoft Visual Basic 6.0.
- Create an ActiveX Dll project.
- On the Project menu, click
References. The References dialog box
appears.
- Click to select the Microsoft Scripting
Runtime check box in the Available References list
box to add the reference in your project.
- Click OK.
- Press CTRL+R to open Project Explorer, click
Project1, and then press F4 to access the properties for the
project.
- Change the Name property to
remoteAccess.
- In Project Explorer, click Class1.cls,
and then change the Name property to
clsRemoteAccess.
- On the File menu, click Save
Project. The Save File As dialog box
appears.
- Save the class file as clsRemoteAccess.cls.
- Save the project file as remoteAccess.vbp.
- Paste the following code in the code window of the clsRemoteAccess class:
Public fs As New FileSystemObject
Public txtStream As TextStream
'
Public Function WriteToFile() As Boolean
On Error GoTo Erro
Set txtStream = fs.OpenTextFile("\\<ServerName>\<ShareName>\<TextFileName>", ForAppending, False)
'
txtStream.WriteLine ("Hi i am able to write")
txtStream.Close
WriteToFile = True
Exit Function
Erro:
WriteToFile = False
End Function Note <ServerName>,
<ShareName>, and
<TextFileName> are placeholders for these
values in your environment. - On the File menu, click Make
remoteAccess.dll. The Make Project dialog box
appears.
- Click OK.
- On the File menu, click
Exit. The Microsoft Visual Basic dialog box
appears.
- Click Yes.
- Create a COM+ application:
- On a computer that is running the Microsoft Windows
2000 Advance Server operating system, click Start, point to
Programs, point to Administrative Tools, and
then click Component Services. The Component
Services dialog box appears.
- Expand Component Services, expand
Computers, expand My Computer, and then click
COM+ Applications.
- Right-click COM+ Applications, click
New, and then click Application. The
Welcome to the COM Application Install Wizard wizard
appears.
- Click Next.
- Click Create an empty
application.
- In the Enter a name for the new
application box, type remoteComponent, and then
click Next.
- Click This user.
- In the User box, type the name of a
user who has access to the remote security-enhanced resource.
- In the Password box, type the password
for the user account.
- In the Confirm password box, type the
password again.
- Click Next, and then click
Finish.
- Add the ActiveX component to the COM+ application:
- In the left pane of the Component
Services dialog box, expand COM+ Applications, expand
remoteComponent, and then click
Components.
- Right-click Components, point to
New, and then click Component. The
Welcome to the COM Component Install Wizard wizard
appears.
- Click Next.
- Click Install new
component(s).
- Locate the remoteAccess.dll file that you created in
step 1.
- Click Open, click
Next, and then click Finish. This step
installs the dynamic link library (DLL) in the COM+ application.
- Use the COM component in the ASP.NET application:
- Start Microsoft Visual Studio .NET.
- On the File menu, point to
New, and then click Project. The New
Project dialog box appears.
- Under Project Types, click
Visual Basic Projects.
- Under Templates, click ASP.NET
Web Application, and then click OK.
- In Solution Explorer, right-click
References, and then click Add Reference. The
Add Reference dialog box appears.
- Click the COM tab.
- In the Component Name column, click
remoteAccess.
- Click Select, and then click
OK.
- In Solution Explorer, right-click the
WebForm1.aspx file, and then click View
Code.
- Paste the following code at the top of the
WebForm1.aspx.vb file.
- Locate the Page_Load method.
- Paste the following code in the Page_Load method.
Dim objRemoteAccess As New clsRemoteAccessClass
Dim blnWriteResult As Boolean
'
blnWriteResult = objRemoteAccess.WriteToFile()
'
If (blnWriteResult) Then
Response.Write("Success")
Else
Response.Write("Failed")
End If
- On the Build menu, click Build
Solution.
- On the Debug menu, click
Start. You receive the success message in the
browser.
Use the code impersonation featureBy default, the ASP.NET worker process (Aspnet_wp.exe) runs under
the security context of the ASPNET user account. To use this method, the user
account under the security context that the ASP.NET worker process
(Aspnet_wp.exe) runs in must be part of the "Act as part of the operating
system" policy. You can use Local Security Policy in the
Windows Administrative Tools to add the ASPNET user account to the "Act as part
of the operating system" policy. Note To use this method, you must maintain a list of user names and
their corresponding passwords in your application. Because you are using those
user names and passwords to connect to the remote security-enhanced resources
from the code, you must make changes in your application when these user names
or their corresponding passwords change.
- Start Microsoft Visual Studio .NET
- On the File menu, point to
New, and then click Project. The New
Project dialog box appears.
- Select Visual Basic Projects under
Project Types.
- Select ASP.NET Web Application under
Templates.
- Click OK.
- Right-click the WebForm1.aspx file in the
solution explorer window, and then click View Code.
- Add the following code at the top of the
WebForm1.aspx.vb file.
Imports System.IO
Imports System.Security
Imports System.Security.Principal - Locate the Public Class WebForm1 Inherits
System.Web.UI.Page statement and then add the following code after the Public
Class WebForm1 Inherits System.Web.UI.Page statement.
Dim LOGON32_LOGON_INTERACTIVE As Integer = 2
Dim LOGON32_PROVIDER_DEFAULT As Integer = 0
'
Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpxzUsername As String, _
ByVal lpszDomain As String, _
ByVal lpszpassword As String, _
ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Integer
Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Integer
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
'
Declare Auto Function CloseHandle Lib "Kernel32.dll" (ByVal handle As IntPtr) As Long
'
Dim impersonationContext As WindowsImpersonationContext - Locate the Page_Load method, and then paste the following code in the Page_Load method.
Try
If impersonateValidUser("<UserName>", "", "<Password>") Then
Dim fs As New FileStream("\\<ServerName>\<ShareName>\<TextFileName>", FileMode.Append)
Dim w As New StreamWriter(fs)
Try
w.Write(w.NewLine)
w.WriteLine("Hi how are you")
w.Close()
fs.Close()
Catch
w.Close()
fs.Close()
End Try
'
undoImpersonation()
Response.Write("Success")
Else
Response.Write("Failure")
End If
Catch ex As Exception
Response.Write(ex.Message)
Response.Write(vbNewLine & User.Identity.Name)
Response.Write(vbNewLine)
Response.Write(vbNewLine & Principal.WindowsIdentity.GetCurrent.Name)
End Try Note <ServerName>,
<ShareName>,
<UserName>,
<Password>, and
<TextFileName> are placeholders for these
values in your environment. <Password> and
<UserName> are the values for the credential
of the user who has access to the
<TextFileName> file on the remote
computer. - Locate the End Sub statement and then paste the following code after the End Sub statement.
'
Private Function impersonateValidUser(ByVal userName As String, _
ByVal domain As String, ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
impersonateValidUser = False
'
If RevertToSelf() Then
If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _
LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
impersonateValidUser = True
End If
End If
End If
End If
'
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
'
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
'
End Function
'
Private Sub undoImpersonation()
impersonationContext.Undo()
End Sub - On the Build menu, click Build
Solution.
- On the Debug menu, click
Start. You receive the success message in the
browser.
Note To use this method, you must maintain a list of user names and
their corresponding passwords in your application. Because you are using those
user names and passwords to connect to the remote security-enhanced resources
from the code, you must make changes in your application when these user names
or their corresponding passwords change. Call the WNetAddConnection2 function in your codeTo use this method, you must call the WNetAddConnection2 function. The WNetAddConnection2 function makes a connection to a network resource. The function
can redirect a local device to the network resource. Note To use this method, you must maintain a list of user names and
their corresponding passwords in your application. Because you are using those
user names and passwords to connect to the remote security-enhanced resources
from the code, you must make changes in your application when these user names
or their corresponding passwords change.
- Start Microsoft Visual Studio .NET
- On the File menu, point to
New, and then click Project. The New
Project dialog box appears.
- Under Project Types, click Visual
Basic Projects.
- Under Templates, click ASP.NET Web
Application, and then click OK.
- In Solution Explorer, right-click the
WebForm1.aspx file, and then click View
Code.
- Add the following code at the top of the WebForm1.aspx.vb
file.
Imports System.IO
Imports System.Runtime.InteropServices - Add the following code after the Public Class WebForm1
Inherits System.Web.UI.Page statement.
'
Structure NETRESOURCE
Public dwScope As Int32
Public dwType As Int32
Public dwDisplayType As Int32
Public dwUsage As Int32
Public lpLocalName As String
Public lpRemoteName As String
Public lpComment As String
Public lpProvider As String
End Structure
'
Public Const NO_ERROR As Int32 = 0
Public Const CONNECT_UPDATE_PROFILE As Int32 = &H1
Public Const RESOURCETYPE_DISK As Int32 = &H1
'
Declare Function WNetAddConnection2 Lib "mpr.dll" Alias _
"WNetAddConnection2A" (ByRef lpNetResource As NETRESOURCE, _
<MarshalAs(UnmanagedType.LPStr)> ByVal lpPassword As String, <MarshalAs(UnmanagedType.LPStr)> ByVal lpUserName As String, _
ByVal dwFlags As Int32) As Int32
'
Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias _
"WNetCancelConnection2A" (ByVal lpName As String, _
ByVal dwFlags As Long, ByVal fForce As Long) As Long
- Locate the Page_Load method.
- Paste the following code in the Page_Load method.
Try
'
Dim Result As Long
Dim theNetResource As NETRESOURCE
theNetResource.dwType = RESOURCETYPE_DISK
theNetResource.lpRemoteName = "\\<ServerName>\<ShareName>"
theNetResource.lpLocalName = "X:"
'
Result = WNetAddConnection2(theNetResource, "<Password>", "<Domain\UserName>", CONNECT_UPDATE_PROFILE)
'
If (Result = NO_ERROR) Then
'
Dim fs As New FileStream("X:\<TextFileName>", FileMode.Append)
Dim w As New StreamWriter(fs)
'
Try
w.Write(w.NewLine)
w.WriteLine("Hi how are you")
w.Close()
fs.Close()
Response.Write("Success")
Catch
Response.Write("Failed")
w.Close()
fs.Close()
End Try
'
Else
Response.Write("Failed")
End If '
Result = WNetCancelConnection2(theNetResource.lpLocalName, 0, 0)
'
Catch
'
End Try
' Note <ServerName>,
<ShareName>,
<Password>,
<Domain\UserName>, and
<TextFileName> are placeholders for these
values in your environment. <Password> and
<Domain\UserName> are the values for the
credential of the user who has access to the
<TextFileName> file on the remote
computer. - On the Build menu, click Build
Solution.
- On the Debug menu, click
Start. You receive the success message in the
browser.
This
behavior is by design. Steps to reproduce the behaviorIn these steps, you write to a text file that is located on
another computer in the same network. This text file is secured from being
accessed through other computers in the network.
- Start Microsoft Visual Studio .NET
- On the File menu, point to
New, and then click Project. The New
Project dialog box appears.
- Under Project Types, click Visual
Basic Projects.
- Under Templates, click ASP.NET Web
Application.
- Click OK.
- In Solution Explorer, right-click the
WebForm1.aspx file, and then click View
Code.
- Add the following code at the top of the Webform1.aspx.vb
file.
Imports System.IO
Imports System.Security - Locate the Page_Load method.
- Paste the following code in the Page_Load method.
Try
Dim fs As New FileStream("\\<ServerName>\<ShareName>\<TextFileName>", FileMode.Append)
Dim w As New StreamWriter(fs)
'
Try
w.Write(w.NewLine)
w.WriteLine("Hi how are you")
w.Close()
fs.Close()
Catch
w.Close()
fs.Close()
End Try
'
Catch ex As Exception
Response.Write(ex.Message)
End Try Note <ServerName>,
<ShareName>, and
<TextFileName> are placeholders for these
values in your environment. - On the Build menu, click Build
Solution.
- On the Debug menu, click
Start.
You may receive the error message that is mentioned in the
"Symptoms" section.
For additional information, click the following article number to view the
article in the Microsoft Knowledge Base: 306158Â
(http://kbalertz.com/Feedback.aspx?kbNumber=306158/
)
INFO: Implementing impersonation in an ASP.NET application
306590Â
(http://kbalertz.com/Feedback.aspx?kbNumber=306590/
)
INFO: ASP.NET security overview
For more information, visit the following Microsoft
Developer Network (MSDN) Web sites:
APPLIES TO- Microsoft ASP.NET 1.1
- Microsoft ASP.NET 1.0
| kbfileio kbdll kbapi kbuser kbsettings kbpermissions kbpasswords kbconfig kbauthentication kbprb KB842789 |
Community Feedback System
Very often, it takes hours to solve a problem. Very often, you've looked high
and low, and have tried a lot of solutions. When you finally found it, chances
are, it was because someone else helped you. Here's your chance to give back.
Use our community feedback tool to let others know what worked for you and what
didn't.
Please also understand that the community feedback system is not warranted to be
correct, it's simply a system that we've built to let people try and help each
other. If something in a feedback response doesn't make sense to you, or you're
not comfortable making changes that the feedback talks about (like registry
edits), please consult a professional.
Thank you for using kbAlertz.com Feedback System.
-- Scott Cate
|
Nihal
- nihal.ekanayake NOSPAM-AT-NOSPAM gmail.com
|
Reported as Irrelevant
|
| Written:
9/9/2005 2:04 PM |
|
|
(Optional) Name
(Optional)
Public URL Or Email
Comments
No
HTML -- Text Only Please
|
 |
 |
 |
 |
 |
 |
 |
| |