1

私はこれにこだわっています。Azure Service Bus で HTTPS エンドポイントを正常に作成する WCF データ サービスがあります。

私は最初に を使用してテスト用にサービスをセットアップしまし<security relayClientAuthenticationType="None" />たが、クライアントでサービスを問題なく使用することができました。

ただし、このサービスを通過するデータは機密であるため、ロックダウンするために<security relayClientAuthenticationType="RelayAccessToken" />、サービスの Web.Config ファイルに切り替えました。

次のコードを使用してトークンを取得しています。

static string GetToken(string serviceNamespace, string issuerName, string issuerPassword)
    {
        if (_token == null)
        {
            string acsEndpoint = "https://" + serviceNamespace + "-sb.accesscontrol.windows.net/WRAPv0.9";
            string relyingPartyAddress = "http://" + serviceNamespace + ".servicebus.windows.net";

            NameValueCollection postData = new NameValueCollection
            {
                { "wrap_scope", relyingPartyAddress },
                { "wrap_name", issuerName },
                { "wrap_password", issuerPassword },
            };

            WebClient webClient = new WebClient();
            byte[] responseBuffer = webClient.UploadValues(acsEndpoint, "POST", postData);
            string response = Encoding.UTF8.GetString(responseBuffer);
            response = Uri.UnescapeDataString(response);

            string[] tokenVariables = response.Split('&');

            int tokenIndex = Array.FindIndex(tokenVariables, s => s.StartsWith("HMACSHA256"));

            string[] tokenVariable = tokenVariables[tokenIndex].Split('=');

            _token = HttpUtility.UrlDecode(tokenVariable[1]);
        }

        return _token;
    }
static string _token = null;

次にcontext.SendingRequest += new EventHandler<SendingRequestEventArgs>(OnSendingRequest);、以下を使用してトークンを REST 要求のヘッダーに追加します。

static void OnSendingRequest(object sender, SendingRequestEventArgs e)
    {
        e.RequestHeaders.Add(
            "Authorization",
            string.Format("WRAP access_token=\"{0}\"", GetToken("MyNamespace", "owner", "MySecret") )
            );
    }

そして、私のリクエストは次の形式になります(セキュリティが追加される前は完全に機能していました)

try
        {
            var results = (from b in context.Banks where b.Bank1 != "Bank1" select b).Take(200).ToList();
            ViewBag.Results = results;
        }
        catch (DataServiceQueryException ex)
        {
            ViewBag.Message = "Authentication failed. A new token will be requested.";
            var code = ex.Response.StatusCode;
            if (code == 401)
                _token = null;
        }

トークンを取得してアタッチするためのコードを開発しているときに、多くのトークン エラーに遭遇したため、現在はトークンを正常に取得していると思いますが、次のエラーが発生します。

500TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0、タイムスタンプ:11/11/2012 11:48:33 AM 説明: 現在の Web 要求の実行中に未処理の例外が発生しました。エラーの詳細とコード内のどこでエラーが発生したかについては、スタック トレースを確認してください。例外の詳細: System.Data.Services.Client.DataServiceClientException:500TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0、タイムスタンプ:11/11/2012 11:48:33 AM ソース エラー: 31 行目: context.SendingRequest += new EventHandler(OnSendingRequest); 32 行目: 33 行目: var results = (from b in context.Banks where b.Bank1 != "Bank1" select b).Take(200).ToList(); 34 行目: 35 行目: 試してください ソース ファイル: c:\Users\v-tadam.REDMOND\Documents\Visual Studio 2012\Projects\CFARPOC\CFARPOCClient\Controllers\HomeController.cs 行: 33 スタック トレース: [DataServiceClientException:500TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0、タイムスタンプ:11/11/2012 11:48:33 AM] System.Data.Services.Client.QueryResult.Execute() +414618 System.Data.Services.Client.DataServiceRequest .Execute(DataServiceContext コンテキスト、QueryComponents queryComponents) +131 [DataServiceQueryException: この要求の処理中にエラーが発生しました。] System.Data.Services.Client.DataServiceRequest.Execute(DataServiceContext コンテキスト、QueryComponents queryComponents) +432 System.Data.Services.Client .DataServiceQuery`1.Execute() +77 System.Data.Services.Client.DataServiceQuery`1.GetEnumerator() +13 System.Collections.Generic.List`1..ctor(IEnumerable`1 コレクション) +369 System.Linq .Enumerable.ToList(IEnumerable`1 source) +58 CFARPOCClient.Controllers.HomeController.Banks() in c:\Users\v-tadam.REDMOND\Documents\Visual Studio 2012\Projects\CFARPOC\CFARPOCClient\Controllers\HomeController.cs:33 lambda_method(Closure , ControllerBase , Object[] ) +101 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase コントローラー, Object[] パラメーター) +14 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext、IDictionary`2 パラメータ) +211 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext、ActionDescriptor actionDescriptor、IDictionary`2 パラメータ) +27 System.Web. Mvc.Async.c__DisplayClass42.b__41() +28 System.Web.Mvc.Async.c__DisplayClass8`1.b__7(IAsyncResult _) +10 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57 System.Web .Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +48 System.Web.Mvc.Async.c__DisplayClass39.b__33() +57 System.Web.Mvc.Async.c__DisplayClass4f.b__49() +223 System.Web.Mvc.Async.c__DisplayClass37.b__36(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResult`1 .End() +57 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +48 System.Web.Mvc.Async.c__DisplayClass2a.b__20() +24 System.Web.Mvc.Async.c__DisplayClass25.b__22( IAsyncResult asyncResult) +102 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +43 System.Web.Mvc.c__DisplayClass1d.b__18(IAsyncResult) asyncResult) +14 System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +57 System.Web.Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.Controller.EndExecute (IAsyncResult asyncResult) +47 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.c__DisplayClass8.b__3(IAsyncResult asyncResult) +25 System.Web. Mvc.Async.c__DisplayClass4.b__3(IAsyncResult ar) +23 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +47 System.Web.Mvc .MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 結果) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708 System.Web.HttpApplication.ExecuteStep(IExecutionStep ステップ、ブール値および完了同期) +155

このエラーは、問題を見つけるのに役立ちません。私は何を間違っていますか?セキュリティが実装される前に、サービスの使用は問題なく機能し、トークンを取得してリクエストに添付する方法についてできる限りの調査を行いました。私が間違ってやったことが飛び出しますか?

4

1 に答える 1

4

私は自分の間違いを見つけました。何がトークンを構成するかについて根本的な誤解がありました。何らかの理由で、「HMACSHA256」に続くテキストであることが頭に浮かびましたが、実際には「wrap_access_token =」に続く応答のすべてがトークンでした (これは今では明らかなようです...)

とにかく、他の誰かがこの問題を抱えている場合、トークンは正しく取得されていますが、間違ったトークンが要求ヘッダーに追加されているため、500 エラー コードがスローされています。「GARBAGETOKEN」を付けて同じ動作を観察することでこれをテストしました。

以下は、有効な GetToken メソッドです。

static string GetToken(string serviceNamespace, string issuerName, string issuerPassword)
    {
        if (_token == null)
        {
            string acsEndpoint = "https://" + serviceNamespace + "-sb.accesscontrol.windows.net/WRAPv0.9";
            string relyingPartyAddress = "http://" + serviceNamespace + ".servicebus.windows.net";

            NameValueCollection postData = new NameValueCollection
            {
                { "wrap_scope", relyingPartyAddress },
                { "wrap_name", issuerName },
                { "wrap_password", issuerPassword },
            };

            WebClient webClient = new WebClient();
            byte[] responseBuffer = webClient.UploadValues(acsEndpoint, "POST", postData);
            string response = Encoding.UTF8.GetString(responseBuffer);

            string token = response.Split('&')
                .Single(value => value.StartsWith("wrap_access_token=") )
                .Split('=')[1];

            _token = HttpUtility.UrlDecode(token);
        }

        return _token;
    }
    static string _token = null;

うまくいけば、私の愚かさが他の誰かを助けます:)

于 2012-11-12T04:20:02.713 に答える