Quick Powershell and SQL Server tip

Today I had to create a quick copy of a database for some integration testing purposes. In the process, I learnt two things:

1. How to replace text in a bunch of files with Powershell:

dir Create* | % { $file=$_; (Get-Content $file) | % { $_ -replace '\[RealDb\]', '[My_Db_Copy]' } | Set-Content $file }

2. How to execute a bunch of files against a SQL server:

dir Create* | % { sqlcmd -S MY_DATABASE_SERVER -i $_ }

No rocket science, but very, very helpful to me. And maybe to someone else?

Posted in Uncategorized | Leave a comment

MVC AntiForgeryToken and WIF gotcha

We are in the process of implementing a Windows Identity Foundation based login. And in this process, we had some problems with an MVC site. The AntiForgeryTokens were suddenly invalid. We got the following error on every postback in our MVC app:


A required anti-forgery token was not supplied or was invalid.

Stack trace:
at System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.c__DisplayClass8.b__4()
at System.Web.Mvc.Async.AsyncResultWrapper.c__DisplayClass1.b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.c__DisplayClass8`1.b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

After an afternoon of head-scratching and googling, I decided to download the source code of MVC myself (a big thank you to Microsoft for providing it) and see what was wrong.

This StackOverFlow post led me in the right direction:

A couple of posts helped me build our MVC webs against the MVC source code in lieu of the official MVC distribution:

(I eventually went for the last approach, although the source server stuff is pretty cool too).

Stepping through the MVC code, I found that the following code was the problem:

  • In MVC2:System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization, SystemWebMvc\Mvc\ValidateAntiForgeryTokenAttribute.cs, lines 68-69
  • In MVC3:System.Web.Helpers.AntiForgeryWorker.Validate, System.Web.WebPages\Helpers\AntiForgeryWorker.cs, lines 89 and 90

The code looks like this.

            string currentUsername = AntiForgeryData.GetUsername(context.User);
            if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {
                // error: form token is not valid for this user
                // (don't care about cookie token)
                throw CreateValidationException();
            }

I found out that the current user in our MVC app had the Name set to null. However, in the AntiForgeryData class, the Username property is a bit magic:

        public string Username {
            get {
                return _username ?? String.Empty;
            }
            set {
                _username = value;
            }
        }

However, The AntiForgeryData.GetUserName is not:

        internal static string GetUsername(IPrincipal user) {
            if (user != null) {
                IIdentity identity = user.Identity;
                if (identity != null && identity.IsAuthenticated) {
                    return identity.Name;
                }
            }

            return String.Empty;
        }

So, the following statement:

String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)

will evaluate as:

String.Equals("", null, StringComparison.OrdinalIgnoreCase)

which evaluates to false, and, hence, an HttpAntiForgeryException will be thrown.

Why did we get this problem when introducint WIF? Because we now have a ClaimsIdentity Principal as the user in the web application, and we hadn’t bothered populating it with anything but the claims we used in the target application, and, as of now, the Name property was not one of them (or so we thought).

The solution to the problem was to add a Microsoft.IdentityModel.Claims.ClaimTypes.Name claim to the output claims identity in our implementation of SecurityTokenService.GetOutputClaimsIdentity. And suddenly the AntiForgeryToken validates again.

I would say that this should be categorized as a bug in the MVC framework, it is an edge case setting the Current Identity’s User Name to null, however, it should still have worked 🙂

Posted in .NET, C#, MVC, WIF | 4 Comments

X509Certificate2Collection is picky…

Just a quickpost. I noticed the other day, experimenting with WIF, that the X509 Certificate Store is extremely picky on the Distinguished name when trying to locate a certificate in the certificate store. My certificate’s Distinguished name shows in the Certificate store as the following:

CN = mycomputer-wif-sign
OU = Flaktveit
O = MyCompany
S = Bergen
C = NO

The parts of the DN are separated by line breaks, and the equal signs are surrounded by white space. So you wouldn’t think it mattered an awful lot how you would provide this as a key to X509Certificate2Collection.Find

? store.Certificates.Find(findType, "CN= mycomputer-wif-sign, OU= Flaktveit, O= MyCompany, S= Bergen, C= NO", false).Count
0
? store.Certificates.Find(findType, "CN=mycomputer-wif-sign,OU=Flaktveit, O=MyCompany, S=Bergen, C=NO", false).Count
0
? store.Certificates.Find(findType, "CN=mycomputer-wif-sign, OU=Flaktveit, O=MyCompany, S=Bergen, C=NO", false).Count
1

Notice that the only one of the three that actually returns the certificate, is the one that has no whitespace surrounding the equal signs, and exactly one blank after the commas.

Please, dear X509Certificate2Collection, give me some slack? How about using some String.Split and String.Trim magic to make this work?

Just a small rant 😉

Posted in .NET, C#, WIF | Leave a comment

Windows Identity Foundation and date formats

I am starting preparation for a WIF-based security solution, and when playing with the STS that is created when you click “Add STS reference”, and “Add new STS project” in Visual Studio, I came across a curious thing.

I was trying to add a couple of more claims to my claims set, and among these were the AuthenticationInstant claim. All the claim types in Microsoft.IdentityModel are strings, so I naïvely converted “DateTime.Now” to a string and thought that was going to do the trick.

FormatException: String was not recognized as a valid DateTime.]
   System.DateTimeParse.ParseExactMultiple(String s, String[] formats, DateTimeFormatInfo dtfi, DateTimeStyles style) +3602766
   System.DateTime.ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) +49
   Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler.CreateAuthenticationStatement(SamlSubject samlSubject, AuthenticationInformation authInfo, SecurityTokenDescriptor tokenDescriptor) +1132
   Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler.CreateStatements(SecurityTokenDescriptor tokenDescriptor) +215
   Microsoft.IdentityModel.Tokens.Saml11.Saml11SecurityTokenHandler.CreateToken(SecurityTokenDescriptor tokenDescriptor) +114
   Microsoft.IdentityModel.SecurityTokenService.SecurityTokenService.Issue(IClaimsPrincipal principal, RequestSecurityToken request) +1580
   Microsoft.IdentityModel.Web.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(SignInRequestMessage requestMessage, IPrincipal principal, SecurityTokenService sts, WSFederationSerializer federationSerializer) +667
   Microsoft.IdentityModel.Web.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(SignInRequestMessage requestMessage, IPrincipal principal, SecurityTokenService sts) +42
   _Default.authButton_Click(Object sender, EventArgs e) in d:\src\WifTest\BusinessApp_STS\Default.aspx.cs:109
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +141
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +149
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +39
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +37
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +87
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4226

Boom. No luck. OK, Try more of the standard .NET ToString date formats (http://msdn.microsoft.com/en-us/library/az4se3k1.aspx), but without any luck.

dotPeek to the rescue. After digging through the Microsoft.IdentityModel dll for some minutes, I come across the following class:

// Type: Microsoft.IdentityModel.DateTimeFormats
// Assembly: Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
// Assembly location: C:\Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5\Microsoft.IdentityModel.dll
 
namespace Microsoft.IdentityModel
{
  internal class DateTimeFormats
  {
    internal static string[] Accepted = new string[16]
    {
      "yyyy-MM-ddTHH:mm:ss.fffffffZ",
      "yyyy-MM-ddTHH:mm:ss.ffffffZ",
      "yyyy-MM-ddTHH:mm:ss.fffffZ",
      "yyyy-MM-ddTHH:mm:ss.ffffZ",
      "yyyy-MM-ddTHH:mm:ss.fffZ",
      "yyyy-MM-ddTHH:mm:ss.ffZ",
      "yyyy-MM-ddTHH:mm:ss.fZ",
      "yyyy-MM-ddTHH:mm:ssZ",
      "yyyy-MM-ddTHH:mm:ss.fffffffzzz",
      "yyyy-MM-ddTHH:mm:ss.ffffffzzz",
      "yyyy-MM-ddTHH:mm:ss.fffffzzz",
      "yyyy-MM-ddTHH:mm:ss.ffffzzz",
      "yyyy-MM-ddTHH:mm:ss.fffzzz",
      "yyyy-MM-ddTHH:mm:ss.ffzzz",
      "yyyy-MM-ddTHH:mm:ss.fzzz",
      "yyyy-MM-ddTHH:mm:sszzz"
    };
    internal static string Generated = "yyyy-MM-ddTHH:mm:ss.fffZ";
 
    static DateTimeFormats()
    {
    }
  }
}

And then, I ask myself the following two questions:

  1. Why, why, why couldn’t Microsoft use some of the standard date formats when implementing this?
  2. And, if this was impossible, how about actually exposing these date formats, at least the “Generated” string, so that others can use it without having to dig through disassembled code and duping the format to application code.

Well, just a little rant. I hope to have some more blog posts coming up, both on WIF, and a few inspired by NDC2011, which I had the pleasure of attending last week.

Posted in .NET, C#, Uncategorized, WIF | Tagged , | 1 Comment

SAXParser and external DTDs

I am playing a bit with Android in the evenings nowadays, and as a part of this, I needed to parse an HTML file for displaying some of the information. I first used DOM to extract all relevant nodes from the HTML, and then processed the nodes.

Then I thought: “Let’s be a bit cleverer…” We’ll use SAX, because then we don’t have to download the whole file to start processing it. As a sidenote, I am only interested in the first N lines of the file. I’ve used SAX in Python before, and it was blazingly fast. Processed 32.000 files in just a few seconds.

Enter javax.xml.parsers.SAXParser.

After just about an hour or so rewriting my XML parser to use SAX instead of DOM, I was very happy. Time to test. Used a small XML fragment containing a bit more than the number of elements I need. Parsed in a fraction of a second. Happy.

Ok, let’s test this on some real data. I go on the web, save a copy of a relevant webpage, and start unit testing. Extreme slowness. Hmmm…. Strange. Could it be some issues with the FileInputStream reading the whole file before starting parsing? The file was just below 100K, so I couldn’t understand why it could be so slow even though it read the whole file before starting parsing.

After a few hours googling, printing out debug messages, etc, I looked at the HTML source. There is a DTD definition in it…

<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">

Long shot… Comment out that line. The parsing is performed in under a second…

Seems like the SAX parser used is trying to download the dtd from wapforum.org, but failing, for some reason. After more googling and experimenting with saxParserFactory.setValidating(false), without any luck, I came across a few comments on a few blog posts mentioning the following feature:

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

That did the trick. The parsing time is down to below a second again. Moving onwards into the dark corners of Android development…

Posted in Android, Java | Leave a comment

VB.NET If(condition, truePart, falsePart) != C#’s ?:

The ternary If operator (http://msdn.microsoft.com/en-us/library/bb513985.aspx) was new in VB.NET 2.0 (VS2008). However, I don’t use it much, and I have counted on it being equal to the ?: operator in C#. Today I discovered an interesting difference.

Consider the following code in C#:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TernaryCsharp
{
    [TestClass]
    public class UnitTest1
    {

        [TestMethod]
        public void TestMethod1()
        {
            Int32? valueToSet = null;
            Int32 valueToSetFrom = 0;
            valueToSet = valueToSetFrom != 0 ? valueToSetFrom : null;

            Assert.AreEqual(null, valueToSet);
        }
    }
}

and the following code in VB.NET:

Option Strict On
Option Explicit On

<TestClass()>
Public Class UnitTest1

    <TestMethod()>
    Public Sub Test_That_Value_Is_Set_To_Nothing_With_If()
        Dim valueToSet As Integer? = Nothing
        Dim valueToSetFrom As Integer = 0
        valueToSet = If(valueToSetFrom <> 0, valueToSetFrom, Nothing)

        Assert.AreEqual(Nothing, valueToSet)
    End Sub

    <TestMethod()>
    Public Sub Test_That_Value_Is_Set_To_Nothing_Directly()
        Dim valueToSet As Integer? = Nothing
        Assert.AreEqual(Nothing, valueToSet)
    End Sub

End Class

The code looks equivalent, right? Is it? I’m afraid not. The intent is to set the variable valueToSet to null/Nothing in both VB and C#. However, this is not what happens. The code in VB compiles fine, but when you run it, the variable valueToSet is set to 0, not null.

In C# the code doesn’t even compile, and reports that there is no implicit conversion between ‘int’ and ‘null’. This is fine. The arguments to ?: need to be convertible to one another. The compiler tells me that I can’t rely on this to work. VB, however, gives the impression that this is going to do what I want, but does quite the opposite…

Whether this is a bug or indeed intended behaviour is left as an exercise to the VB.NET team at MS.

Observe also that the second unit test, which sets the Integer? value to Nothing in VB.NET, behaves exactly as you would expect, and actually sets the value to Nothing.

I rest my case.

Posted in .NET, C#, VB | Leave a comment

TFS2010 – Build including a shelveset

We recently upgraded our TFS server to TFS2010. And there are small bits and bobs that are not 100% equivalent to TFS2008, one of these being that MSBuild 4.0 is used to build the solutions.

MSBuild 4.0 should use the compatibility level specified on the projects when building, however, there are some small gotchas including functions not returning a value on all paths, etc.

However, that is not the topic of this post.

Having performed the changes I expected would make the solutions build on the build server, I would really like to verify that the code would actually build on the build server before checking in. And, voilà. TFS2010 and VS2010 have the solution, right there in the “Queue new build” window:

Queue new build windowSuddenly you can verify that the changes build on the actual build server without checking it in, and fix any potential errors.

This gives developers the opportunity to verify their changes against the checked-in solution, on the build server, running all unit and integration tests, without actually checking in the code.

I like it. A lot.

And, you also have the opportunity of checkin in if the build is successful. Nice.

Posted in TFS | Tagged , | Leave a comment