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

vts*_*vts 24 c# asp.net wcf soap web-services

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

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

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

<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>
Run Code Online (Sandbox Code Playgroud)

Ser*_*gey 59

上面的答案是错的!不要添加自定义标头.从您的示例x​​ml判断,它是标准的WS-Security标头.WCF绝对支持开箱即用.添加服务引用时,应在配置文件中为您创建basicHttpBinding绑定.您必须修改它以包含具有TransportWithMessageCredential模式的security元素和包含clientCredentialType = UserName的message元素:

<basicHttpBinding>
  <binding name="usernameHttps">
    <security mode="TransportWithMessageCredential">
      <message clientCredentialType="UserName"/>
    </security>
  </binding>
</basicHttpBinding>
Run Code Online (Sandbox Code Playgroud)

上面的配置告诉WCF通过HTTPS在SOAP头中期望用户ID /密码.然后,您可以在拨打电话之前在代码中设置ID /密码:

var service = new MyServiceClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";
Run Code Online (Sandbox Code Playgroud)

除非此特定服务提供商偏离标准,否则它应该有效.

  • 啊哈,看起来它不喜欢WCF添加的额外标签.用自定义绑定替换基本绑定,并更改端点以引用它,它可以防止WCF添加Timestamp标记并允许接收不安全的错误.<customBinding> <binding name ="secureCustom"> <security authenticationMode ="UserNameOverTransport"enableUnsecuredResponse ="true"includeTimestamp ="false"> </ security> <textMessageEncoding messageVersion ="Soap11"> </ textMessageEncoding> <httpsTransport> </ httpsTransport> </ binding> </ customBinding> (5认同)

Tho*_*rin 38

可能有一种更聪明的方法,但您可以手动添加标题,如下所示:

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());
}
Run Code Online (Sandbox Code Playgroud)

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

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; }
}
Run Code Online (Sandbox Code Playgroud)

我没有NonceUsernameTokenXML中添加这个位,但它与那个非常相似Password.该Created元素还需要添加,但这很简单[XmlElement].