使用 Windsor Castle 和 WcfFacility 创建具有 Message Security 和用户名凭据的 WCF 代理

发布于 2024-10-17 05:39:06 字数 2137 浏览 16 评论 0原文

好的,我们正在使用消息安全用户名凭据(以及 X509 证书加密)来与我们的 WCF 服务进行通信。我对这种方法不满意,但这不是问题的重点,我不想讨论这个问题。

我正在使用温莎城堡ASP NET Web Forms + MVC 混合中生成代理。我们正在使用表单身份验证并使用用户的凭据与 WCF 服务进行通信 - 这将有助于审核所有调用。正如我所说,我对这种方法不满意,但这不是重点。

我创建了继承 AbstractCredentials 类的 CustomCredentials 类,并且 WcfFacility 很乐意使用它来配置我的代理。正如您将在下面看到的,我的所有设置都只有几行。我在下面创建了单元测试,它演示了我正在做的所有事情:创建代理,进行调用,然后在循环中释放它。现在我期望这个测试能够工作,但它没有工作,我得到

Expected: 10 But was: 1

我没有包含绑定,但这无关紧要,正如我所说的,我正在将 Message Security 与 X509 证书一起使用。

我知道对于具有消息安全性的通道工厂,一旦打开就无法更改凭据。这是同一个问题吗?

这是 WcfFacility 中的错误还是限制?

这是代码

[TestFixture]
public class Harness
{

    private IWindsorContainer _container;
    public static int NumberOfTimesCredentialsConfigured = 0;

    [SetUp]
    public void Setup()
    {
        _container = new WindsorContainer().AddFacility<WcfFacility>();

    Component
        .For<IFrameworkUsers>()
        .ActAs(DefaultClientModel
        .On(WcfEndpoint.FromConfiguration("FrameworkUsersService"))
        .Credentials(new CustomCredentials()))
        .LifeStyle.Transient);
    }

    [Test]
    public void MultipleProxyTest()
    {

        const int Runs = 10;
        NumberOfTimesCredentialsConfigured = 0;
        for (int i = 0; i < Runs; i++)
        {
            IFrameworkUsers frameworkUsers = _container.Resolve<IFrameworkUsers>();
            frameworkUsers.CreateUserSession();
            _container.Release(frameworkUsers);
        }

        Assert.AreEqual(Runs, NumberOfTimesCredentialsConfigured);
                    // FAILS!!! Expected: 10  But was:  1
    }

    [TearDown]
    public void TearDown()
    {

    }


}

public class CustomCredentials : AbstractCredentials
{


    #region Overrides of AbstractCredentials

    protected override void ConfigureCredentials(ClientCredentials credentials)
    {
        credentials.UserName.UserName = "testuser";
        credentials.UserName.Password = "abcdef";

        Harness.NumberOfTimesCredentialsConfigured++;
    }

    #endregion
} 

OK we are using message security with username credentials (and X509 certificate encryption) to communicate with our WCF service. I am not happy with this approach but that is not the point of question and I do not want to get into that.

I am using Windsor Castle to generate proxies in ASP NET Web Forms + MVC hybrid. We are using forms authentication and use user's credentials to communicate with WCF services - this will help auditing all calls. As I said, I am not happy with this approach but that is not the point.

I have created CustomCredentials class which inherits AbstractCredentials class and WcfFacility happily uses it to configure my proxies. As you will see below, all my setup is just a few lines. I have created unit test below which demonstrates all I am doing: creating a proxy, making a call and then releasing it in a loop. Now I am expecting this test to work but it does not and I get

Expected: 10 But was: 1

I have not included binding but that is irrelevant, as I said I am using Message Security with X509 certificates.

I know that for channel factory with message security, once opened you cannot change credentials. Is this the same issue?

Is this a bug in WcfFacility or a limitation?

Here is the code

[TestFixture]
public class Harness
{

    private IWindsorContainer _container;
    public static int NumberOfTimesCredentialsConfigured = 0;

    [SetUp]
    public void Setup()
    {
        _container = new WindsorContainer().AddFacility<WcfFacility>();

    Component
        .For<IFrameworkUsers>()
        .ActAs(DefaultClientModel
        .On(WcfEndpoint.FromConfiguration("FrameworkUsersService"))
        .Credentials(new CustomCredentials()))
        .LifeStyle.Transient);
    }

    [Test]
    public void MultipleProxyTest()
    {

        const int Runs = 10;
        NumberOfTimesCredentialsConfigured = 0;
        for (int i = 0; i < Runs; i++)
        {
            IFrameworkUsers frameworkUsers = _container.Resolve<IFrameworkUsers>();
            frameworkUsers.CreateUserSession();
            _container.Release(frameworkUsers);
        }

        Assert.AreEqual(Runs, NumberOfTimesCredentialsConfigured);
                    // FAILS!!! Expected: 10  But was:  1
    }

    [TearDown]
    public void TearDown()
    {

    }


}

public class CustomCredentials : AbstractCredentials
{


    #region Overrides of AbstractCredentials

    protected override void ConfigureCredentials(ClientCredentials credentials)
    {
        credentials.UserName.UserName = "testuser";
        credentials.UserName.Password = "abcdef";

        Harness.NumberOfTimesCredentialsConfigured++;
    }

    #endregion
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

残疾 2024-10-24 05:39:06

我在城堡论坛发帖了,没有回复。这是 WCF 设施中设计的一个问题,它们在其中缓存服务通道,这些通道在没有安全性的情况下可以使用,但在安全性的情况下不起作用。

I posted on castle forum and no reply. It is a problem by design in WCF Facility in which they cache service channels which is OK with no security but does not work with security.

梦里梦着梦中梦 2024-10-24 05:39:06

通常,您的凭据和 IWcfEndpoint(这是 DefaultClientModel.On(...) 调用的结果)仅在配置容器时创建一次。如果您想每次提供不同的凭据 - 您需要使它们成为动态依赖项,如下所示:

_container.Register(Component.For<IFrameworkUsers>()
    .AsWcfClient()
    .DependsOn(
        (k, d) => d["endpoint"] = 
            new DefaultClientModel(WcfEndpoint.FromConfiguration("FrameworkUsersService"))
                .Credentials(new CustomCredentials())
     )
    .LifeStyle.Transient);

String endpoint 这里是 WcfFacility 使用的依赖项的名称。我不确定具体在哪里,但它在某些拦截器中得到了解决(您可以在 lambda 中设置断点并调试测试以查看调用堆栈)。我假设它是为了匹配 AsWcfClient(IWcfEndpoint endpoint) 方法参数的名称。

所以答案是否定的,这不是 WcfFacility 的错误或限制。

Your credentials and IWcfEndpoint in general (which is the result of DefaultClientModel.On(...) call) are created only once when the container is configured. If you want to provide different credentials each time - you need to make them dynamic dependency like below:

_container.Register(Component.For<IFrameworkUsers>()
    .AsWcfClient()
    .DependsOn(
        (k, d) => d["endpoint"] = 
            new DefaultClientModel(WcfEndpoint.FromConfiguration("FrameworkUsersService"))
                .Credentials(new CustomCredentials())
     )
    .LifeStyle.Transient);

String endpoint here is the name of dependency consumed by WcfFacility. I'm not sure where exactly, but it is resolved in some interceptor (you may set breakpoint in the lambda and debug your test to look at call stack). I assume it is made to match name of AsWcfClient(IWcfEndpoint endpoint) method argument.

So the answer is no, it is nor bug nor limitation of WcfFacility.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文