C# 如何将WCF用户名clientCredentialType传递给其他服务?

C# 如何将WCF用户名clientCredentialType传递给其他服务?,c#,wcf,web-services,security,C#,Wcf,Web Services,Security,我在IIS6中托管了多个WCF服务,不应影响同一主机上的此问题,出于性能/维护和其他原因,我希望使用Facade服务将多个请求合并为一个请求, 所有这些都是通过特殊服务合同/服务完成的,该服务具有一个调用其他服务进行多个操作的操作 在不久的将来,我将使用WSHTTP-BasicHttp和消息安全性以及用户名客户端凭据类型 我希望Facade服务使用来自客户端的凭据。这意味着对后端服务的调用将获得凭据,就像客户端将直接调用它一样 例如: 客户端使用用户名A和密码B调用FacadeService.C

我在IIS6中托管了多个WCF服务,不应影响同一主机上的此问题,出于性能/维护和其他原因,我希望使用Facade服务将多个请求合并为一个请求, 所有这些都是通过特殊服务合同/服务完成的,该服务具有一个调用其他服务进行多个操作的操作

在不久的将来,我将使用WSHTTP-BasicHttp和消息安全性以及用户名客户端凭据类型

我希望Facade服务使用来自客户端的凭据。这意味着对后端服务的调用将获得凭据,就像客户端将直接调用它一样

例如: 客户端使用用户名A和密码B调用FacadeService.CompositeOperation。 现在FacadeService.CompositeOperation需要调用BackEndService.BackendOperation,将Credentials.UserName.UserName设置为A,将Credentials.UserName.Password设置为B,就像客户端调用此操作时所做的一样。我没有办法在WCF中提取这些信息,这应该是,因为它是敏感信息,但我也没有找到一种方法来获取这些信息的令牌并将其转发给后端服务。我不需要知道FacadeService中的这些信息,只需要将它们传递给后端服务即可

在FacadeService中,与在BackEndService中一样,身份验证是通过ASP.NET提供程序进行的,授权是一种自定义的基于角色的授权,使用PrimaryIdentity中的用户名,因此BackEndService上的PrimaryIdentity应设置为客户端发送的内容


我该怎么做呢?

我昨天读了你的帖子,但不确定答案,但鉴于你没有回复,我想我应该补充一些东西,或许可以提供一些思考的素材

首先,拨打附加服务电话是否会过度占用资源?如果不是,那么就有一个理由要求代码清晰,将它们分开,以便将来开发人员能够准确地知道发生了什么,而不是一个服务调用执行多个操作

您是否无法从正在使用的方法中的服务器端代码调用其他服务?与以前一样,您是服务器端,安全上下文应该保存您所关注的用户的身份,以便对其他服务的调用将使用相同的身份

最后,我想知道WCF模拟是否可以在服务器上使用,以实现您的目标。我自己也没用过,所以我没法提出我想要的建议


希望这能有所帮助-祝你好运

有一次我试图将密码和用户名一起存储在PrimaryIdentity中。 为了实现这一点,我们需要做的是提供一个新的UserNameSecurityTokenAuthenticator,它将验证用户名和密码,然后可以存储在标识中,然后将标识存储在WCF的SecurityContext中

步骤

班级

一,。TestServiceHost:ServiceHost

二,。UserNamePasswordSecurityTokenManager:ServiceCredentialsSecurityTokenManager

public override SecurityTokenManager CreateSecurityTokenManager()
{
    return new UserNamePasswordSecurityTokenManager(this);
}
三,。TestUserNameSecurityTokenAuthenticator:UserNameSecurityTokenAuthenticator

public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
            {
                outOfBandTokenResolver = null;
                return new TestUserNameSecurityTokenAuthenticator();
            }
            return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
        }
四,。我的身份:身份

五,。我的授权政策:授权政策

一,。创建新的ServiceHost类TestServiceHost

二,。在TestServiceHost中,重写OnOpen并提供新的类UserNamePasswordServiceCredentials

