Sunday 29 December 2013

Azure Active Directory and MVC application

The ASP.NET Web Application template in Visual Studio 2013 comes with a new feature that allows us to quickly set up basic wiring required for the web application’s authentication and authorization to work against different authentication options – No Authentication (that’s simple!), Individual User Accounts (which was essentially already present in ASP.NET MVC4 template of Visual Studio 2012), Windows Authentication (that’s simple, again) and Organizational Accounts (which promises to make the application work against Office 365, Active Directory or Windows Azure Active Directory).

Authentication options

Authentication options 2

“Organizational Accounts” option is something that i had not tried out before. So I thought of giving it a try and it did not turn out all that pleasant (for me, at least).
I have an Windows Azure account which comes with a default Active Directory. It took me couple of minutes to figure out the actual domain of the default active directory (I did not locate any place that specifies that domain name for the directory). It is actually pretty simple – <yoursigninemailaddresswithoutdotsanddotcom> @ onmicrosoft.com. You can also find it in the browser’s address bar once you have signed into https://manage.windowsazure.com.

Azure AD Address

So with high hopes, i entered the domain address and clicked the OK button. It launched another windows which asked me to authenticate. So far so good.

Sign in address

I entered the details and the browser window authenticated me and as expected it closed by itself after the authentication was complete.  But then i was presented with an error prompt.

Sign in address error

I checked the errors in event log and there was one interesting thing related to error encountered while querying GraphAPI. I figured this was because i had selected Single Sign On and Read data. If i chose Single Sign On option, then there is no error in event viewer but i still get the error prompt. 

Application: devenv.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Data.Services.Client.DataServiceQueryException
Stack:
   at System.Data.Services.Client.DataServiceRequest.Execute[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Data.Services.Client.DataServiceContext, System.Data.Services.Client.QueryComponents)
   at System.Data.Services.Client.DataServiceQuery`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].Execute()
   at System.Data.Services.Client.DataServiceQuery`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].GetEnumerator()
   at System.Collections.Generic.List`1[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]..ctor(System.Collections.Generic.IEnumerable`1<System.__Canon>)
   at System.Linq.Enumerable.ToList[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]](System.Collections.Generic.IEnumerable`1<System.__Canon>)
   at Microsoft.VisualStudio.Web.AzureAD.ProvisionGraphHelper.GetUser(System.String)
   at Microsoft.VisualStudio.Web.AzureAD.ProvisionGraphHelper.HasProvisionRight(System.String)
   at Microsoft.VisualStudio.Web.AzureAD.ProvisionGraphHelper.AcquireToken(System.String, Boolean ByRef, System.String ByRef)
   at Microsoft.VisualStudio.Web.AzureAD.VsAzureADService.LoginToTenant(System.String, Boolean ByRef, System.String ByRef)
   at Microsoft.VisualStudio.Web.Project.AuthenticationDialogViewModel.BeforeCloseDialogByClickYes(Microsoft.VisualStudio.Web.AzureAD.Contracts.IVsAzureADService, Microsoft.VisualStudio.Web.AzureAD.UrlChecker, System.Action`1<System.String>)
   at Microsoft.VisualStudio.Web.Project.AuthenticationDialogWindow.OkAuthenticationButton_Click(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject, System.Windows.RoutedEventArgs, System.Windows.RoutedEvent)
   at System.Windows.UIElement.OnMouseUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs)
   at System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr, System.Windows.Input.InputMode, Int32, System.Windows.Input.RawMouseActions, Int32, Int32, Int32)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr, Boolean ByRef)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)


And then i found another interesting thing. Once I clicked OK on the error prompt, the Create ASP.NET Web application wizard became useless –> You can choose any other option (I switched my selection to “No Authentication”) but it kept on restarting the Visual Studio.

Sign in address error 2

And here is the event log entry:

