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:

Friday, January 29, 2010

CF HttpWebRequest does not allow writing to the request stream by default

While trying to send data via a request stream, I ran into this error in the compact framework:
ex = {"Either ContentLength must be set to a non-negative number, or SendChunked set to true in order to perform the write operation when AllowWriteStreamBuffering is disabled."}

This was a bit confusing since I didn't get this error when running from a windows client.  I finally figured out that I have to allow writing to the stream:

private void SendData(WebRequest request, object dto)
{
   // I had to add this for the CF framework. It isn't true by default.
   if (request is HttpWebRequest)
      ((HttpWebRequest) request).AllowWriteStreamBuffering = true;

   using (Stream requestStream = request.GetRequestStream())
   {
         if (IsJsonRequest(request))
            SendDataAsJson(requestStream, dto);
        else SendDataAsXml(requestStream, dto);
   }
}

MSUnit toolbar does not work or is grayed out

If you have a library with MSUnit tests in it (probably because you converted MBUnit or NUnit tests to MSUnit tests) and the MSUnit toolbar will not work (stays grayed out), you are probably missing the ProjectTypeGuids. The line your missing from the library project file in the top most PropertyGroup is this one:


<projecttypeguids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</projecttypeguids>

The line above identifies the project as a test project ({3AC096D0-A1C2-E12C-1390-A8335801FDAB}) in the C# ({FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}) language.


Reference that I found after the fact:




Friday, December 4, 2009

JSON Serialization

The Problem:
Here is the error that took me a few days of back-and-forth with an India programming team to figure out:

DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON.
at System.Runtime.Serialization.Json.JsonWriterDelegator.WriteDateTime(DateTime value)
at System.Runtime.Serialization.XmlWriterDelegator.WriteDateTime(DateTime value, XmlDictionaryString name, XmlDictionaryString ns)


The Solution:
I found that I had an uninitialized date time property (meaning it was equal to DateTime.MinValue) in my data transfer object (DTO). If your WEST of GMT, this doesn't cause a problem; however, if your EAST of GMT, the DataContractJsonSerializer will puke.

Saturday, November 7, 2009

WCF REST HttpStatusCode.Unauthorized status code does not work

Alternate title: WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized does not work.
Alternate title: HttpStatusCode.Unauthorized turned into HttpStatusCode.NotFound

The problem:
I spent at least three hours tracking this stupid thing down. The problem that I ran into was Forms Authentication. What's happening is that I am returning HttpStatusCode.Unauthorized (401), but forms authentication is routing the error to the login page. If you don't have a Login.aspx, you will get a resource not found error (HttpStatusCode.NotFound - 404).

If you can change your authentication mode to Windows and the problem goes away, you have this problem.
OR
If you use the browser to hit your REST web service that requires authentication (it returns a 401 status code) and it routes you to your aspx login screen, you have this problem.

Possible solutions:
  • Check out this MSDN article: Supporting HTTP Authentication and Forms Authentication in a Single ASP.NET Web Site . If for some reason this link dies, search for Mixed Authentication Disposition ASP.NET Module (MADAM), which the name of the HttpModule that the MSDN article talks about that allows you to use both HTTP authentication (in this case basic/digest) and Forms authentication in the same web site.
  • I did run across a couple of post were people wanted to use both Windows and Forms authentication together. In those post, it was suggested that the people create a virtual directory in IIS so that you could have two different web.config that specify different authentication methods. I don't know if this will work for this problem, but it is a possible alternative.





Thursday, September 10, 2009

Remote Desktop Drive sharing not working

I ran into a Windows 2003 server on our local network today that would not allow me to share drives so that I could upload/download files to/from the server.

My remote desktop settings look like this:


However, when I connected and opened up windows explorer, my local drives did not appear in the tree view on the left.

Update ->  There two ways to fix this.

Way 1:
After a little bit of digging, I discovered that the group policy for drive sharing (a.k.a. "Drive redirection") was not configured on the Windows 2003 server. This can be fixed by using the MMC snap in called "Group Policy Object Editor":


After navigating to "\Local Computer Policy\Computer Configuration\Administrative Templates\Windows Components\Terminal Services\Client/Server data redirect", I changed the "Do not allow drive redirection" from "Not Configured" to "Disabled" under and it worked fine afterward:




Way 2:
This can also be accomplished this way on Windows Server 2003:



Steps from the Administrative tools window under the control panel.
  1. Double click on "Terminal Service Configuration"
  2. Left click "Connections" on the dialog
  3. Right click "Rdp-Tcp" in the right hand windows.
  4. Uncheck "Drive mapping" on the "Client Settings" tab.

Thursday, July 9, 2009

CurrentSessionContext call results in "No current session context configured."

Well, I was playing with NHibernate today and trying to create a single session in a windows application that would stay open till I was ready to close it. I was using CurrentSessionContext.Bind(someSession) when I generated this error: "No current session context configured." After some searching around, I discovered that I was missing a line in my Hibernate.cfg.xml file.

< name="current_session_context_class" > thread_static < /property >

Apparently, it can have several settings:
  • managed_web
  • call
  • thread_static
  • web

References:

Thursday, June 25, 2009

RichTextBox with better spacing

It took a bit of looking around today to figure out how to create a resource file entry to style my RichTextBox so that it doesn't have ridiculous spacing. I found this, which shows how to do it inside the page or window. However, I wanted to put it in a resource file so that I could reuse it. I finally came up with this:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="RichTextWithBetterSpacing" TargetType="{x:Type RichTextBox}">
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontFamily" Value="Arial"/>
<Style.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0"/>
</Style>
</Style.Resources>
</Style>
</ResourceDictionary>

Wednesday, December 10, 2008

Custom RoleProvider notes

I finally completed my custom RoleProvider that uses NHibernate to retrieve data from the database. Below I have listed my notes on this topic.

Issue: My RoleProvider would not work if I overrode the default constructor.
Solution: Override the Initialize method and put your code there instead.

Issue: The RoleProvider class cannot access HttpContext.Current.Session.
Solution: There really isn't a solution. It's just a fact.

Resources:

Custom MembershipProvider notes

I finally completed my custom MembershipProvider that uses NHibernate to retrieve data from the database. Below I have listed my notes on this topic.

Issue: I could not get the "Web Site Administration Tool" to create a user without giving me an error.

Solution: Make sure that the following property returns true:
public override bool RequiresQuestionAndAnswer
If it was false, I would get a generic error that made absolutely no sense:

The following message may help in diagnosing the problem: Exception has been thrown by the target of an invocation. at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.Web.Administration.WebAdminMembershipProvider.CallWebAdminMembershipProviderHelperMethodOutParams(String methodName, Object[] parameters, Type[] paramTypes) at System.Web.Administration.WebAdminMembershipProvider.CreateUser(String username, String password, String email, String passwordQuestion, String passwordAnswer, Boolean isApproved, Object providerUserKey, MembershipCreateStatus& status) at System.Web.UI.WebControls.CreateUserWizard.AttemptCreateUser() at System.Web.UI.WebControls.CreateUserWizard.OnNextButtonClick(WizardNavigationEventArgs e) at System.Web.UI.WebControls.Wizard.OnBubbleEvent(Object source, EventArgs e) at System.Web.UI.WebControls.CreateUserWizard.OnBubbleEvent(Object source, EventArgs e) at System.Web.UI.WebControls.Wizard.WizardChildTable.OnBubbleEvent(Object source, EventArgs args) at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


Issue: I ran into a couple of examples that verify the password by unencoding the one in the database and then comparing it to the user's entry.

Solution: I recommend that you do it the same way that Microsoft did it. That is to encode the user's entry and compare it to the encoded database entry. It eliminates the need to have an unencode method.


Other things worth noting:

If you are going to use Encryption encoding (as opposed to clear text or hash encoding), don't forget to generate your own MachineKey. Here are a few link on that topic:

Resources:

Thursday, December 4, 2008

WCF & the IIS Require secure channel (ssl) setting

After turning on "Require secure channel (SSL)" on the IIS 6.0 Directory security tab (secure communications dialog), I lost several hours today trying to figure out why my WCF services stopped working and started giving me this error:
[System.ServiceModel.ServiceActivationException] = {"The requested service, 'https://www.Dave.com/DoIt/MyService.svc' could not be activated. See the server's diagnostic trace logs for more information."}

I tried a variety of things, but when I finally broke down and ran the diagnostic trace I got the following:
The service '/DoIt/MyService.svc' cannot be activated due to an exception during compilation. The exception message is: Could not find a base address that matches scheme http for the endpoint with binding MetadataExchangeHttpBinding. Registered base address schemes are [https]..

All my services use https to send data; however, my metadata exchange binding, which I intended to remove/comment out later, use http. When I changed all my metadata exchanged end points to use mexHttpsBinding instead of mexHttpBinding and all my behaviors to use <servicemetadata httpsgetenabled="true"> instead of <servicemetadata httpgetenabled="true">, everything started working again.

I figured that the http endpoints would just be ignored or if accessed permissioned denied because all addresses must use a secure channel (https). It appears that I was wrong and that it causes a compilation error.

Wednesday, July 30, 2008

WCF DateTime field adjusted automatically for time zone

Well, I got bit by DateTime serialization yesterday. Our server is in the U.S. Central Standard Time (CST) zone and our client is in the U.S. Eastern Standard Time (EST) zone. All data saved in the database is relative to the client and NOT the server. So when the client wants to see all data for today, only the date is specified using DateTime.Today. So when the EST client sent a date of 7/29/08 00:00:00 AM to our WCF webservice on the CST server, the date was converted to 7/28/08 11:00:00 PM. The symptom from the client's point of view was that they could never retrieve data for today.

