1

我坚持这一点。我有一个 WCF 数据服务,它成功地在 Azure 服务总线中创建了一个 HTTPS 终结点。

我最初将服务设置为测试使用<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 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 集合) +369 System.Linq .Enumerable.ToList(IEnumerable`1 source) +58 CFARPOCClient.Controllers.HomeController.Banks() 在 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 step, Boolean& completedSynchronously) +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 回答