Application: devenv.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException
Stack:
   at System.Windows.Window.set_DialogResult(System.Nullable`1<Boolean>)
   at Microsoft.VisualStudio.Web.Project.AuthenticationDialogWindow.OkAuthenticationButton_Click(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs)
   at System.Windows.Controls.Primitives.ButtonBase.OnClick()
   at System.Windows.Controls.Button.OnClick()
   at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject, System.Windows.RoutedEventArgs, System.Windows.RoutedEvent)
   at System.Windows.UIElement.OnMouseUpThunk(System.Object, System.Windows.Input.MouseButtonEventArgs)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate, System.Object)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(System.Object, System.Windows.RoutedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(System.Object, System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject, System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs)
   at System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs, Boolean)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs)
   at System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr, System.Windows.Input.InputMode, Int32, System.Windows.Input.RawMouseActions, Int32, Int32, Int32)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr, MS.Internal.Interop.WindowMessage, IntPtr, IntPtr, Boolean ByRef)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)


So I reverted to an older technique that made my ASP.NET website work with my Azure Active Directory. I used Azure management portal to add an application to my AD. I called it AzureADTesting and added my application’s URI and URL (I kept both as same https://localhost:44300/).

add applications
Copied the Federation Metadata document URL.

Azure AD Testing

Created an standard website in Visual Studio 2012 and used “Identity and Access Tool” for Visual Studio 2012 to point it to the Federation metadata endpoint of my Azure AD. It makes the required changes in web.config and adds necessary assembly references. Now when you run the web application, it redirects to Azure AD for authentication. Remember, you can not use your Microsoft Account to login.
Live account error

Users have to be in User role in AD. It is easy actually, you can create a new user in the AD and use the credentials to login.

Create an ASP.NET Web application in Visual Studio 2013 with “No Authentication” option. I used the same application name as i used when creating the ASP.NET MVC4 application.

Copied the web.config to new application from old application. Copied “System.IdentityModel.Tokens.ValidatingIssuerNameRegistry” assembly from the Packages folder from application created in step # 3 to new application and added a reference. That’s it. You are set now. It should work for you.
In order to verify that application was indeed signing in users using AD, I modified the Index view of Home controller and it showed the email address of the user in Name.

Change to Index view of Home controller

Email address

I will spend some more time on finding out the real reason why the same AD is not working with the default template of VS 2013. May be it is a known issue or may be i am missing something.

Thursday 26 December 2013

Source code structure regeneration from .NET assembly

Have you ever run into a scenario where you are presented with an assembly from Production or UAT environment for analysis and also told that this assembly has been present on Production since the time our company had its website launched and the vendor who created the application to us forgot to give us the code for that? I have run into this kind of scenario and i know for sure that some of my colleagues and friends have run into similar situations too.

Of course, we have the option of (hoping that they are not out of business by now) going through the ledgers and bills to find out the work order details, find their current email address and phone number and contact them for the code base. Chances are that they have shown little interest in retaining the code base of what they did 10 years ago. 

Well, the assemblies in question are .NET assemblies you have few more options - use a tool to regenerate the code from the assembly. 

Reflector used to one of the best free .NET tools available but it no longer available as free.

DotPeek is another free tool available that has pretty much all the functionality that is required to regenerate the code. One of the cool features is that it allows to create a project from an assembly and arranges class files in such a way that folder structure follows the namespace hierarchy (goodness that we may need!!) and one file has one class only.

For example : I created simple C# console application, ConsoleApplication1 which only one file Program.cs and it has some classes in different namespaces.


I compiled the application in release mode, added the assembly to dotPeek application and selected the option "Export to Project":


It creates the project which looks like following (notice the nice structure). 


The only sad (if i may say so) part is that it can does not allow generating code for multiple assemblies together.

Sunday 22 December 2013

Testing it all the way

I have always believed in the fact that developers are testers as well and that QA folks are additional pair of eyes who ensure that nothing is missed out. Developers should be testing their code to the point that they have high level of confidence if it comes down to applying their code change to a different environment by skipping BVTs.

This brings me to my main point which is "how do you ensure that your application is well tested" before it reaches in the treacherous hands of QA guys who seem to make everything fail just by touching it. Generally there are two ways that developers use to test the application:

1. Manual testing: This is pretty useful when developer is working on user interfaces. There are things that are hard to automate when it comes to user interfaces - be it XAML based such as WPF, Silverlight or HTML based such as web pages or just simple Windows Forms applications. Few of the things that I prefer to test in the user interface are -

  • Different resolutions: Users may be using the application on high resolution screens e.g. 1920x1080 or on projectors, TV screen which may not support any resolution higher than 1024x768. As a developer, you need to ensure that application works well in all the supported cases.
  • Different devices: Users may be using a tablet, laptop, desktop computer, phone. Some devices may be running on battery and that may require you to keep heavy calculation on server.
  • Different browsers
  • Different culture settings: Good for ensuring that all data in different culture fits in the screen etc.
  • Different type of data: Generally the domain model is separated from the model used by user interfaces and it is possible to have a data type mismatch. In such cases you need to ensure that data is valid e.g. input boxes should not allow users to enter text values if only numerals are allowed.
  • Different amount of data: One such case is when you have a grid then does it starts to show scroll bar if data does not fix in available screen area.
  • <>

2. Automated testing (Unit testing): It has wider impact because it can lead to identifying the design limitations in the application as well as implementation flaws. The greatest advantage of automated unit testing is that you can feel confident about identifying the areas of the application that may be broken if we end up changing a component or behavior e.g. database schema etc. Any well designed application should allow testability of most of the aspects the implementation logic in programmatic manner. There are many strategies available that can be used but all of this begins with a mindset that targets to achieve high level of test coverage - just achieving code coverage is not the right target though because that can be done in misleading ways and raise false hopes. 

Test Driven Development (TDD) has been preferred way and I myself have tried to promote it within the different teams i worked with - sometimes developers accept it and sometimes they shrug their shoulders because their timelines are too tight :). The approach of Red -> Green -> Refactor is a very helpful one and should be used if timelines and other factors permit.

  • Components should be loosely couple - preferably interface driven. Use Inversion of Control (IoC) technique with Dependency Injection (DI) containers (e.g. Unity container to ensure that interface implementations are replaceable when running the tests - this can help in reducing dependency on external systems such as database hosted on SQL Server, a third party WCF service which is not available for purpose of development testing etc.
  • Use Fakes? There are frameworks like Moq, Microsoft Fakes etc. which allow providing predetermined simulated implementation for components and methods. My personal preference is to avoid these unless there is no way left.
  • If application does not allow testing of a certain feature, then there is some issue with the design and it needs to be looked at before it is too late. Unit tests should be the starting point of any implementation and need to written in such a way that they add value in terms of functionality testing and are not written to meet certain coverage criteria. e.g. test cases should be written for cases when method is invoked with a) null values b) illegal values c) application state that may lead to business rule violation i.e. possibility of duplicate data d) exception scenario and the error messages returned by those scenario i.e. ensure that application returns contextual error message e) other scenarios.
  • There is some level of design required when writing test cases as well because in almost all cases we would want the unit tests to be re-runnable - tests should pass repeatedly with each execution which may mean that you have to chose the data carefully e.g. either use a Fake data access layer or prepare database layer in such a way that it works all the time (populate with seed data before test execution and remove it once test runner has finished running all the tests).
  • If the aspects of application are testable then implementing advanced testing scenarios becomes easy e.g. this
  • It makes release management easy as well because it can help you identify which version of component A works with which version of component B.