我已經創建了使用IWA的asp.net(vb.net)網站。完全沒有問題。使用ASP.NET時如何模擬Windows Credentials?
但是,現在我擁有的用戶不一定是我公司域的一部分,但需要登錄我的網絡才能訪問公共信息。
我在我的AD上創建了一個公共賬戶。我想要做的是,當外部用戶登錄時,能夠傳遞公共賬戶憑據,以便他們可以訪問公共信息。
這可能嗎?
我已經創建了使用IWA的asp.net(vb.net)網站。完全沒有問題。使用ASP.NET時如何模擬Windows Credentials?
但是,現在我擁有的用戶不一定是我公司域的一部分,但需要登錄我的網絡才能訪問公共信息。
我在我的AD上創建了一個公共賬戶。我想要做的是,當外部用戶登錄時,能夠傳遞公共賬戶憑據,以便他們可以訪問公共信息。
這可能嗎?
您可以臨時模擬用戶:
在C#,但你可以很容易將其翻譯成VB
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
if (LogonUser("TempUser", Environment.MachineName,
"password", LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, SecurityImpersonation, ref tokenDuplicate) != 0)
{
m_ImpersonatedUser = new WindowsIdentity(tokenDuplicate);
m_ImpersonationContext = m_ImpersonatedUser.Impersonate();
try
{
// impersonated code here
}
catch { throw; }
finally
{
m_ImpersonationContext.Undo();
}
}
}
}
你可以使用身份模擬在web.config設置設置憑據:
<system.web>
<authentication mode="Windows"/>
<identity impersonate="true" userName="foo" password="bar"/>
</system.web>
,使密碼不存儲在明文你也應該加密的web.config。 http://msdn.microsoft.com/en-us/library/89211k9b.aspx
另一種選擇是讓您的用戶能夠在代碼中模擬您的服務帳戶。請注意,這個代碼在C#中,但我寫它爲飛行Windows模仿。它可以被編譯成一個DLL和引用在VB.NET:
/// <summary>
/// Facilitates impersonation of a Windows User.
/// </summary>
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
public string Environment { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string DomainName { get; set; }
public enum LogonType
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
public enum LogonProvider
{
Default = 0,
WinNT35 = 1,
WinNT40 = 2,
WinNT50 = 3
}
/// <summary>
/// Windows Token.
/// </summary>
private readonly SafeTokenHandle _handle;
/// <summary>
/// The impersonated User.
/// </summary>
private WindowsImpersonationContext impersonatedUser;
public Impersonation()
{
}
/// <summary>
/// Initializes a new instance of the Impersonation class. Provides domain, user name, and password for impersonation.
/// </summary>
/// <param name="domainName">Domain name of the impersonated user.</param>
/// <param name="userName">Name of the impersonated user.</param>
/// <param name="password">Password of the impersonated user.</param>
/// <remarks>
/// Uses the unmanaged LogonUser function to get the user token for
/// the specified user, domain, and password.
/// </remarks>
public Impersonation(AccountCredentials credentials)
{
string[] splitName = WindowsIdentity.GetCurrent().Name.Split('\\');
string name = (splitName.Length > 0) ? splitName[0] : null;
LogonType logonType = LogonType.Interactive;
LogonProvider logonProvider = LogonProvider.Default;
if (name != credentials.Domain)
{
logonType = LogonType.NewCredentials;
logonProvider = LogonProvider.WinNT50;
}
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
credentials.UserName,
credentials.Domain,
credentials.Password,
(int)logonType,
(int)logonProvider,
out this._handle);
if (!returnValue)
{
// Something went wrong.
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
this.impersonatedUser = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
}
/// <summary>
/// Initializes a new instance of the Impersonation class. Provide domain, user name, and password for impersonation.
/// </summary>
/// <param name="domainName">Domain name of the impersonated user.</param>
/// <param name="userName">Name of the impersonated user.</param>
/// <param name="password">Password of the impersonated user.</param>
/// <remarks>
/// Uses the unmanaged LogonUser function to get the user token for
/// the specified user, domain, and password.
/// </remarks>
public Impersonation(string domainName, string userName, string password)
{
string[] splitName = WindowsIdentity.GetCurrent().Name.Split('\\');
string name = (splitName.Length > 0) ? splitName[0] : null;
LogonType logonType = LogonType.Interactive;
LogonProvider logonProvider = LogonProvider.Default;
if (name != domainName)
{
logonType = LogonType.NewCredentials;
logonProvider = LogonProvider.WinNT50;
}
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
userName,
domainName,
password,
(int)logonType,
(int)logonProvider,
out this._handle);
if (!returnValue)
{
// Something went wrong.
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
this.impersonatedUser = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
}
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
public void Dispose()
{
this.impersonatedUser.Dispose();
this._handle.Dispose();
}
private static string[] GetAccountInfo(string accountInfo)
{
return accountInfo.Split(' ');
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true) { }
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
public class AccountCredentials
{
public string UserName { get; set; }
public string Password { get; set; }
public string Domain { get; set; }
}
然後你會做一個使用塊你模擬的動作:
using(new Impersonation(new AccountCredentials("user", "password", "domain"))
{
// do impersonated actions
}
您必須使用這些指令在類:
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security.Principal;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
using System.Configuration;
了翔實的答案謝謝你們......對不起,找回這麼晚了......所以,我現在所做的就是這個....
進口System.Web.Security
進口System.Security.Principal
進口System.Security.Permissions
進口System.Runtime.InteropServices
進口統環境
公共類重定向 繼承System.Web.UI.Page
Dim LOGON32_LOGON_INTERACTIVE As Integer = 2
Dim LOGON32_PROVIDER_DEFAULT As Integer = 0
Dim impersonationContext As WindowsImpersonationContext
Declare Function LogonUserA Lib "advapi32.dll" (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 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
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim redirstr As Integer
redirstr = Request.QueryString("id")
If impersonateValidUser("*username*", "*Domain*", "*Password*") Then
'Insert your code that runs under the security context of a specific user here.
Try
'Integrated Windows Authentication Site
Response.Redirect("http://<<servername>>/<app>/<<file>")
Catch ex As Exception
End Try
undoImpersonation()
Else
'Your impersonation failed. Therefore, include a fail-safe mechanism here.
'Not Integrated Windows Authentication Site
Response.Redirect("http://<<servername>>:81/<app>/<<file>?user=<<username>>&pass=<<password>>)
End If
End Sub
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
末級
所以在這種情況下,理想的應該傳遞行動的IWA網站,如果我的身份驗證通過它的確如此,但是一旦我進入IWA網站,就需要我的Windows憑據,而不是我想要模仿的那個。我如何實現這一點...哪裏可以使用我的模擬的Windows用戶憑據去網站?
這將使他的所有用戶都承擔這個Windows憑據,這不是他所需要的。他正在研究某種混合模式身份驗證,網絡內的用戶使用他們的憑據,但外部用戶應使用所有相同的帳戶。 – tucaz
我添加了用於在飛行模擬中執行的代碼。它是用C#編寫的,但可以在VB.NET中作爲DLL引用。 –