如何在WCF 4.0 RESTful服务中使用基本身份验证传递比用户名/密码更多的数据到服务方法?

10

要求:

WCF 4.0 IIS 主机 基本认证与自定义来源 RESTful

有很多例子和方法可以实现基本认证,从使用 UserNamePasswordValidator,到 ServiceAuthorizationManagerIDispatchMessageInspector 等等。

我面临的问题是,验证实际上将从身份验证后端获取比是/否答案更多的信息。而我想以某种方式将此信息传递给被调用的服务方法(即它将是完整的 User 对象,具有许多属性来控制服务行为)。我想避免根据用户名从用户存储库检索数据的第二个调用,因为我可以从安全上下文中访问它。

到目前为止,我找到的最接近的解决方案是 this solution,它使用了 WCF REST Starter Kit 的 RequestInterceptor,在其中我可以注入 ServiceSecurityContext 的子类来携带我的数据,并在服务方法中将 ServiceSecurityContext.Current 转换回来。

以上的问题在于,它是针对 WCF 3.5 编写的,而我想避免使用 Starter Kit。

问题:您有没有任何想法,在哪里挂接链条是最合适的地方,以便我可以从验证逻辑传递数据到服务。换句话说,我在哪里能够使用我的自定义安全上下文来替换它以继续负载?或者任何其他承载机制?
我要的行为是:
客户端(可以是浏览器)尝试使用服务:GET https://myservcer/service/data 服务器响应“需要基本身份验证” 客户端提供基本身份验证标头并再次发送请求 服务器根据标头中的用户名/密码从数据库中拉出一个用户对象。 如果找不到用户,请重新请求认证 如果找到用户,则将User对象传递给服务方法 所有这些都应该发生而不会使第二次往返到数据库。
到目前为止,我了解到的是,UserNamePasswordValidator不会做到这一点 - 如果我在那里检索用户对象,没有办法传递用户对象。
我可以创建自定义IAuthorizationPolicy或SecurityToken(哪一个),并将User对象放入其中。 但是...这应该发生在哪里。 我可以用UserNameSecurityTokenAuthenticator吗? 它会返回正确的HTTP错误代码以要求凭据吗? 我在哪里修改web.config以使用我的自定义内容? 到目前为止,我只看到如何设置仅使用自定义UserNamePasswordAuthenticator。

编辑:请查看我的回答了解我的方法。尽管如此,问题很好,我得到的答案很有价值。

3个回答

4
我们实现了自己的身份验证HTTP模块。该模块挂钩到HttpApplication的“on request authenticate”事件,并针对后端运行身份验证。后端可以返回任何想要的内容(在我们的情况下,返回的内容不仅仅是是/否)。返回的对象实现了System.Security.Principal.IIdentity接口。一旦身份验证成功,我们将身份(由auth返回的对象)附加到HttpContext.User中携带的主体上。
通过管道,您可以在任何时候访问当前上下文的用户并获取所有标识信息。
这种方法的唯一显著缺点是它需要ASP.net兼容性,但如果您已经以这种方式运行您的Rest服务,则不应该有问题。

谢谢。我正在研究类似的方法 - 我看的模块是:http://www.codeproject.com/KB/aspnet/mybasicauthentication.aspx。同一个人还展示了如何在下一步中钩取:http://www.leastprivilege.com/HTTPBasicAuthenticationAgainstNonWindowsAccountsInIISASPNETPart3AddingWCFSupport.aspx。你有没有经历过类似的事情,或者你找到了一些从上下文中获取身份的捷径? - Sunny Milenov
这与链接中展示的方式有些不同。我们希望 1)使认证部分可进行单元测试,因此必须删除所有对 HttpContext.Current 的依赖;2)允许业务逻辑提供身份而不是HttpContext.Current,因为相同的 BL 可以从其他地方调用。为此,我们创建了 IdentityFactories,在 WS 下运行时注入查看 HttpContext 的工厂。这有意义吗?我可以稍后编辑答案并提供更多细节。现在我很忙,希望这有所帮助。 - ale
这很有道理。我的问题是,你是否已经在这些确切的地方进行了拦截,就像它们所显示的那样,还是找到了更合适的方法。否则,你对工厂的看法是正确的。 - Sunny Milenov
1
该模块在AuthenticateRequest处进行拦截(类似于CodeProject链接),并传递给我们定制的认证器。因此,在这个意义上,它是相似的。我们的方法对我们来说效果很好。如果您想到了不同的方法,我很想听听您是如何做到的。祝你好运! - ale

0

最终我并没有使用WCF。Nancy更容易创建和测试RESTful API,并且随着最新更改(将在0.8版本中发布),我所询问的问题变得非常简单。


0

我已经阅读了所有这些文章,一直在反复阅读,但似乎每个人最终都会感到困惑,并且通常决定采取其他方式。我将编辑我的问题并提供更多细节,但仍然没有解决我的问题的方法。 - Sunny Milenov

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