无法对 ASP.NET Core 中的 SOAP 服务进行身份验证 [英] Can't authenticate towards SOAP service in ASP.NET Core

查看:20
本文介绍了无法对 ASP.NET Core 中的 SOAP 服务进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用来自 ASP.NET Core 库项目的 SOAP Web 服务.

I'm trying to consume a SOAP web service from an ASP.NET Core Library project.

我已经安装了为我创建代理类的 Mictosoft WCF Web 服务参考提供程序,但我在身份验证方面遇到了问题.

I have installed the Mictosoft WCF Web Service Reference Provider that has created the proxy classes for me, but I have a problem with the authentication.

我的代码目前是这样的:

My code currently looks like this:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential);

var address = new EndpointAddress(@"https://myserviceaddress.asmx");
var client = new TestApiClient(binding, address);
client.ClientCredentials.UserName.UserName = "testusername";
client.ClientCredentials.UserName.Password = "testpassword";
var result = await client.GetDataAsync(params);

我尝试了一些不同的方法,但我要么得到未授权,要么得到以下变体:在绑定安全属性securityMode"的上下文中不支持值TransportWithMessageCredential"..

I have tried some different approaches, but I either get Unauthorized, or variants of this: The value 'TransportWithMessageCredential' is not supported in this context for the binding security property 'securityMode'..

我想我还应该在 binding.Security.Message 上设置一些属性,但是 binding.Security 上存在的唯一属性是 TransportMode.

I think I'm also supposed to set some properties on binding.Security.Message, but the only property that exist on binding.Security is Transport and Mode.

有人知道如何正确设置吗?

Anyone know how to set this up correctly?

是否有其他更好的方式来使用来自 ASP.NET Core 的 SOAP 服务?我喜欢一种不必创建代理类的动态方式,但如果必须的话,我可以使用代理,但我需要能够使用用户和密码进行身份验证,而且我必须使用 https.

Are there any other better ways of consuming the SOAP service from ASP.NET Core? I would love a dynamic way that don't have to create the proxy classes, but I can live with the proxies if I have to, but I need to be able to authenticate with a user and password, and I have to use https.

推荐答案

在同一个问题上挣扎了很多天后,由于 .Net 核心在此答案发布之前的支持非常有限,我设法通过构建整体解决了这个问题将自己包裹起来并使用 SimpleSoapClient.

After struggling many days with the same issue, because .Net core has a very limited support till date of this answer, I managed to solve it by building the whole envelope myself and using SimpleSoapClient.

我将尝试通过一个简单的示例逐步完成所有需要的步骤.因为每一步都有自己需要解决的问题.

I will try to go through all needed steps, step by step with a simple example. because each step has its own issues that needs to be solved.

让我们假设您的模型是一只猫.

Let us assume that your model is a Cat.

 public class Cat
    {
        public int Lives { get; set; }
    }

您的整个信封模型将如下所示:

Your entire envelop model will look like:

public class Envelope
{
    public EnvelopeHeader Header { get; set; }
    public EnvelopeBody Body { get; set; }
}
public class EnvelopeHeader
{
    [XmlElementAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
    public Security Security { get; set; }
}


[XmlTypeAttribute(AnonymousType = true, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
[XmlRootAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", IsNullable = false)]
public class Security
{
    public SecurityUsernameToken UsernameToken { get; set; }
}


[XmlTypeAttribute(AnonymousType = true, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public  class SecurityUsernameToken
{
    public string Username { get; set; }
    public SecurityUsernameTokenPassword Password { get; set; }
    [XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
    public string Id { get; set; }
}


[XmlTypeAttribute(AnonymousType = true, Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public  class SecurityUsernameTokenPassword
{
    [XmlAttributeAttribute()]
    public string Type { get; set; }
    [XmlTextAttribute()]
    public string Value { get; set; }
}

public  class EnvelopeBody
{
    public Cat Cat{ get; set; }
}

P.S:不要忘记在正文中需要的地方包含 XML 命名空间.

P.S: do not forget to include XML namespaces where needed in your body.

下一步是将您的 Envelop 模型序列化为 XML 字符串.

Next step is serializing your Envelop model into XML string.

string xml;
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
using (MemoryStream ms = new MemoryStream())
  {
    using (XmlWriter writer = XmlWriter.Create(ms, settings))
     {
       XmlSerializerNamespaces names = new XmlSerializerNamespaces();
       names.Add("", "");//add your needed namespaces here
       XmlSerializer cs = new XmlSerializer(typeof(Envelope));
       var myEnv = new Envelope()
        {
         Header = new EnvelopeHeader()
          {
           Security = new Security()
            {
              UsernameToken = new SecurityUsernameToken()
               {
                Username = "",
                Password = new SecurityUsernameTokenPassword()
                {
                 Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",//update type to match your case
                 Value = ""
                }
               }
              }
             },
             Body = new EnvelopeBody()
             {
              Cat = new Cat() { Lives = 7 }
             }
            };
            cs.Serialize(writer, myEnv, names);
            ms.Flush();
            ms.Seek(0, SeekOrigin.Begin);
            StreamReader sr = new StreamReader(ms);
            xml = sr.ReadToEnd();
          }
     }

最后使用以下方法发送您的 XML 信封:

Finally send your XML envelop using:

  SoapEnvelope responseEnvelope = null;
        using (var client = SoapClient.Prepare().WithHandler(new DelegatingSoapHandler()
        {
            OnHttpRequestAsyncAction = async (z, x, y) =>
            {
                x.Request.Content = new StringContent(xml , Encoding.UTF8, "text/xml");
            }
        }))
        {
                responseEnvelope = client.SendAsync("url", "action",SoapEnvelope.Prepare()).Result;
        }

请注意,您需要根据您的情况更新许多选项.我的情况是使用 WCF 的 WSSE 安全标头中的PasswordText"类型的密码.

Please note that you need to update many options according to your case. My case was password of type "PasswordText" in the WSSE Security Header with WCF.

这篇关于无法对 ASP.NET Core 中的 SOAP 服务进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