1

我试图在我的 WCF 服务中实现 oauth 身份验证。我正在从 jQuery ajax 进行服务调用。我已经在使用 POST 动词的 CORS 启用服务中尝试了以下代码。但是在这里我得到 pa["oauth_consumer_key"] 一如既往地为空。请查看代码并帮助我找出问题所在。

使用 POST 和 CORS


jQuery ajax 调用:-

 function logClick() {
            var sEmail = $('#username').val();
            var sPassword = $('#password').val();
            var key = "test";
            var oauth_signature = "xxxxxxx";
            var timestamp = (new Date()).getTime();
            var nonce = Math.random();
            var auth_header = 'OAuth oauth_nonce="' + nonce + '"' +
            ', oauth_signature_method="HMAC-SHA1"' +
            ', oauth_timestamp="' + timestamp + '"' +
            ', oauth_consumer_key="' + key + '"' +
            ', oauth_signature="' + oauth_signature + '"' +
            ', oauth_version="1.0"';

            var userData = '{"email":"' + sEmail + '","password":"' + sPassword + '"}';
            $.support.cors = true;
            $.ajax({
                data: userData,
                type: "POST",
                dataType: "json",
                contentType: "application/json;charset=utf-8",
                url: "http://mydomain/MyAppService.svc/UserValidation",
                beforeSend : function(xhr, settings) {
                          $.extend(settings, { headers : { "Authorization": auth_header } });
              },
                success: function (msg) {
                   alert("success");
                },
                error: function () {
                    alert("Network error");
                }
            });
        }

WCF 服务代码

  [OperationContract]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UserValidation")]
        int UserValidation(string email,string password);


     public int UserValidation(string email, string password)
    {

        if (Authenticate(WebOperationContext.Current.IncomingRequest))
        {
            //my code
             return 1;
        }
        else
        {
            return 0;
        }
    }

    private static bool Authenticate(IncomingWebRequestContext context)
    {

        bool Authenticated = false;
        string normalizedUrl;
        string normalizedRequestParameters;

        NameValueCollection pa = context.Headers; 
        //NameValueCollection pa = context.UriTemplateMatch.QueryParameters;// tried this also
        if (pa != null && pa["oauth_consumer_key"] != null)  // pa["oauth_consumer_key"] is always null
        {
              // to get uri without oauth parameters
            string uri = context.UriTemplateMatch.RequestUri.OriginalString.Replace
                (context.UriTemplateMatch.RequestUri.Query, "");
            string consumersecret = "suryabhai";
            OAuthBase oauth = new OAuthBase();
            string hash = oauth.GenerateSignature(
                new Uri(uri),
                pa["oauth_consumer_key"],
                consumersecret,
                null, // totken
                null, //token secret
                "GET",
                pa["oauth_timestamp"],
                pa["oauth_nonce"],
                out normalizedUrl,
                out normalizedRequestParameters
                );

            Authenticated = pa["oauth_signature"] == hash;
         }
        return Authenticated;

    }

我在 GET 和 JSONP 中进行了相同的 aouth 身份验证。以下是代码。此处身份验证正在工作,但即使服务返回数据,我也没有得到结果。(在 jQuery ajax 调用中进入错误块)

GET 和 JSONP


jQuery ajax 调用:-

function getData() {

            $.ajax({
                  url: "http://mydomain/MyAppService.svc/GetData/328?oauth_consumer_key=test&oauth_nonce=10a33ed37b549301644b23b93fc1f1c5&oauth_signature=AMTsweMaWeN7kGnSwoAW44WKUuM=&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1289976718&oauth_version=1.0?callback=?",
                type: "GET",
                crossDomain: true,
                contentType: "application/json; charset=utf-8",
                dataType: "jsonp",
                processdata: true,
                success: function (msg) {
                    alert("success");

                },
                error: function error(response) {
                    alert(" Network Error"); // always entering to this block
                }
            });

WCF 服务:-

 [OperationContract]
        [WebInvoke(Method = "GET",
  ResponseFormat = WebMessageFormat.Json,
  BodyStyle = WebMessageBodyStyle.Bare,
  UriTemplate = "GetData/{ParentID}")]
        List<Parent> GetData(string ParentID);


 public List<Parent> GetData(string ParentID)
        {
             List<Parent> ParentList = new List<Parent>();
            if (Authenticate(WebOperationContext.Current.IncomingRequest)) // it is working
           {
                //my code
              return ParentList ; // result is getting, but on client it is going to error block of jQUery ajax call
           }
            else
            {
                return ParentList ;
            }
        }

private static bool Authenticate(IncomingWebRequestContext context)
        {

            bool Authenticated = false;
            string normalizedUrl;
            string normalizedRequestParameters;
            NameValueCollection pa = context.UriTemplateMatch.QueryParameters;
            if (pa != null && pa["oauth_consumer_key"] != null)  
            {
                  // to get uri without oauth parameters
                string uri = context.UriTemplateMatch.RequestUri.OriginalString.Replace
                    (context.UriTemplateMatch.RequestUri.Query, "");
                string consumersecret = "suryabhai";
                OAuthBase oauth = new OAuthBase();
                string hash = oauth.GenerateSignature(
                    new Uri(uri),
                    pa["oauth_consumer_key"],
                    consumersecret,
                    null, // totken
                    null, //token secret
                    "GET",
                    pa["oauth_timestamp"],
                    pa["oauth_nonce"],
                    out normalizedUrl,
                    out normalizedRequestParameters
                    );

                Authenticated = pa["oauth_signature"] == hash;
             }
            return Authenticated;

        }

网络配置:-

<?xml version="1.0"?>
<configuration>

  <system.web>
    <authentication mode="None" />
    <httpRuntime maxRequestLength="2147483647"/>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true"  aspNetCompatibilityEnabled="true"/>
    <services>
      <service name="DataAppAppService.MyAppService">
        <endpoint address="" behaviorConfiguration="webHttpBehavior" binding="webHttpBinding" bindingConfiguration="WebHttpBindingWithJsonP" contract=DataAppAppService.IMyAppService" />
      </service>
    </services>

    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"  maxReceivedMessageSize="2147483647"
                   maxBufferSize="2147483647" transferMode="Streamed"
              >

        </binding>

      </webHttpBinding>
    </bindings>

    <behaviors>
      <endpointBehaviors>
        <behavior name="webHttpBehavior">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceThrottling maxConcurrentCalls="30" maxConcurrentInstances="30" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="true" />
  </system.webServer>

</configuration>
4

2 回答 2

0

“但我仍然对 Get、JSONP 和 oAuth 有疑问。有什么想法吗?” --> 我可以使用带有 CORS 的 GET 方法来解决这个问题。这是我的代码。

$.support.cors = true;
$.ajax({
    type: "GET",
    dataType: "json",
    contentType: "application/json;charset=utf-8",
    url: "http://mydomain:89/MyAppAppService.svc/GetFolders",
    beforeSend: function (xhr) {
      var username = "test";
      var password = "testpwd";
      xhr.setRequestHeader("Authorization", "Basic " + $.base64('encode', username + ':' + password));
                               },
    success: function (msg) {
        alert("Success");
    },
    error: function (jqXHR, status, message) {
      alert(jqXHR.responseText);
      alert(status + " " + message);
    }
});

谢谢。

于 2013-08-28T08:41:32.680 回答
0

我能够解决“使用 POST 和 CORS”问题。我已将 Authorization 标头添加到“Access-Control-Allow-Headers”中,它解决了这个问题。

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept");

有什么方法可以从 javascript 生成 oauth_signature。现在我正在对值进行硬编码,但是随着时间戳和 oauth_nonce 每次都在变化,我得到了不同的签名。所以我需要通过 ajax 请求传递正确的签名,而不是提供硬编码值。请给个建议。

但我仍然对 Get、JSONP 和 oAuth 有疑问。有什么想法吗?

谢谢。

于 2013-07-24T09:06:09.930 回答