我们有一个 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 怎么可能仍然触发接口方法上的任何 LDAP 查找?
我发现了这个,http://support.microsoft.com/kb/976494但在我的环境中,webs-server 和 DC 都是 2008 R2,所以这不应该适用。然而,我的事件日志中确实存在一些错误,表明与 DC 存在一些通信问题,但由于我们不依赖 LDAP,所以这应该不是问题。
安全系统无法与服务器 ldap/ddc.domain.com/xxxxxxxxxxxxx 建立安全连接。没有可用的身份验证协议。
服务器超出了我的范围,这意味着我无法自己解决这个问题,但是我确实有一个支持票,但出于安全原因可能有意进行此设置(即使它看起来很愚蠢)。
有没有人遇到过这个问题?
跟进:堆栈跟踪显示:
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 中的默认主体?