WCF服务和oauth + jQuery ajax调用

时间:2013-07-16 13:01:07

标签: wcf jquery oauth

我试图在我的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;

        }

的Web.config: -

<?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>

2 个答案:

答案 0 :(得分: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的问题。有什么想法吗?

感谢。

答案 1 :(得分:0)

“但我仍然遇到Get和JSONP以及oAuth的问题。有什么想法吗?” - &GT;我可以使用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);
    }
});

感谢。