在WCF SOAP API使用HTTP授权头认证 [英] Authentication using HTTP Authorization Header in WCF SOAP API

查看:253
本文介绍了在WCF SOAP API使用HTTP授权头认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们目前有一个WCF SOAP API,允许消费者使用一个用户名和密码进行身份验证(内部使用的 UserNamePasswordValidator )作为参考的用户名和密码,在SOAP体传递如下:

We currently have a WCF SOAP API that allows the consumer to authenticate using a username and password (internally uses a UserNamePasswordValidator) For reference the username and password is passed in the SOAP Body as follows:

<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" mustUnderstand="1">
<Timestamp Id="_0">
    <Created>
        2013-04-05T16:35:07.341Z</Created>
        <Expires>2013-04-05T16:40:07.341Z</Expires>
    </Timestamp>
    <o:UsernameToken Id="uuid-ac5ffd20-8137-4524-8ea9-3f4f55c0274c-12">
        <o:Username>someusername</o:Username>
        <o:Password o:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">somepassword
    </o:Password>
</o:UsernameToken>
</o:Security>

我们大家喜欢的此外支持用户在指定凭据< A HREF =http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.8相对=nofollow> HTTP授权头,因为无论是基本身份验证,或< A HREF =http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-15#section-2.1相对=nofollow> OAuth的承载令牌

We we like to additionally support a consumer to specify credentials in the HTTP Authorization header, as either Basic auth, or an OAuth Bearer token

我们已经有了实际做非SOAP的API认证几种方法,但我不熟悉如何告诉WCF使用我可能会为此创造任何类。我怎样才能做到这一点?我见过的唯一的其他问题,试图回答这个是这里,但接受答使用SOAP头,而不是HTTP头,和提问者基本上放弃了

We already have several ways of actually doing the authentication for non-SOAP APIs, but I am not familiar with how to tell WCF to use any class I might create for this. How can I accomplish this? The only other question I have seen that attempts to answer this is here, but the accepted answer uses SOAP headers, not HTTP headers, and the asker essentially gave up.

显然,任何解决方案需要向后兼容 - 我们需要继续支持消费者指定凭据。在SOAP安全标

Obviously any solution needs to be backwards compatible - we need to continue to support consumers specifying credentials in the SOAP Security Header.

推荐答案

一个可以使用的 MessageInspectors 的。

事情是这样的:

One of the ways you can go is using MessageInspectors.
Something like this:

首页的 - 创建消息检查 - 负责与您的凭据

First - create message inspector - to be responsible to add header with your credentials

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Xml;

namespace your_namespace
{


    /// <summary>
    /// /************************************
    /// * 
    /// * Creating Message inspector for 
    /// * updating all outgoing messages with Caller identifier header
    /// * read http://msdn.microsoft.com/en-us/magazine/cc163302.aspx
    /// * for more details
    /// * 
    /// *********************/
    /// </summary>
    public class CredentialsMessageInspector : IDispatchMessageInspector,
        IClientMessageInspector
    {
        public object AfterReceiveRequest(ref Message request,
            IClientChannel channel,
            InstanceContext instanceContext)
        {
            return null;
        }

        public void BeforeSendReply(ref Message reply, object
            correlationState)
        {
#if DEBUG
            //// Leave empty 
            //MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
            //Message message = buffer.CreateMessage();
            ////Assign a copy to the ref received
            //reply = buffer.CreateMessage();


            //StringWriter stringWriter = new StringWriter();
            //XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);
            //message.WriteMessage(xmlTextWriter);
            //xmlTextWriter.Flush();
            //xmlTextWriter.Close();

            //String messageContent = stringWriter.ToString();
#endif             
        }

        public void AfterReceiveReply(ref Message reply, object
            correlationState)
        {
#if DEBUG
            //// Leave empty 
            //MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
            //Message message = buffer.CreateMessage();
            ////Assign a copy to the ref received
            //reply = buffer.CreateMessage();


            //StringWriter stringWriter = new StringWriter();
            //XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);
            //message.WriteMessage(xmlTextWriter);
            //xmlTextWriter.Flush();
            //xmlTextWriter.Close();

            //String messageContent = stringWriter.ToString();
#endif
        }

        public object BeforeSendRequest(ref Message request,
            IClientChannel channel)
        {
            request = CredentialsHelper.AddCredentialsHeader(ref request);
            return null;
        }

        #region IDispatchMessageInspector Members

        #endregion
    }
}

的 - 添加代码,添加标题

Second - add the code to add header

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;

namespace your_namespace
{

    public class CredentialsHelper
    {
       // siple string is for example - you can use your data structure here
        private static readonly string CredentialsHeaderName = "MyCredentials";
        private static readonly string CredentialsHeaderNamespace = "urn:Urn_probably_like_your_namespance";

        /// <summary>
        /// Update message with credentials
        /// </summary>
        public static Message AddCredentialsHeader(ref Message request)
        {

          string user = "John";
          string password = "Doe";

            string cred = string.Format("{0},{1}",   user, password);

            // Add header
            MessageHeader<string> header = new MessageHeader<string>(cred);
            MessageHeader untyped = header.GetUntypedHeader(CredentialsHeaderName, CredentialsHeaderNamespace);

            request = request.CreateBufferedCopy(int.MaxValue).CreateMessage();
            request.Headers.Add(untyped);

            return request;
        }

        /// <summary>
        /// Get details of current credentials from client-side added incoming headers
        /// 
        /// Return empty credentials when empty credentials specified 
        /// or when exception was occurred
        /// </summary>
        public static string GetCredentials()
        {
            string credentialDetails = string.Empty;
            try
            {
                credentialDetails = OperationContext.Current.IncomingMessageHeaders.
                    GetHeader<string>
                        (CredentialsHeaderName, CredentialsHeaderNamespace);
            }
            catch
            {
                    // TODO: ...
            }
            return credentialDetails;
        }

    }
}



第三的 - 让你的服务器端

Third - get your credentials on the server side

public void MyServerSideMethod()
{
   string credentials = CredentialsHelper.GetCredentials();
   . . . 
}



希望这有助于。

Hope this helps.

这篇关于在WCF SOAP API使用HTTP授权头认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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