我知道以下函数以domain\username格式返回当前Windows用户的名称.
Convert.ToString( WindowsIdentity.GetCurrent().Name );
Run Code Online (Sandbox Code Playgroud)
但是如何以username@domain格式获取用户名?
编辑:
我在这个编辑中做出回应,因为回复的每个人都有相同的基本想法.
根据我的理解,从domain\username格式中解析名称并将其构造为username@domain不安全或建议.我相信这是因为不能保证这两个域名在不同的格式中是相同的.例如,在我工作的公司中,格式的domain一部分domain\username基于deparment,但在username@domain,它是公司名称.这是需要DNS查找的事情.
我希望有一个API执行此DNS查找.我想我应该把这些信息放到原来的问题中.抱歉.
我一直在使用WIF来验证我们的新网站,STS基于starter-sts实现.
为了使其在负载均衡环境中正常工作,我在global.asax中使用了以下内容来覆盖默认的证书行为.
void onServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
{
List<CookieTransform> sessionTransforms = new List<CookieTransform>(new CookieTransform[]
{
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform(e.ServiceConfiguration.ServiceCertificate),
new RsaSignatureCookieTransform(e.ServiceConfiguration.ServiceCertificate)
});
SessionSecurityTokenHandler sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);
}
Run Code Online (Sandbox Code Playgroud)
这一切都正常工作,人们已成功使用该系统,但不时我们得到一个爆炸:
ID1014:签名无效.数据可能已被篡改.
在事件日志中,所以我打开了WIF跟踪,并在日志中看到了以下提到的内容.
ID1074:尝试使用ProtectedData API加密cookie时发生CryptographicException(有关详细信息,请参阅内部异常).如果您使用的是IIS 7.5,则可能是由于应用程序池上的loadUserProfile设置被设置为false.
我有一种感觉,正如我想的那样,这导致我走入一条黑暗的小巷,因为我改变了使用RSA的实现,这不应该影响我.
有什么想法可以帮到我吗?
我有一个MVC站点,允许使用Forms登录和Windows身份验证登录.我使用自定义MembershipProvider对Active Directory进行身份验证,使用System.Web.Helpers AntiForgery类进行CSRF保护,以及Owin cookie身份验证中间件.
在登录期间,一旦用户通过了针对Active Directory的身份验证,我将执行以下操作:
IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut(StringConstants.ApplicationCookie);
var identity = new ClaimsIdentity(StringConstants.ApplicationCookie,
ClaimsIdentity.DefaultNameClaimType,
ClaimsIdentity.DefaultRoleClaimType);
if(HttpContext.Current.User.Identity is WindowsIdentity)
{
identity.AddClaims(((WindowsIdentity)HttpContext.Current.User.Identity).Claims);
}
else
{
identity.AddClaim(new Claim(ClaimTypes.Name, userData.Name));
}
identity.AddClaim(new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "Active Directory"));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userData.userGuid));
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, identity);
Run Code Online (Sandbox Code Playgroud)
我的SignOut函数如下所示:
IAuthenticationManager authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut(StringConstants.ApplicationCookie);
Run Code Online (Sandbox Code Playgroud)
登录是通过jQuery.ajax请求执行的.成功后,Window.location会更新到站点的主页面.
使用Forms和IntegratedWindowsAuthentication(IWA)登录都可以,但是在使用IWA登录时遇到了问题.这是发生的事情:
User.Identity此时的类型为WindowsIdentity与AuthenticationType设置为Negotiate …我有一个ASP.NET应用程序,要求用户使用基本身份验证登录其域帐户.用户可以进行选择,然后按下按钮.
在按下按钮后的某个时刻是这段代码:WindowsIdentity.Impersonate(userIdentity.Token).userIdentity的类型为WindowsIdentity,之前设置为(WindowsIdentity)User.Identity.
userIdentity存储为会话变量,我认为这是因为按下按钮后,包含此代码的页面将通过AJAX调用.
当我点击这段代码时,它大约有2/3的时间,但是1/3的时间,我得到了这个例外:用于模仿的无效令牌 - 它不能被复制.我觉得对我来说最大的问题是为什么它有时会起作用而不是其他时候?在某些会话中,它在失败之前会工作几次.在其他人,它立即失败.
这是堆栈跟踪:
在System.Security.Principal.WindowsIdentity.CreateFromToken(IntPtr userToken)
在System.Security.Principal.WindowsIdentity..ctor(IntPtr userToken,String authType,Int32 isAuthenticated)
在System.Security.Principal.WindowsIdentity.Impersonate(IntPtr userToken)
at Resource_Booker.BLL.ReservationAgent.SubmitReservationRequest(预订,Patron赞助人)在C:\ dev\RoomRes\Resource Booker\BLL\ReservationAgent.cs:第101行
在C:\ dev\RoomRes\Resource Booker\Reserve.aspx.cs中的Resource_Booker.Reserve.reserve_Click(Object sender,EventArgs e):第474行
在System.EventHandler.Invoke(Object sender,EventArgs e)
在System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
在System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)
这是一个令人困惑的因素:我无法在我的本地Windows 7 x64工作站上重现此问题 - 虽然我的身份验证是在此处隐式传递的,因为我使用的是localhost - 或者在Windows 2003 32位IIS 6.0环境中.它只发生在一个漂亮的Windows 2008 R2环境中.所有这些环境都是域成员.
下面的代码示例用于返回我之前的windows id,但现在它不起作用,并返回空字符串,dunno为什么.
function GetWindowsID: string;
var
Registry: TRegistry;
str:string;
begin
Registry := TRegistry.Create(KEY_WRITE);
try
Registry.Lazywrite := false;
Registry.RootKey := HKEY_LOCAL_MACHINE;
// Registry.RootKey := HKEY_CURRENT_USER;
if CheckForWinNT = true then
Begin
if not Registry.OpenKeyReadOnly('\Software\Microsoft\Windows NT\CurrentVersion') then showmessagE('cant open');
end
else
Registry.OpenKeyReadOnly('\Software\Microsoft\Windows\CurrentVersion');
str := Registry.ReadString('ProductId');
result:=str;
Registry.CloseKey;
finally
Registry.Free;
end; // try..finally
end;
Run Code Online (Sandbox Code Playgroud)
有人可以帮忙吗?
我正在构建一个使用当前用户的WindowsIdentity获取用户信息的站点.我从中得到的主要信息是ssid.
我为当前用户执行此操作,如下所示
IntPtr logonToken = WindowsIdentity.GetCurrent().Token;
WindowsIdentity windowsId = new WindowsIdentity(logonToken);
string ssid = windowsId.User.ToString();
Run Code Online (Sandbox Code Playgroud)
我现在需要做的是,并且失败了,就是获取域中存在的任意用户名的ssid.
我尝试了WindowsIdentity(字符串),但这给了我一个SecurityException
提供的名称不是正确形成的帐户名称.
我坚持这个问题.
我有UNC分享,我知道帐户详细信息,有成功,但它无法访问我的本地系统.我可以通过以下方式访问远程UNC:
var token = default(IntPtr);
var context = default(WindowsImpersonationContext);
LogonUser(_config.Username, _config.Domain, _config.Password, 2, 0, out token);
context = WindowsIdentity.Impersonate(token);
//TODO :: System.IO operations
File.Copy("remote-unc-path","local-path",true); // Exception : Access is denied.
context.Undo();
CloseHandle(token);
Run Code Online (Sandbox Code Playgroud)
但是,我无法在模拟期间访问我的本地系统,因为帐户无法访问它.
在这种情况下如何复制文件?我是否需要使用像缓冲区这样的东西来打开/关闭模拟?
我在PowerShell和C#中执行模拟时遇到了一些奇怪的错误.执行以下代码不会显示任何错误.
PSObject result = null;
using (PowerShell powershell = PowerShell.Create())
{
RunspaceConfiguration config = RunspaceConfiguration.Create();
powershell.Runspace = RunspaceFactory.CreateRunspace(config);
powershell.Runspace.Open();
powershell.AddScript(String.Format(CmdletMap[PSVocab.OsBootTime],
this.ComputerName));
result = powershell.Invoke().First();
powershell.Runspace.Close();
}
return DateTime.Parse(result.ToString());
Run Code Online (Sandbox Code Playgroud)
PS脚本的CmdletMap[PSVocab.OsBootTime]简单地说是:
$info = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $computer
; $info.ConvertToDateTime($info.LastBootUpTime)
Run Code Online (Sandbox Code Playgroud)
上面的C#代码在本地工作正常.但是,一旦我有这样的模块与Windows模拟如此:
WindowsIdentity ImpersonatedIdentity = new WindowsIdentity(ImpersonateUserName);
WindowsImpersonationContext impersonatedContext
= ImpersonatedIdentity.Impersonate();
try
{
PSObject result = null;
using (PowerShell powershell = PowerShell.Create())
{
RunspaceConfiguration config = RunspaceConfiguration.Create();
powershell.Runspace = RunspaceFactory.CreateRunspace(config);
powershell.Runspace.Open();
powershell.AddScript(String.Format(CmdletMap[PSVocab.OsBootTime],
this.ComputerName));
result = powershell.Invoke().First();
powershell.Runspace.Close();
}
return DateTime.Parse(result.ToString());
} …Run Code Online (Sandbox Code Playgroud) 我们在生产环境中得到与此线程完全相同的错误.[ WIF安全令牌缓存
有人解决了这个错误吗?消息:ID4243:无法创建SecurityToken.在令牌缓存中找不到令牌,并且在上下文中未找到cookie.
以下是有关我们设置的一些信息:
•我们在.NET Framework 4.5.1中使用内置Windows Identity Framework
•问题几乎总是与从RelyingParty#X更改为RelyingParty #Y相关联(例如,当用户点击RP#Y他已经签名而没有要求时) - 当他在此事件后再次登录时,他被带到了他要求的页面,在RP#Y内
•我们正在使用e.SessionToken.IsReferenceMode = true; //在服务器上缓存,以获得更小的cookie
•通过使用IsReferenceMode = true,我们的FedAuth cookie存储一个指向实际令牌的"指针",该指针存储在我们的数据库中
•我们使用自己的DatabaseSecurityTokenCache,它覆盖了SessionSecurityTokenCache中的函数.通过使用DatabaseSecurityTokenCache和IsSessionMode = true,我们对服务器场友好(但我们也保证在所有登录会话中都在同一服务器内)所以如果由于某种原因应用程序池死了,我们'能够通过DatabaseSecurityTokenCache从数据库中获取令牌.我已经通过在会话中间完全杀死IIS来验证这一点(使用"net stop WAS"并使用"net start W3SVC"重新启动它,我们仍然可以从DatabaseSecurityTokenCache获取令牌).我也试过通过简单地使用开箱即用的SessionSecurityTokenCache来做同样的事情,并且会分别失败(如预期的那样)
•默认令牌生存期为20分钟(但如果用户可以将其更改为40或60分钟) - 这只会在用户下次登录时生效(并且90%的用户只使用默认令牌20)分钟寿命)
•我们使用证书(在所有服务器上都相同)来加密FedAuth cookie,而不是机器密钥(如果使用服务器场,使用不同的机器密钥,那将是灾难性的)
•因此所有服务器都可以解密从其他服务器加密的cookie.
•我们在RelyingParty4和RelyingParty5(两个不同的依赖方)中有一个倒计时的javascript,用作"超时脚本",以防用户无人看管他的计算机......当令牌即将退出时,他将退出到期 - (减去)30秒(例如20分钟 - 30秒= 19,5分钟),空闲时间.这是保护我们非常敏感的银行信息,因此当用户回到他的机器时,他将需要再次登录.例如,我们也在使用滑动会话([ http://www.cloudidentity.com/blog/2013/05/08/sliding-sessions-for-wif-4-5/]),当我们滑动时,客户端的javascript也会更新,以匹配令牌的长度减去30秒.这30秒用于确保注销时会话仍处于活动状态,因此它比令牌/会话的生命周期短一点.如果满足这个条件,我们目前正在滑动:总寿命/ 2 ....例如20/2
•如果用户正在进行任何活动(即他正在四处走动,做一些工作),我们只会滑动.如上例所示,我们在minute10 +中滑动(如果令牌寿命为20min)
•我们多次调试问题,这是我们得到的WIF错误:异常:System.IdentityModel.Tokens.SecurityTokenException消息:ID4243:无法创建SecurityToken.在令牌缓存中找不到令牌,并且在上下文中未找到cookie.源:Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader,SecurityTokenResolver tokenResolver)中的Microsoft.IdentityModel,位于Microsoft.IdentityModel.Web.SessionAuthenticationModule的Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte []标记,SecurityTokenResolver tokenResolver). System.Web.HttpApplication.SyncEventExecutionStep.System.Web上的Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender,EventArgs eventArgs)中的Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken&sessionToken)上的ReadSessionTokenFromCookie(Byte [] sessionCookie) System.Web.HttpApplication.ExecuteStep中的.HttpApplication.IExecutionStep.Execute()(IExecutionStep step,Boolean&completedSynchronously)
•我们已经能够通过使用旧的FedAuth cookie和这个插件来重新生成错误:(注意!我们不确定这是否与PROD上发生的情况相同,但至少它会给出相同的错误我们的记录系统)这很好,但我认为你应该添加一些步骤,了解我们如何能够修改FedAuth cookie的内容,在本地实现这个问题.-你可以使用它:它很简单以前会话中的FedAuth cookie的值(在同一台机器上!不是来自另一台机器,不起作用)并将其粘贴到FedAuth cookie的值中并刷新页面.-
用于修改Cookie的插件,在Chrome中称为"编辑此Cookie": - 如果我们将此Cookie的内容更改为上一个会话的值,并点击刷新(Chrome中的CTRL + R),我们就会得到臭名昭着的TokenSecurityException ID4243和RP呼叫一个联邦FederatedSignout因为我们无法从这种情况中恢复.
退出....
我还应该提一下,我们认真对待IsReferenceMode上的Microsoft MSDN文章标记为"重要",并将其添加到我们的
SessionAuthenticationModule_SessionSecurityTokenCreated事件:
e.SessionToken.IsReferenceMode = true;
取自MSDN:
重要!要在参考模式下运行,Microsoft建议为global.asax.cs文件中的WSFederationAuthenticationModule.SessionSecurityTokenCreated事件提供处理程序,并在SessionSecurityTokenCreatedEventArgs.SessionToken属性中传递的令牌上设置SessionSecurityToken.IsReferenceMode属性.这将确保会话令牌在每个请求的参考模式下运行,并且优于仅在会话认证模块上设置SessionAuthenticationModule.IsReferenceMode属性.
下面是我们的整个SessionAuthenticationModule_SessionSecurityTokenReceived,请检查我在其中添加的评论...它解释了所有内容:
void …Run Code Online (Sandbox Code Playgroud) 我正在使用WindowsPrincipal的IsInRole方法来检查WPF和Winforms应用程序中的组成员身份.我正在生成一个身份令牌,可以用于任何AD用户(不一定是实际登录到计算机的用户 - 取决于我正在做什么我不一定要进行身份验证,我只使用基本的信息级令牌(我认为它的正确名称是"身份令牌").
第一次在特定计算机上运行此代码时,操作系统会为指定的用户生成标识令牌.然后,IsInRole函数使用该标记来验证组成员身份.它很快,所以我非常喜欢它.但是,后续调用创建WindowsIdentity/WindowsPrincipal会引用现有令牌而不是创建新令牌.我知道如何更新令牌的唯一方法是退出计算机或重新启动(清除令牌缓存).有谁知道重置缓存身份令牌的更好方法?
示例代码C#:
Using System.Security.Principal;
WindowsIdentity impersonationLevelIdentity = new WindowsIdentity("Some_UserID_That_Isn't_Me", null);
WindowsPrincipal identityWindowsPrincipal = new WindowsPrincipal(impersonationLevelIdentity);
If (identityWindowsPrincipal.IsInRole("AN_AD_GROUP")) { ...
Run Code Online (Sandbox Code Playgroud)
VB:
Imports System.Security.Principal
Dim impersonationLevelIdentity = New WindowsIdentity("Some_UserID_That_Isn't_Me", Nothing)
Dim identityWindowsPrincipal = New WindowsPrincipal(impersonationLevelIdentity)
if identityWindowsPrincipal.IsInRole("AN_AD_GROUP") then...
Run Code Online (Sandbox Code Playgroud)