2012-11-11 78 views
1

我被困在此。我有一個WCF數據服務,可以在Azure服務總線中成功創建一個HTTPS端點。通過Azure服務總線對WCF數據服務進行身份驗證

我最初設置服務使用<security relayClientAuthenticationType="None" />進行測試,我能夠在客戶端使用服務。

然而,通過這項服務的數據會很敏感,所以要鎖定它,我在服務的Web.Config文件中切換到<security relayClientAuthenticationType="RelayAccessToken" />

我使用下面的代碼,以獲得我的令牌:

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; 
     } 

當我開發的代碼來獲取和附加我跑中大量令牌錯誤的道理,所以我相信我成功地得到一個令牌現在,但現在我得到以下錯誤:

500 TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0, Timestamp:11/11/2012 11:48:33 AM Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.Data.Services.Client.DataServiceClientException: 500 TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0, Timestamp:11/11/2012 11:48:33 AM Source Error: Line 31: context.SendingRequest += new EventHandler(OnSendingRequest); Line 32: Line 33: var results = (from b in context.Banks where b.Bank1 != "Bank1" select b).Take(200).ToList(); Line 34: Line 35: try Source File: c:\Users\v-tadam.REDMOND\Documents\Visual Studio 2012\Projects\CFARPOC\CFARPOCClient\Controllers\HomeController.cs Line: 33 Stack Trace: [DataServiceClientException: 500 TrackingId:38940805-f9b3-4444-a8e3-2a00b2309cf6_G0, Timestamp:11/11/2012 11:48:33 AM] System.Data.Services.Client.QueryResult.Execute() +414618 System.Data.Services.Client.DataServiceRequest.Execute(DataServiceContext context, QueryComponents queryComponents) +131 [DataServiceQueryException: An error occurred while processing this request.] System.Data.Services.Client.DataServiceRequest.Execute(DataServiceContext context, 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 collection) +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 controller, Object[] parameters) +14 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +211 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +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 result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9629708 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

這錯誤不能幫助我找到問題。我究竟做錯了什麼?在執行安全措施之前使用該服務完美無瑕,並且我已經完成了所有研究,以瞭解如何獲取令牌並將其附加到我的請求中。有什麼東西會跳出來,我做錯了嗎?

回答

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; 

希望我的愚蠢幫助別人:)