首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将标头中的用户名/密码传递给SOAP WCF服务

如何将标头中的用户名/密码传递给SOAP WCF服务
EN

Stack Overflow用户
提问于 2013-04-16 10:54:58
回答 8查看 124.9K关注 0票数 28

我正在尝试使用第三方web服务https://staging.identitymanagement.lexisnexis.com/identity-proofing/services/identityProofingServiceWS/v2?wsdl

我已经将其添加为服务引用,但我不确定如何传递头部的凭据。

如何使header请求与此格式匹配?

代码语言:javascript
复制
<soapenv:Header>
    <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken wsu:Id="UsernameToken-49" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:Username>12345/userID</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/ oasis-200401-wss-username-token-profile-1.0#PasswordText">password123</wsse:Password>
            <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">d+VxCZX1cH/ieMkKEr/ofA==</wsse:Nonce>
            <wsu:Created>2012-08-04T20:25:04.038Z</wsu:Created>
        </wsse:UsernameToken>
    </wsse:Security>
</soapenv:Header>
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2013-04-16 15:45:55

可能有一种更聪明的方法,但您可以像这样手动添加标头:

代码语言:javascript
复制
var client = new IdentityProofingService.IdentityProofingWSClient();

using (new OperationContextScope(client.InnerChannel))
{
    OperationContext.Current.OutgoingMessageHeaders.Add(
        new SecurityHeader("UsernameToken-49", "12345/userID", "password123"));
    client.invokeIdentityService(new IdentityProofingRequest());
}

这里,SecurityHeader是一个自定义实现的类,它需要一些其他类,因为我选择使用属性来配置XML序列化:

代码语言:javascript
复制
public class SecurityHeader : MessageHeader
{
    private readonly UsernameToken _usernameToken;

    public SecurityHeader(string id, string username, string password)
    {
        _usernameToken = new UsernameToken(id, username, password);
    }

    public override string Name
    {
        get { return "Security"; }
    }

    public override string Namespace
    {
        get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
    }

    protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
        serializer.Serialize(writer, _usernameToken);
    }
}


[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
    public UsernameToken()
    {
    }

    public UsernameToken(string id, string username, string password)
    {
        Id = id;
        Username = username;
        Password = new Password() {Value = password};
    }

    [XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
    public string Id { get; set; }

    [XmlElement]
    public string Username { get; set; }

    [XmlElement]
    public Password Password { get; set; }
}

public class Password
{
    public Password()
    {
        Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
    }

    [XmlAttribute]
    public string Type { get; set; }

    [XmlText]
    public string Value { get; set; }
}

我没有向UsernameToken XML添加Nonce位,但它与Password非常相似。还需要添加Created元素,但它是一个简单的[XmlElement]

票数 41
EN

Stack Overflow用户

发布于 2013-04-17 11:24:49

上面的答案大错特错!请勿添加自定义标头。从您的示例xml判断,它是一个标准的WS-Security标头。WCF绝对支持它的开箱即用。在添加服务引用时,应该在配置文件中为您创建basicHttpBinding绑定。您必须对其进行修改,以包含模式为TransportWithMessageCredential的安全元素和clientCredentialType =UserName的消息元素:

代码语言:javascript
复制
<basicHttpBinding>
  <binding name="usernameHttps">
    <security mode="TransportWithMessageCredential">
      <message clientCredentialType="UserName"/>
    </security>
  </binding>
</basicHttpBinding>

上面的配置告诉WCF在HTTPS上的SOAP头中需要userid/password。然后,您可以在进行调用之前在代码中设置id/password:

代码语言:javascript
复制
var service = new MyServiceClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";

除非这个特定的服务提供商偏离了标准,否则它应该是有效的。

票数 64
EN

Stack Overflow用户

发布于 2015-06-30 22:19:36

添加一个自定义的硬编码头可能会起作用(有时也可能会被拒绝),但这是完全错误的方法。WSSE的目的是安全性。正是由于这个原因,微软发布了Microsoft Web Services Enhancements 2.0,随后又发布了WSE 3.0。您需要安装此软件包(http://www.microsoft.com/en-us/download/details.aspx?id=14089)。

文档并不容易理解,特别是对于那些没有使用过SOAP和WS-Addressing的人。首先,"BasicHttpBinding“是SOAP1.1,它不会为您提供与WSHttpBinding相同的消息头。安装该程序包并查看示例。您需要引用WSE 3.0中的DLL,并且还需要正确设置您的消息。WS Addressing header上有大量的数据或变体。您要查找的是UsernameToken配置。

这是一个较长的解释,我应该为每个人写一些东西,因为我在任何地方都找不到正确的答案。您至少需要从WSE 3.0包开始。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16028014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档