1

WCF サービスに oauth 認証を実装しようとしていました。jQuery ajaxからサービスコールを行っています。POST動詞を使用して、CORS対応サービスで次のコードを試しました。しかし、ここでは常に null として 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 で同じ認証を行いました。以下はコードです。ここで認証は機能していますが、サービスがデータを返しても結果が得られません。(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>
4

2 に答える 2

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 が毎回変化するため、異なる署名を取得しています。SOハードコーディング値を与えるのではなく、ajaxリクエストを介して正しい署名を渡す必要があります。提案してください。

しかし、まだ Get と JSONP と oAuth に問題があります。何かご意見は?

ありがとう。

于 2013-07-24T09:06:09.930 に答える