protected override void OnOpening()
{
    base.OnOpening();
    this.Description.Behaviors.Add(new UserNamePasswordServiceCredentials());
}
三,。然后在UserNamePasswordServiceCredentials中,提供新的UserNamePasswordSecurityTokenManager

public override SecurityTokenManager CreateSecurityTokenManager()
{
    return new UserNamePasswordSecurityTokenManager(this);
}
四,。然后在UserNamePasswordSecurityTokenManager中提供新的TestUserNameSecurityTokenAuthenticator

public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
        {
            if (tokenRequirement.TokenType == SecurityTokenTypes.UserName)
            {
                outOfBandTokenResolver = null;
                return new TestUserNameSecurityTokenAuthenticator();
            }
            return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
        }
五,。然后在TestUserNameSecurityTokenAuthenticator中,您可以验证用户名和密码,并创建自己的身份。在此函数中,您将返回要评估的IAuthorization策略列表。我创建了自己的授权策略,并将新标识传递给它,以便在上下文中设置标识

protected override System.Collections.ObjectModel.ReadOnlyCollection<System.IdentityModel.Policy.IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password)
        {           
            ClaimSet claimSet = new DefaultClaimSet(ClaimSet.System, new Claim(ClaimTypes.Name, userName, Rights.PossessProperty));
            List<IIdentity> identities = new List<IIdentity>(1);
            identities.Add(new MyIdentity(userName,password));
            List<IAuthorizationPolicy> policies = new List<IAuthorizationPolicy>(1);
            policies.Add(new MyAuthorizationPolicy(ClaimSet.System, identities));
            return policies.AsReadOnly();
        }


public class MyAuthorizationPolicy : IAuthorizationPolicy
    {
        String id = Guid.NewGuid().ToString();
        ClaimSet issuer;
        private IList<IIdentity> identities;
        #region IAuthorizationPolicy Members


        public MyAuthorizationPolicy(ClaimSet issuer, IList<IIdentity> identities)
        {
            if (issuer == null)
                throw new ArgumentNullException("issuer");
            this.issuer = issuer;
            this.identities = identities;

        }

        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            if (this.identities != null)
            {
                object value;
                IList<IIdentity> contextIdentities;
                if (!evaluationContext.Properties.TryGetValue("Identities", out value))
                {
                    contextIdentities = new List<IIdentity>(this.identities.Count);
                    evaluationContext.Properties.Add("Identities", contextIdentities);
                }
                else
                {
                    contextIdentities = value as IList<IIdentity>;
                }
                foreach (IIdentity identity in this.identities)
                {
                    contextIdentities.Add(identity);
                }
            }
            return true;
        }

        public ClaimSet Issuer
        {
            get { return this.issuer; }
        }

        #endregion

        #region IAuthorizationComponent Members

        public string Id
        {
            get { return this.id; }
        }

        #endregion
    }
因此,此示例显示了如何覆盖WCF中的安全性:

现在你的问题是:

一,。实施此技术并在您的身份中设置用户名和密码。现在,当您调用子服务时,从中获取标识提取用户名和密码并传递给子服务

二,。验证用户名和密码,并为其生成令牌,该令牌应为此创建新的令牌服务。将此令牌与用户名一起保存在您的身份中,并将这两个令牌传递给您的子服务。现在,为了让这种方法发挥作用,子服务必须验证您新生成的令牌,为此您应该有一个令牌服务,它可以通过验证用户名和密码来创建令牌,还可以验证令牌和用户名


就我个人而言,我会选择方法2,但它会带来新的管理费用。

您好,谢谢您的回复。1.目前没有性能问题,但将来我会对它进行测试,如果我将其更改为使用TCP/IPC绑定的话。至于代码的清晰性,有 完全没有问题,因为这个门面服务就是为这个目的而设计和制造的。2.这是不可能的,因为我使用用户名凭据,并且需要用户名/密码。3.模拟仅适用于Windows,我需要用户名/密码凭据类型。谢谢