Rajeeshcv.com

Sharing my knowledge

How web servers identify your session?

I think, you have all created session variables inside an asp.net application. Then how the web server is knows you are the same guy created that session when the successive request goes to the server. Before explain this, we have to think that every request that we sent from a web browser is considered as a new request by the IIS. This is the behavior of every web application i.e. the state less nature. For example if you open a url, first the browser sent a request for the default document. Then the browser parses the HTML response and it sends another set of requests based on the required images, scripts that are included in that page. Below you could see, the different requests that sent by my browser when I opened my blog Image Some think “State less” nature is the biggest drawback of a web application, but in my view this is an advantage because you could distribute your application as you like, because it is not tightly coupled to a particular request. Developing “State aware” application is on of the main challenge involved in any web development. For developing a “State aware” application, you don’t need to do much. All most all server side scripting languages supports creation of “Session” variables. Session variables are created in the memory location where your web server runs and it is created per user basis. That means, User1 creates a session variable but User2 can’t modify that particular session variable, he can only work with the session variables he created. Ok thats about session, but how your server identify this users? [ad#ad-2] I will explain that with an example, for that I have created a simple website with one page and I have placed two buttons in that page. When user click on the “Button1″, a session variable is set. If the user click on the “Butto2″, the value from session variable is written back on the page using Response.Write(..) method. Image When I first hit this url, the HTTP headers of request and response looks like below Image Image This request simply means, we are looking for a “Default.aspx” page and the web server is returning that page. Ok. Now we click on “Button 1″, at that time if you look at the HTTP request header Image from that header you could understand that, it is a simple form post header. As I said earlier, we are setting a session variable. Because of that, your server will create id for identifying your session and that value is send back as a cookie to browser through response header. Below is the response header of “Button 1″ click Image In that response, you could see a “Set-Cookie” header with cookie name “AS.NET_SessionId” with some value is sent back to the browser. From now ownwards, each an every request send from that page will have this cookie value. To show that, we click on the “Button 1″ again, see below is the request header for that Image There your browser passes the “AS.NET_SessionId” cookie value to the server thorugh each and every request. With this cookie value only your server indentify the sessions, Hope you have got some idea about this. Here I have used “Fiddler” tool for intercepting these request/response. If you need this tool please goto http://www.fiddler2.com/fiddler2/ and download it.

Multiple visual studio development servers while debugging

You might have noticed that when you start debugging an ASP.NET web application, it start more than one visual studio development servers and in the system tray you see something like this

Mutiple_development_server

This happens when your solution contains more than one web application, setting one as the StartUp project is not going to help..

The reason for this is - by default any web application is set to start when we trigger the debugging process in visual studio. We need to disable that auto start feature so that only one visual studio development server is getting started when we are debugging.

These are the steps for disabling it

  1. Select the web project which you don’t want to start
  2. Go to the properties window (Shortcut – press F4)
  3. Set “Always Start When Debugging” to False

Disable_Start_When_Debuggin

This is how you could do it in Visual studio 2010, I hope the same applies to Visual studio 2008 too. Now if you start debugging, you will see only one development webserver.

Hope this helps


Integrating BrowserID In To Your ASP.NET MVC Application

BrowserID is a decentralized identity system which verifies the ownership of an email address in a secure manner, without the use of any application specific authentication mechanism. Which means, you don’t need to provide an login forms in your application, instead use BrowserID feature.

BrowserID

I am not going to explain in detail about this, but you can follow the links below to know more about it

I have created demo application to show how it could be integrated into ASP.NET MVC (it could applied to ASP.NET Forms also) application.

You can see the demo app here - http://nbrowserid.apphb.com/.
Code for this is hosted in https://github.com/cvrajeesh/NBrowserID

 

How the Demo Application works

In this demo Secret page link can only accessed if you have logged into the application. In order to login I have provided a “Sign in” button, like most of the applications, but when you click on it. It will open a pop-up window (make sure you have disable pop-up blockers), which is a URL from https://browserid.org not from my application. If you don’t have a BrowserID create one, otherwise enter the Email address and Password. Then follow the steps and finally click on the “Sign” in button, which log you into the application and from there you can access the Secret page link.

How to implement this in ASP.NET MVC

Enable BrowserID in your application -

Include the BrowserID javascript file https://browserid.org/include.js to your master page,

<script src="@Url.Content("https://browserid.org/include.js")" type="text/javascript"></script>

Identify the User -

Instead of displaying a login form on your site which takes a username and password, it uses the BrowserID JavaScript API when the user clicks your sign-in button. For that I have added the below script to the _LogOnPartial.cshtml which comes with the ASP.NET MVC application you have created

$(document).ready(function () {

$('#login').click(function () {
    navigator.id.getVerifiedEmail(gotVerifiedEmail);
});
.....
.....

});

 

Upon a successful sign-in, you'll be called back with an assertion, a string containing a signed claim that proves the user is who they say they are. Which is passed to a method called “gotVerifiedEmail”

// a handler that is passed an assertion after the user logs in via the
// browserid dialog
function gotVerifiedEmail(assertion) {
    // got an assertion, now send it up to the server for verification
    if (assertion !== null) {
        $.ajax({
            type: 'POST',
            url: '/Account/LogOn',
            data: { assertion: assertion },
            success: function (res, status, xhr) {
                if (res != null) {
                    loggedIn(res.email);
                }
            },
            error: function (res, status, xhr) {
                alert("login failure" + res);
            }
        });
    }
}

 

Which then sends a POST Request to the LogOn method on the Account controller, for verifying the assertion is correct or not. If it is a verified correctly, we will set up a forms authentication cookie so that ASP.NET feels that user has logged in to the application. Then returns the Email address back.

[HttpPost]
public ActionResult LogOn(string assertion)
{
    var authentication = new BrowserIDAuthentication();
    var verificationResult = authentication.Verify(assertion);
    if (verificationResult.IsVerified)
    {
        string email = verificationResult.Email;
        FormsAuthentication.SetAuthCookie(email, false);
        return Json(new { email });
    }

    return Json(null);
}

 

In order to do the verification, we post the assertion to the URL provided by the Identity Authority itself (https://browserid.org/verify in this case), which will give a valid response if it is valid. The Verify method looks like this

public VerificationResult Verify(string assertion)
{
    JObject verificationResult = this.GetVerificationResult(assertion);
    string email = "";
    bool verified = false;

    if (verificationResult != null && verificationResult["status"].ToString() == "okay")
    {
        email = verificationResult["email"].ToString();
        verified = true;
    }

    return new VerificationResult {Email = email, IsVerified = verified };
}

/// <summary>
/// Gets the verification result from Identity Authority.
/// </summary>
/// <param name="assertion">The assertion.</param>
/// <returns></returns>
private JObject GetVerificationResult(string assertion)
{
    // Build he request
    var req = (HttpWebRequest)WebRequest.Create(IdentityAuthorityVerificationUrl);
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";

    if (HttpContext.Current == null)
    {
        throw new NullReferenceException("HttContext is null. Please make sure that, your application is running in a web scenario");
    }

    // Build the data for posting
    var payload = string.Format("assertion={0}&audience={1}", assertion, HttpContext.Current.Request.Headers["Host"]);
    byte[] payloadInBytes = Encoding.UTF8.GetBytes(payload);
    req.ContentLength = payloadInBytes.Length;

    var dataStream = req.GetRequestStream();
    dataStream.Write(payloadInBytes, 0, payloadInBytes.Length);
    dataStream.Close();

    JObject result = null;

    var res = req.GetResponse();
    dataStream = res.GetResponseStream();
    if (dataStream != null)
    {
        var responseData = new StreamReader(dataStream).ReadToEnd();
        res.Close();
        dataStream.Close();
        result = JObject.Parse(responseData);
    }else
    {
        res.Close();
    }

    return result;
}

 

Hope this will help you to setup an authentication system to your application very easily and in a more secure way.

Demo: http://nbrowserid.apphb.com/
Code: https://github.com/cvrajeesh/NBrowserID


Web Usability&ndash; avoid an extra page load with OpenSearch.

Now a days most of the websites, blogs or any applications that are on internet will have a search functionality which is great!!!. Before the Omnibox concept was introduced by google chrome, if we want to search something in google, as a user I need to go to www.google.com and type the search query. After the introduction of Omnibox, user don’t need to open the google website instead you could do the search from the address bar itself. From the usability point of view, it is a great functionality IMHO.

From the point of google search application, they have done it smartly. As a web developer how could you provide the same usability feature to your own website. Some of the website I frequently visits has done like this.

http://www.stackoverflow.com 

clip_image001

If you are in google chrome, after you type the stackoverflow.com a message will be displayed on the address bar saying that “Press Tab to search Stack Overflow”. If you press tab, you can directly type the search query in the address bar itself and pressing enter will show the results. This basically allows you to do a quick search, instead of going to the website and finding the search box and pressing search button(a long process is it? Smile)

Recently I was working on a hobby project called http://www.ifscfinder.com , which is a website were you could search for a “Indian Finacial System Code” of any banks in India. It simply provide a search box where user could enter the Bank/Branch name and it will list the banks that matches the  query.  So I wanted to have the same feature like stackoverflow in my ifscfinder too.

After googling for sometime, I found about the opensearch which helps to achieve this functionality. You could read more about opensearch from here http://www.opensearch.org

What I had do was, create an xml file(OpenSearch description document), it will have URL format which needs to be called when user enter a search query. ifscfinder xml file looks like this

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
  <ShortName>IFSC Finder</ShortName>
  <Description>Search IFSC: Find  Indian Financial System Code of a Bank</Description>
  <InputEncoding>UTF-8</InputEncoding>
  <Url type="text/html"
       template="http://www.ifscfinder.com/Search?q={searchTerms}"/>
</OpenSearchDescription>

After this is created, I upload it the website. In order for the browser to sense whether my website opensearch, I had to add link tag to the head element

<link rel="search" type="application/opensearchdescription+xml" title="IFSCFinder.com" href="/opensearchdescription.xml" />

With this ifscfinder has got a nice quick search option in google chrome

clip_image001[9]

clip_image002

Firefox also detect the opensearch , which mean you could add this site to the search engine list in firefox

 image

IE9 doesn’t care about this at all(don’t know why!!!)


How to move directories across SVN repositories

Recently we were restructuring our project repositories, where I had to move a project from it’s own repository to another repository.

When do a move under SVN you need to make sure that the history is not lost, so I will explain two common scenarios and how you could do the SVN move

Scenario 1 - Moving files or directories with in a SVN repository


Below is a screen shot of my existing repository and I want to move the configuration directory to the project  directory without loosing the history.

Screen1

First of of all this will work only for the versioned items, so please commit your changes to the directory you want to move before doing this. The steps explained below assumes that you are using Tortoise SVN

Here are the steps

  1. Right click on the directory you want to move
  2. Drag and drop on to the directory where you want to move this.
  3. Choose the “SVN Mover Versioned item(s) here” item from the context menu.
    Screen2
  4. Now commit the changes back to the repository.

Don’t forget to uncheck “Stop on copy/rename” option in the “Log messages” dialog if you are trying to see the history of the moved directory.

Screen3

 

Scenario 2 – Moving directories across SVN repositories

 

In this case I want to move Project directory to another repository “Repo2”

The first technique I have mentioned will work only if the source and target are under same repository, but in some cases you have to move the directories across different SVN repositories. This cannot be done from a SVN client slike TortoiseSVN, you need o use the utilities that comes with SVN.

Follow these steps

  1. Dump the repository to a file using the svnadmin tool – e.g. svnadmin dump c:\Repositories\Repo1 > Repo1file
  2. Now load the dumped filed into the target repository – e.g. svnadmin load c:\Repositories\Repo2 < Repo1file

Here is the full syntax for svnadmin tool

$ svnadmin dump --help
dump: usage: svnadmin dump REPOS_PATH [-r LOWER[:UPPER] ] [--incremental]

Dump the contents of filesystem to stdout in a 'dumpfile'
portable format, sending feedback to stderr. Dump revisions
LOWER rev through UPPER rev. If no revisions are given, dump all
revision trees. If only LOWER is given, dump that one revision tree.
If --incremental is passed, then the first revision dumped will be
a diff against the previous revision, instead of the usual fulltext.

Valid options:
-r [--revision] arg : specify revision number ARG (or X:Y range)
--incremental  : dump incrementally
--deltas   : use deltas in dump output
-q [--quiet]  : no progress (only errors) to stderr


Attach to Any ASP.NET Web Server from Visual Studio in One Click

This is an update to my previous blog post Attach to Visual Studio Development Server with One Click.

The Visual Studio Macro from previous article doesn’t support IISExpress or IIS; it only supported the Visual Studio Development Server, more over it doesn’t detect latest Development Web Server “WebDev.WebServer40.exe”.

Now I have updated the Macro so that it will automatically detect the Web Server setting from the project properties and attach it accordingly.

Below is the code for the new Macro, I think it is self-explanatory

Public Sub AttachToWebServer()
    Dim attached As Boolean = False
    Dim project As EnvDTE.Project = GetStartupProject()

    If (project Is Nothing) Then
        MsgBox("Couldn't find a web project that can be attached")
        Return
    End If

    attached = AttachToProcess(project)

    If (Not attached) Then
        MsgBox("Couldn't attach to the process")
    End If
End Sub

Private Function GetStartupProject() As EnvDTE.Project
    Dim startUpProject As String = DTE.Solution.Properties.Item("StartupProject").Value

    For Each currentProject As EnvDTE.Project In DTE.Solution.Projects
        If currentProject.Name = startUpProject Then
            Return currentProject
        End If
    Next
    Return Nothing
End Function

Private Function AttachToProcess(ByVal project As EnvDTE.Project) As Boolean
    Dim serverProcessNamePattern As String
    ' Using either IIS express or IIS
    If project.Properties.Item("WebApplication.UseIIS").Value = "True" Then
        ' Using IIS Express
        If project.Properties.Item("WebApplication.DevelopmentServerCommandLine").Value.ToString().Length > 0 Then
            serverProcessNamePattern = ".*iisexpress.exe"
        Else ' Real IIS
            serverProcessNamePattern = ".*w3wp.exe"
        End If

    Else ' Assume development web server
        serverProcessNamePattern = ".*WebDev.WebServer\d+.EXE"
    End If

    Return AttachToWebServer(serverProcessNamePattern)

End Function

Private Function AttachToWebServer(ByVal serverProcessNamePattern As String) As Boolean

    Dim attached As Boolean = False

    For Each process In DTE.Debugger.LocalProcesses
        If (Regex.IsMatch(process.Name, serverProcessNamePattern)) Then
            process.Attach()
            attached = True
            Exit For
        End If
    Next

    Return attached
End Function

Read my previous article Attach to Visual Studio Development Server with One Click to understand how we can add this Macro as command to the Visual Studio toolbar.