Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用自定义ClientCredentials的WCF身份验证:要使用的clientCredentialType是什么?_C#_Wcf_Web Services_Authentication_Token - Fatal编程技术网

C# 使用自定义ClientCredentials的WCF身份验证:要使用的clientCredentialType是什么?

C# 使用自定义ClientCredentials的WCF身份验证:要使用的clientCredentialType是什么?,c#,wcf,web-services,authentication,token,C#,Wcf,Web Services,Authentication,Token,我不得不放弃基本的WCF用户名/Pwd安全性,实现我自己的自定义客户端凭据,以保存默认情况下提供的更多信息 我努力了,但我错过了一些东西,因为它不起作用 首先,我有一些自定义ClientCredentials,它们提供了自定义ClientCredentialsSecurityTokenManager: public class CentralAuthCredentials : ClientCredentials { public override System.IdentityModel

我不得不放弃基本的WCF用户名/Pwd安全性,实现我自己的自定义客户端凭据,以保存默认情况下提供的更多信息

我努力了,但我错过了一些东西,因为它不起作用

首先,我有一些自定义ClientCredentials,它们提供了自定义ClientCredentialsSecurityTokenManager:

public class CentralAuthCredentials : ClientCredentials
{
    public override System.IdentityModel.Selectors.SecurityTokenManager CreateSecurityTokenManager()
    {
        return new CentralAuthTokenManager(this);
    }
}

public class CentralAuthTokenManager : ClientCredentialsSecurityTokenManager
{
    private CentralAuthCredentials credentials;

    public CentralAuthTokenManager(CentralAuthCredentials creds) : base(creds)
    {
        this.credentials = creds;
    }

    public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
    {
        if (this.IsIssuedSecurityTokenRequirement(tokenRequirement) || tokenRequirement.TokenType == CentralAuthToken.TOKEN_TYPE)
            return new CentralAuthTokenProvider(credentials.UserId, credentials.UserPassword, credentials.ImpersonateId, credentials.LoginType);
        else
            return base.CreateSecurityTokenProvider(tokenRequirement);
    }

    public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver)
    {
        outOfBandTokenResolver = null;
        if (this.IsIssuedSecurityTokenRequirement(tokenRequirement) || tokenRequirement.TokenType == CentralAuthToken.TOKEN_TYPE)
            return new CentralAuthTokenAuthenticator();
        else
            return base.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver);
    }

    public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
    {
        return new CentralAuthTokenSerializer();
    }
}
现在,当我运行应用程序时,我的自定义凭据和令牌管理器会被创建。 然而,在方法中:

CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
    ...
}
public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
    return new CentralAuthTokenSerializer();
}
tokenRequirement.TokenType显示为我的自定义标记以外的内容。这就引出了我的第一个问题:WCF是如何知道令牌要求的

此外,该方法:

CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
{
    ...
}
public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
    return new CentralAuthTokenSerializer();
}
不会被客户端调用一次,但不会调用返回的令牌序列化程序上的任何方法。这向我表明,自定义令牌从未通过网络发送。我假设这是因为对CreateSecurityTokenProvider()的调用从未返回我的自定义令牌提供程序,因为从未传入SecurityTokenRequirement,表明需要我的自定义令牌

在客户方面,我有:

public class CentralAuthorizationManagerClient : ClientBase<ICentralAuthorizationManager>, ICentralAuthorizationManager, IDisposable
{
    public PFPrincipal GenerateToken()
    {
        if (!this.ChannelFactory.Endpoint.Behaviors.Contains(typeof(CentralAuthCredentials)))
            throw new ArgumentException("Must set CentralAuthCredentials before calling this method.");
        return base.Channel.GenerateToken();
    }

    public PFPrincipal GenerateToken(CentralAuthToken token)
    {
        this.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
        this.ChannelFactory.Endpoint.Behaviors.Add(new CentralAuthCredentials(token));
        return this.GenerateToken();
    }
看起来WCF正在使用一些默认的令牌管理器来尝试处理我的自定义令牌,而不是我的自定义令牌处理程序(从未调用我的自定义令牌处理程序的构造函数)。我认为这是因为对于客户端,我有以下配置:

<endpointBehaviors>
    <behavior name="Server2ServerEndpointBehavior">
        <clientCredentials type="MyApp.Security.CentralAuthCredentials, MyApp">

但是在服务器上,我没有任何等价物让它知道自定义客户端凭据。因此,新问题:在服务器的配置中,我应该告诉它自定义客户端凭据是什么


更新#2:

好吧,我终于猜出了更多的谜题。我只实现了一个ClientCredentials实现,认为客户端发送creds,就是这样。客户端不验证服务,因此我不需要自定义ServiceCredentials。嗯,我错了。指定的ServiceCredentials从ClientCredentials验证令牌,反之亦然。因此,我只需添加一个自定义ServiceCredentials实现,该实现传递相同的令牌序列化程序和令牌身份验证程序类


关于下一个问题:WCF现在将忽略我在配置中指定的x509证书,这些证书与UserName auth正常工作。我要为这个问题提出一个全新的问题

我正在开发的一个应用程序遇到了类似的问题,不幸的是我放弃了,因为我无法让自定义凭据正常工作。我现在使用用户名/密码(客户端凭据)和证书(服务凭据),并将自定义加密的soap头添加到服务调用中,以传递其他信息,例如用户ID等。

Ok,所以这个问题读起来几乎和我最近两天的问题一模一样!
<endpointBehaviors>
    <behavior name="Server2ServerEndpointBehavior">
        <clientCredentials type="MyApp.Security.CentralAuthCredentials, MyApp">