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

查看:118
本文介绍了无法对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);

我尝试了一些不同的方法,但要么获得了未授权,要么得到了以下变体:The value 'TransportWithMessageCredential' is not supported in this context for the binding security property 'securityMode'..

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天全站免登陆