5

还没有看到很多与日内瓦相关的问题,我也在日内瓦论坛上发布了这个问题......

我正在处理一个场景,我们有一个具有广泛安装基础的 win forms 应用程序,它将在整个操作过程中对我们集中托管的各种服务发出频繁的调用。

这些服务都使用日内瓦框架,所有客户都应该首先调用我们的 STS 以获取令牌以允许访问服务。

开箱即用,使用 ws2007FederationHttpBinding,可以将应用程序配置为在每次服务调用之前从 STS 检索令牌,但显然这不是最有效的方式,因为我们几乎重复了调用服务的工作。

或者,我已经实现了从应用程序“手动”检索令牌所需的代码,然后在对服务调用操作时传递相同的预检索令牌(基于 WSTrustClient 示例和论坛上的帮助);效果很好,所以我们确实有一个解决方案,但我认为它不是很优雅,因为它需要在代码中构建 WCF 通道,远离美妙的 WCF 配置。

我更喜欢 ws2007FederationHttpBinding 方法,在这种方法中,客户端只需像任何其他 WCF 服务一样调用该服务,而无需了解有关日内瓦的任何信息,并且绑定负责令牌交换。

然后有人(乔恩辛普森)给了我 [我认为是] 一个好主意 - 添加一个服务,托管在应用程序本身中以缓存本地检索到的令牌。本地缓存服务将执行与 STS 相同的合约;当接收到请求时,它会检查是否存在缓存令牌,如果存在则返回它,否则它将调用“真实”STS,检索新令牌,缓存并返回它。客户端应用程序仍然可以使用 ws2007FederationHttpBinding,但不是将 STS 作为颁发者,而是使用本地缓存;

通过这种方式,我认为我们可以实现两全其美 - 在没有服务特定的自定义代码的情况下缓存令牌;我们的缓存应该能够处理所有 RP 的令牌。

我创建了一个非常简单的原型来看看它是否有效,并且 - 不幸的是有点不足为奇 - 我有点卡住了 -

我的本地服务(当前是控制台应用程序)获取请求,并且 - 第一次 - 调用 STS 以检索令牌,将其缓存并成功将其返回给客户端,随后客户端使用它来调用 RP。一切正常。

然而,第二次,我的本地 cahce 服务尝试再次使用相同的令牌,但客户端失败并出现 MessageSecurityException -

“安全处理器无法在消息中找到安全标头。这可能是因为消息是不安全的错误,或者是因为通信双方之间存在绑定不匹配。如果为安全配置了服务并且客户端是不使用安全性。”

是否有什么东西阻止了同一个令牌被多次使用?我对此表示怀疑,因为当我按照 WSTrustClient 示例重用令牌时,它运行良好;我错过了什么?我的想法可能吗?一个好?

这是本地缓存的(非常基本的,在这个阶段)主要代码位 -

    static LocalTokenCache.STS.Trust13IssueResponse  cachedResponse = null; 
    public LocalTokenCache.STS.Trust13IssueResponse Trust13Issue(LocalTokenCache.STS.Trust13IssueRequest request) 
    { 
        if (TokenCache.cachedResponse == null) 
        { 
            Console.WriteLine("cached token not found, calling STS"); 
            //create proxy for real STS 
            STS.WSTrust13SyncClient sts = new LocalTokenCache.STS.WSTrust13SyncClient(); 
            //set credentials for sts 
            sts.ClientCredentials.UserName.UserName = "Yossi"; 
            sts.ClientCredentials.UserName.Password = "p@ssw0rd"; 
            //call issue on real sts 
            STS.RequestSecurityTokenResponseCollectionType stsResponse = sts.Trust13Issue(request.RequestSecurityToken); 
            //create result object - this is a container type for the response returned and is what we need to return; 
            TokenCache.cachedResponse = new LocalTokenCache.STS.Trust13IssueResponse(); 
            //assign sts response to return value... 
            TokenCache.cachedResponse.RequestSecurityTokenResponseCollection = stsResponse; 
        } 
        else 
        { 
        } 
        //...and reutn 
        return TokenCache.cachedResponse;
4

2 回答 2

6

这几乎令人尴尬,但感谢论坛上的 Dominick Baier,我现在没有意识到我错过了一个重要的观点(我知道这没有意义!老实说!:-)) -

每个服务代理都会检索一次令牌,假设它没有过期,所以我需要做的就是重用相同的代理,我本来打算这样做,但相当愚蠢的是,我的原型上没有。

另外——我在 MSDN WCF 示例中发现了一个非常有趣的示例——Durable Issued Token Provider,如果我理解正确的话,它使用客户端的自定义端点行为来实现令牌缓存,非常优雅。

我仍然会研究这种方法,因为我们有多个服务,因此我们可以通过在它们的代理之间重用相同的令牌来实现更高的效率。

所以 - 两种解决方案,我的眼睛几乎不知道;希望我的愚蠢在某些时候对某人有所帮助!

于 2008-12-30T14:27:09.940 回答
1

我在这里提供了一个用于缓存令牌的完整示例:http: //blogs.technet.com/b/meamcs/archive/2011/11/20/caching-sts-security-token-with-an-active-web -client.aspx

于 2011-11-20T02:36:59.753 回答