Friday, March 6, 2015

Every use of the Html.AntiForgeryToken helper injects a "X-Frame-Options: SAMEORIGIN" line into the header

We have recently encountered what I feel is a bug in the Html helper named AntiForgeryToken.  For every call to this helper, you will get one “X-Frame-Options: SAMEORIGIN” line stuck in your header.  

According to Microsoft guidance it should be used in conjunction with a form element.  The problem is that in MVC you can have as many forms on a page as you desire.  If you use the AntiForgeryToken helper with each one of them, you will get multiple instances of the “X-Frame-Options: SAMEORIGIN” line stuck in your header.  

I've recently encountered a page that had 147 instances of this line in the header and the page was being killed by default F5 router settings.  It was basically interpreting the excessive header lines as an injection attack of some form.  

If you encounter this, you have three options:
  • Increase the allowed header size in your routers and/or IIS.
  • Remove calls to Html.AntiForgeryToken helper (especially where forms are created in a loop). You will also have to remove the validation check on the controller side.
  • Add AntiForgeryConfig.SuppressXFrameOptionsHeader = true; to Global.ascx, which will remove X-Frame-Options: SAMEORIGIN” completely from your header.  
In my opinion, none of these are really good options.  I have also submitted a bug to Microsoft in the hopes that they will fix this problem.

A co-worker has suggested a possible solution (I have not tested it, but I will post it here) using a custom HtmlHelper:
public static MvcForm BeginAntiForgeryForm(this HtmlHelper htmlHelper)
{
            var mvcForm = htmlHelper.BeginForm();
            htmlHelper.ViewContext.Writer.Write(htmlHelper.AntiForgeryToken().ToHtmlString());
            //Remove X-Frame-Option header to remove duplicates
            HttpContext.Current.Response.Headers.Remove("X-Frame-Options");
            //Add it manually here or in IIS HTTP Response Headers
            HttpContext.Current.Response.Headers.Add("X-Frame-Options","SAMEORIGIN");
            return mvcForm;
}


References


Friday, November 14, 2014

Problems with Forefront Unified Access Gateway (UAG) and the PUT verb




Problem:
We were seeing this error when updating data using the PUT verb
net::ERR_CONNECTION_RESET message
SyntaxError: Unexpected end of input {stack: (...), message: "Unexpected end of input"}

Solution:
Ultimately, I believe the problem was a result of letting WEB API return a void to the calling client.  This results in a 204 "No Content" being returned to the user.  It worked fine internally, but externally via UAG the data was being saved and client was seeing an error.

Now, we are returning an OK like this:
[HttpPut]
public HttpResponseMessage Update(UserViewModel value)
{
        // Update stuff
return Request.CreateResponse(HttpStatusCode.OK);
}

Also, make sure that your Ajax call does NOT include a dataType.
function update(someJavaScriptObject) {
return $.ajax({
url: '/api/Users',
type: 'PUT',
data: someJavaScriptObject,
      dataType: "json"
 });
};

Another possible problem:
Returning primitives from WEB API controller methods and specifying a dataType: "json" in Ajax call.

Another possible solution:

  • Assuming you have the json formatter setup in the WebApiConfig:
    • Just wrap it in a class so that it is turned into a JSON object,  
    • You could also use a anonymous class and CreateResponse method as in:
      return Request.CreateResponse(HttpStatusCode.OK,  new {id = 344});  
  • Remove dataType from the ajax call so that your call accepts *.* and then return the primitive from the WEB API method like this:
    return Request.CreateResponse(HttpStatusCode.OK, 344);  



Thursday, October 23, 2014

Kendo annoyances series: numerictextbox

The problem:
You cannot let the user enter whole numbers. They will be interpreted as thousands of percent.  For example, if the user enters 90 as opposed to .90, this will be 9000%.  


The solution:
Since our users insist on using whole numbers, the only way I've found to fix this is to adjust the maximum percentage value up to 100 (instead of 1), monitor the data change event and then divide any number that is greater than one by 100.  By setting the value, it will cause another change event and then I can push the change to the server.

See the jsFiddle example below for more information.

Resources

Kendo annoyances series: select html element

The problem:
If you need two way binding so that edits that take place on your viewmodel (after user interactions or an AJAX call), you need to create an option template (option being the html element that represents an item inside of a select html element).

Without two way binding:
<select data-text-field="firstName" data-value-field="id" data-bind="source: users, value: selecteUser"></select>

The solution:
<select data-text-field="firstName" data-value-field="id" data-template="optionTemplate"   data-bind="source: users, value: selecteUser"></select>

<script type="text/x-kendo-template" id="optionTemplate">
        <option data-bind="value:id,text:firstName"></option>
  </script>



Resources:


Thursday, September 11, 2014

Kendo: Binding cheat sheet

Varies by type

BUTTON
<button data-bind="text: toggleButtonText, click: toggleButtonClick"></button>

DIV
<div data-bind="text: someText"></div>

<div data-bind="html: rawHtml"></div>


INPUT
<input type="button" style="float: left" data-bind="value: someField, click: toggleChildrenVisibilty" />
<input type="checkbox" style="float: left" data-bind="checked: itemIsLocked" />

SPAN
<span data-bind="text: originalAmount"></span>

SELECT
<select data-value-field="id" data-text-field="name" data-bind="value: selectedProduct, source: products">
</select>

<script>
   var viewModel = kendo.observable({ selectedProduct: null, products:
     [ { id: 1, name: "Coffee" }, { id: 2, name: "Tea" }, { id: 3, name: "Juice" } ] });

   viewModel.selectedProduct = viewModel.products[1];
   kendo.bind($("select"), viewModel);
</script>

Reference
• From http://docs.telerik.com/kendo-ui/getting-started/framework/mvvm/bindings/value


Template
<div data-template="items-template" data-bind="source: items"></div>

TEXTAREA
<textarea id="note" data-bind="value: myNote" rows="3"></textarea>

Kendo: binding to raw HTML

All I wanted was to bind the inner HTML of a DIV to some raw HTML, here is how you do that:
View:
<div data-bind="html: problemList"></div>

ViewModel
var viewModel = new kendo.data.ObservableObject({
    problemList: '<ul><li>Problem 1</li> <li>Problem 2</li></ul>'
});


Friday, July 2, 2010

WCF Method not found only effects SOAP services

I thought I was going to have to blow the OS away on my laptop since it's the only computer I've got that is experiencing this error with SOAP services (REST works great):

The problem:
Method not found: 'Void System.IdentityModel.Selectors.SecurityTokenRequirement.set_IsOptionalToken(Boolean)'.


Stack trace:
at System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, Boolean isOptional, IList`1 providerSpecList)
at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

The solution:
KB976394 - WCF: Make OutgoingSupportingToken public

Reference: