当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《使用自定义ClientCredentials的WCF身份验证:要使用的clientCredentialType是什么?》经验,为你挑选了0个好方法。

我不得不放弃基本的WCF UserName/Pwd安全性并实现我自己的自定义客户端凭据,以保存超出默认提供的更多信息.

我参与了这篇MSDN文章,但我遗漏了一些东西,因为它不起作用.

首先,我有一些自定义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)
{
    ...
}

tokenRequirement.TokenType与我的自定义令牌不同.这提出了我的第一个问题:WCF如何知道令牌要求是什么?

另外,方法:

public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version)
{
    return new CentralAuthTokenSerializer();
}

是否由客户端调用一次,但是返回的令牌序列化程序中的所有方法都不会被调用.这向我表明,自定义令牌永远不会通过网络发送.我假设这是因为对CreateSecurityTokenProvider()的调用从未返回我的自定义令牌提供程序,因为从未传递SecurityTokenRequirement指示我需要自定义令牌.

在客户端,我有:

public class CentralAuthorizationManagerClient : ClientBase, 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();
        this.ChannelFactory.Endpoint.Behaviors.Add(new CentralAuthCredentials(token));
        return this.GenerateToken();
    }

这些方法基本上应该从端点中删除默认凭据并附加我的自定义CentralAuthCredentials的新实例.(我从某处的MSDN文章中抓取了这个删除/添加组合).

在配置中:

    
        
            
                
                    
                    
                        
                    
                
            
        
    

    
        
            
                
                    
                
            
        
    

请注意,行为的clientCredentials类型设置为我的自定义客户端凭据.但是,目前我仍然将绑定的clientCredentialType设置为"UserName".这提出了我的第二个问题:clientCredentialType ="是什么?" 如果我使用自定义凭据,请设置为?根据MSDN,Message安全性的可用值包括:None,Windows,UserName,CertificateIssuedToken.

有任何想法吗?希望我只是缺少一些简单的东西?整个实现还有6个类,但我试图只包括了解情况所需的位数...


更新#1:

我一整天都在努力,感谢一些消息来源,我意识到我遗漏的部分是这个页面的最后一步,即将TokenParameters添加到绑定中,以便绑定知道什么令牌看起来像.这是我原来的第一个问题的答案; "什么设置了令牌要求?" 答案:分配给绑定的TokenParameters.

所以现在我添加了以下扩展,它在绑定上设置了TokenParameters:

public sealed class CentralAuthTokenBindingExtension : BindingElementExtensionElement
{
    public CentralAuthTokenBindingExtension()
        : base()
    {
    }

    public override Type BindingElementType
    {
        get { return typeof(SymmetricSecurityBindingElement); }
    }

    protected override System.ServiceModel.Channels.BindingElement CreateBindingElement()
    {
        X509SecurityTokenParameters protectionParams = new X509SecurityTokenParameters();
        protectionParams.InclusionMode = SecurityTokenInclusionMode.Never;

        SymmetricSecurityBindingElement innerBindingElement = new SymmetricSecurityBindingElement();
        innerBindingElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(new CentralAuthTokenParameters());
        //innerBindingElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
        innerBindingElement.ProtectionTokenParameters = protectionParams;

        return innerBindingElement;
    }
}

    
        
            
        
    

    
        
            
                
                
                
            
        
    

那让我更进一步.现在我在服务器上得到一个新的异常:

"The security token manager cannot create a token authenticator for requirement ..."

看起来WCF正在使用一些默认令牌管理器来尝试处理我的自定义令牌,而不是我的自定义令牌处理程序(从不调用我的自定义令牌处理程序的构造函数).我认为这是发生的,因为对于客户端,我有这个配置:


    
        

但是在服务器上,我没有任何等同于让它知道自定义客户端凭据.所以,新问题:在服务器的配置中,我告诉它自定义ClientCredentials是什么?


更新#2:

好吧,我终于想出了更多的谜题.我只实现了ClientCredentials实现,认为客户端发送了信用证,就是这样.客户端不会对服务进行身份验证,因此我不需要自定义ServiceCredentials.好吧,我错了.指定的ServiceCredentials从ClientCredentials验证令牌,反之亦然.所以我只需要添加一个自定义的ServiceCredentials实现,该实现传递相同的TokenSerializer和TokenAuthenticator类.

转到下一个问题:WCF现在忽略我在配置中指定的x509证书,这些证书与UserName auth一起正常工作.我打算为这个开一个全新的问题!

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有