According to Coding Best Practices Using DateTime in the .NET Framework there are several ways to work around this; however, they missed one. If you change your dates so that DateTimeKind is unspecified, the XML serializer will NOT try to convert them. For example, this code will convert a date to DateTimeKind.Unspecified:


DateTime newDate = DateTime.SpecifyKind(oldDate, DateTimeKind.Unspecified);


References:

Friday, November 30, 2007

Dispatcher versus SynchronizationContext

Today I had the pleasure of playing with the Dispatcher and SynchronizationContext classes. I found that the Dispatcher class is useful when your sure that you are calling within the context of the user interface thread and the SynchronizationContext is useful when you're not quite sure.

If you obtain your Dispatcher class using the static Dispatcher.CurrentDispatcher method on some non-UI thread and call the BeginInvoke method, nothing will happen (No exception, no warning, nada). However, if you obtain your SynchronizationContext class via the static SynchronizationContext.Current method, it will return null if the thread is not a UI thread. This feedback is extremely useful since it allows you to react to both a UI thread and a non-UI thread accordingly.

Here is an example using the Dispatcher class:


using System;
using System.Threading;
using System.Windows.Threading; // WindowsBase.dll

namespace Test
{
public delegate void WriteTextDelegate(string message);

public class DispatcherTest
{
public void Start()
{
// Calling thread determines Dispatcher
m_Dispatcher = Dispatcher.CurrentDispatcher;

if (m_Timer == null)
m_Timer = new Timer(new TimerCallback(WriteText),
null, 1000, 2000);
else m_Timer.Change(1000, 2000);
}

public void Stop()
{
if (m_Timer != null)
m_Timer.Change(Timeout.Infinite, Timeout.Infinite);
}

public event WriteTextDelegate Message;

private Timer m_Timer;
private System.Windows.Threading.Dispatcher m_Dispatcher;

private void WriteText(object state)
{
m_Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new WriteTextDelegate(OnMessage),
DateTime.Now.ToString());
}

private void OnMessage(string message)
{
if (Message != null)
Message(message);
}
}
}



Here is an example using the SynchronizationContext class:

using System;
using System.Threading;

namespace Test
{
public delegate void WriteSomeTextDelegate(string message);

public class SyncTest
{
public void Start()
{
// Calling thread determines SynchronizationContext
m_Context = SynchronizationContext.Current;

if (m_Timer == null)
m_Timer = new Timer(new TimerCallback(WriteText),
null, 1000, 2000);
else m_Timer.Change(1000, 2000);
}

public void Stop()
{
if (m_Timer != null)
m_Timer.Change(Timeout.Infinite, Timeout.Infinite);
}

public event WriteSomeTextDelegate Message;

private System.Threading.Timer m_Timer;
private System.Threading.SynchronizationContext m_Context;

private void WriteText(object state)
{
string message = DateTime.Now.ToString();

if (m_Context != null)
{
m_Context.Post(new SendOrPostCallback(PostCallback), message);
}
else OnMessage(message); // non-UI thread called Start
}

private void OnMessage(string message)
{
if (Message != null)
Message(message);
}

private void PostCallback(object state)
{
if (state is string)
{
OnMessage(state as string);
}
else throw new ArgumentException("State should be a string");

}
}
}


Notes:
  • I used Reflector to look inside the WindowsBase.dll; however, I had problems finding the dll. I expected to find it in a directory below the usual location (C:\ Windows\ Microsoft.NET\ Framework\ v3.0); however, it was in this directory: C:\ Program Files\ Reference Assemblies\ Microsoft\ Framework\ v3.0
  • WCF: Asynchronous Operations

Friday, November 9, 2007

WCF Security Exception: Timestamp is invalid because its creation time is in the future

Well, I ran into a real fun bug today that surfaced itself on the user's computer as a "Security Exception see Inner Exception". Upon examining the inner exception, it told me that the message was incorrectly secured. After placing some tracing on the server, I found this error message:

The security timestamp is invalid because its creation time ('11/9/2007 10:37:07 PM') is in the future. Current time is '11/9/2007 10:28:52 PM' and allowed clock skew is '00:05:00'.

After fixing the user's clock, which was roughly 8 minutes fast, everything worked great. The next question is "How do I increase the maximum skew time"? It took a bit of searching to figure out that I need to create a custom binding to change the values. Here is an example of how to do it:

<bindings>
<customBinding>
<binding name="MaxClockSkewBinding">
<textMessageEncoding />
<security authenticationMode="Kerberos">
<localClientSettings maxClockSkew="00:07:00" />
<localServiceSettings maxClockSkew="00:07:00" />

<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
</bindings>

For more information, see How To: Set a Max Clock Skew on MSDN.


More References: