我们有一个ASP.NET站点,部分依赖于登录凭据的表单身份验证,但IPrincipal的实现完全是自定义的 .
但是,当在特定服务器上运行该站点时(在安全性方面有点半硬化),当使用以下消息调用IPrincipal.IsInRole()时,应用程序崩溃:
System.SystemException:主域和受信任域之间的信任关系失败 .
这表明Web服务器和DC之间存在通信错误,但由于我们的应用程序根本不使用Windows身份验证,因此我不明白为什么需要与DC通信 .
这是我的实施:
[Serializable]
public class CustomPrincipal : IPrincipal
{
public CustomPrincipal( IUser userObj )
{
this.Identity = new CustomIdentity( userObj.Id, userObj.Username );
}
public bool IsInRole( string role )
{
if ( role == null )
return false;
var roles = HttpContext.Current.Session["authentication-roles"] as string[];
if (roles == null)
return false;
return Array.IndexOf( roles, role ) >= 0;
}
public IIdentity Identity { get; private set; }
public CustomIdentity FullIdentity
{
get { return (CustomIdentity) this.Identity; }
}
}
在本地调试它(它工作的地方)时,它是实际运行的正确实现 . 用法如下:
public override void Render()
{
var items = this.manager.Items
.Where( i => EngineContext.CurrentUser.IsInRole( i.Role.InternalName ) );
在这里设置断点使我发现EngineContext.CurrentUser实际上是CustomPrincipal的实现 .
有没有人经历过这个? ASP.NET似乎仍然可能触发Interface方法上的任何LDAP查找?
我发现了这个,http://support.microsoft.com/kb/976494但是在我的环境中,web-server和DC都是2008 R2,所以这不应该依赖于LDAP,这应该不是问题 .
安全系统无法与服务器ldap / ddc.domain.com / xxxxxxxxxxxxx Build 安全连接 . 没有可用的身份验证协议 .
服务器超出了我的范围,这意味着我自己无法解决这个问题,但我确实有一个支持票,但出于安全原因(尽管看起来很愚蠢)可能是故意这样设置的 .
有没有人遇到过这个问题?
后续:堆栈跟踪显示:
at System.Security.Principal.NTAccount.TranslateToSids(IdentityReferenceCollection sourceAccounts, Boolean& someFailed)
at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)
at System.Security.Principal.WindowsPrincipal.IsInRole(String role)
at Company.Sites.Manager.ViewComponents.MenuComponent.<Render>b__0(INavigationItem i)
编辑:
我终于能够在我的开发机器上重现这个错误(我昨天从DC撤销了我的机器,但直到今天才重现它)
看来HttpContext.User实际上是一个WindowsPrincipal,我的代码中的错误是我在登录时只用CustomPrincipal替换它 . 因此,未经身份验证的用户仍然可以获得WindowsPrincipal,如果您的AD上存在信任问题,则可能会失败 .
我尝试通过在appstart上调用它来更改默认主体
AppDomain.CurrentDomain.SetPrincipalPolicy( PrincipalPolicy.NoPrincipal);
但这似乎没有起作用 . 如何在ASP.NET中更改默认的Principal?
1 回答
我认为是WindowsAuthenticationModule将WindowsPrincipal添加到HttpContext.User,但删除它仍然给出了同样的问题 . 这篇文章暗示了这一点:
http://msdn.microsoft.com/en-us/library/ff647076.aspx
我尝试设置AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.NoPrincipal);
在appstart和OnAuthenticateRequest上作为建议但无济于事 .
但是,这有效(在OnAuthenticateRequest中):
我现在会满足于此 . 感谢大家的投入!