将HttpContext.Current.User.Identity传递给WCF

6

寻求一点建议(或者甚至是直接答案)。

我有一个MVC3网站。我也有一组正在运行的WCF服务(现在所有内容都在同一台机器上)。

我想要做的是验证客户端(那部分工作正常),然后将已验证的用户传递给各种WCF调用。

目前,我已经在Global.Asax中连接了Application_AuthenticateRequest()方法,这归结为创建一个新的GenericIdentity & GenericPrincipal,然后将该主体分配给HttpContext.Current.User

...
GenericIdentity identity = new GenericIdentity(userName);
GenericPrincipal principal = new GenericPrincipal(identity, null);
HttpContext.Current.User = principal;
...

看起来这部分也是正常工作的。

但是当我访问我的服务时,我完全失去了我设置的用户。值为空或为假。

我注意到的一个主要问题是,在客户端上,HttpContext.Current.User.Identity 对象的类型为 {System.Web.Security.FormsIdentity},但在服务中它的类型为 {System.Security.Principal.WindowsIdentity}

根据我所读的一些内容,似乎简单地修改我的 web.config 以包含 aspNetCompatibilityEnabled="true" 可能足以使其正常工作。但这不是我看到的。所以,要么我没有完全理解一切(这是一个很好的可能性),要么我搞砸了什么(另一个很好的可能性)。

所以我的问题是,这种情况是否可能发生,如果可能的话,你认为我错过了什么?我注意到有一些人发布了类似的问题,但从来没有得到明确的答案(请参见这里这里)。

非常感谢您的任何建议。


很奇怪你说你看到了一个 FormsIdentity,因为你明确在当前用户上下文中设置了一个 GenericIdentity。你是不是搞混了? - Mauricio Morales
1个回答

2
我不能直接回答你的问题,但希望能帮助你找到明确的答案。
您有两个服务层,似乎您的要求是在所有层之间共享身份验证标识。
因此,原则上,您需要(至少)相同的身份验证机制、算法或技术来实现这一点。但是在这一点上,您没有使用相同的机制(当您看到FormsIdentityWindowsIdentity时,您会注意到这一点)。
事实:
  • 您将需要相同的身份验证机制。
  • 无论使用什么机制,都需要支持您想要进行的第三次跳转(这意味着您可以在不重新验证凭据的情况下使用用户的身份验证与第三方服务)。
问题:
  • 如果您继续使用表单身份验证,则需要重新验证您的WCF服务(当然需要提供身份验证凭据,这可能会有所帮助)。除非您保留用户用于身份验证的密码,否则我认为这很难做到,而这通常是一个坏主意。
  • 如果您继续在站点上使用Windows身份验证,则在用户从Intranet登录时会遇到问题。关于Kerberos(Active Directory使用Kerberos)的有趣事情是,它允许用户访问远程资源而无需重新验证身份……但是这个用户身份令牌只适用于1次跳转。虽然您的WCF和MVC服务在同一台服务器上,它们将工作,但如果您最终将WCF服务移走……那就是第三个框架边界……第三次跳转,Kerberos票证将无法满足要求。
所以……由于不了解您的要求,我首先建议您:
  • 忘记在WCF层进行身份验证
  • 使您的WCF服务访问私有(发挥您的网络技能……防火墙等)。我会从在不监听端口80(或443)的单独IIS Web站点上运行WCF开始,并确保防火墙阻止来自LAN外部(甚至更好,白名单(现在仅限本地主机))的IP对新WCF端口的访问。
  • 将用户身份指定为每个WCF调用的参数。或者如果您感到疯狂,请探索通过SOAP头指定用户身份的方法(如果您的WCF使用SOAP)。一个自定义头也应该可以胜任。然后,您将信任您的Web站点在授权用户访问WCF服务之前正确挑战和验证用户身份。
我已经看到这种情况发生了很多次。在私有服务上没有身份验证是一个很好的性能交易,但您需要采取预防措施,因为一般来说,大多数IT攻击来自内部LAN。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接