c# - 无法将类型 'System.Security.Cryptography.DSACryptoServiceProvider' 的对象强制转换为类型 'System.Security.Cryptography.RSA'

标签 c# .net web-services token saml

我正在尝试通过本文之后的证书身份验证来获取 saml token How to pass a certificate to WSTrust to get Saml Token

当我调用这样的电话时,我收到以下错误

var token = factory.CreateChannel().Issue(rst) as GenericXmlSecurityToken;

Unable to cast object of type 'System.Security.Cryptography.DSACryptoServiceProvider' to type 'System.Security.Cryptography.RSA'

我尝试了本文中提到的 cryptoconfig 解决方案 https://dusted.codes/how-to-use-rsa-in-dotnet-rsacryptoserviceprovider-vs-rsacng-and-good-practise-patterns

并没有解决问题

这是完整的堆栈跟踪

Server stack trace: 
 at System.Security.Cryptography.RSAPKCS1SignatureFormatter.SetKey(AsymmetricAlgorithm key)
at System.Security.Cryptography.SignatureDescription.CreateFormatter(AsymmetricAlgorithm key)
at System.Security.Cryptography.RSAPKCS1SignatureDescription.CreateFormatter(AsymmetricAlgorithm key)
at System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm)
at System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey)
at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CompletePrimarySignatureCore(SendSecurityHeaderElement[] signatureConfirmations, SecurityToken[] signedEndorsingTokens, SecurityToken[] signedTokens, SendSecurityHeaderElement[] basicTokens, Boolean isPrimarySignature)
at System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CreateSupportingSignature(SecurityToken token, SecurityKeyIdentifier identifier)
at System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingToken(SecurityToken token, SecurityKeyIdentifierClause identifierClause)
at System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingTokens()
at System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication()
at System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
at System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.Security.IWSTrustContract.Issue(Message message)
at System.ServiceModel.Security.WSTrustChannel.Issue(RequestSecurityToken rst, RequestSecurityTokenResponse& rstr)
at System.ServiceModel.Security.WSTrustChannel.Issue(RequestSecurityToken rst)
at TestClient.Program.GetSamlToken() 

这是代码

private static string GetSamlToken()
    {
        "Requesting identity token".ConsoleYellow();
        var stsBinding = new WS2007HttpBinding();
        stsBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;
        stsBinding.Security.Message.EstablishSecurityContext = false;
        stsBinding.Security.Message.NegotiateServiceCredential = false;
        stsBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; 

        var factory = new WSTrustChannelFactory(
           stsBinding,
           "https://sometestservice.com/service");
        factory.TrustVersion = TrustVersion.WSTrust13;
        factory.Credentials.ClientCertificate.SetCertificate(System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine, System.Security.Cryptography.X509Certificates.StoreName.My,
            System.Security.Cryptography.X509Certificates.X509FindType.FindByThumbprint, "<cert_thumbprint_removed>");


        var rst = new RequestSecurityToken
        {
            RequestType = RequestTypes.Issue,
            KeyType = KeyTypes.Bearer,
            TokenType = TokenTypes.Saml2TokenProfile11,
            AppliesTo = new EndpointReference("urn:webapisecurity")
        };

        var token = factory.CreateChannel().Issue(rst) as GenericXmlSecurityToken;
        return token.TokenXml.OuterXml;
    }

我错过了什么?

最佳答案

只是为了显示核心库中遗留假设的数量。看来您必须创建自己的 X509AmetrySecurityKeyX509SecurityTokenSecurityTokenProviderClientCredentialsSecurityTokenManager 扩展,如 How to: Change the Cryptographic Provider for an X.509 Certificate's Private Key 中所述。

关于c# - 无法将类型 'System.Security.Cryptography.DSACryptoServiceProvider' 的对象强制转换为类型 'System.Security.Cryptography.RSA',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50244875/

相关文章:

c# - 处理方法中的已知错误和错误消息

c# - 为特定打印机创建任何文件格式的 .PRN 文件的程序/算法!请帮忙!

.net - 如何使用 GetBytes(string) 检查是否存在将转换为 "?"的字符

c# - 验证十进制数据类型时出错

c# - 如果快速单击多次,则 ChildWindow 关闭按钮事件处理程序会执行多次

java - 使用 JAX-WS 声明 Web 方法中未使用的类型

iphone - 如何在 iPhone 中使用异步 Web 服务调用自动完成 TextField?

c# - 需要显示使用 web 服务/jquery 返回的数据

c# - EF Core 2.1 中的动态数据播种迁移生成取决于在 OnModelCreating() 中使用的 DbContext bool-flag

c# - 使用 C# 在 vi​​sio 中创建形状