Will be speaking in three events in April – Join and Learn

Hello All,

In this month (April’13), I’ll be speaking in three events on ASP.NET, WCF, SQL Server 2012. Join these sessions with me and learn the technology you are interested in. Event details are

Simple steps to improve performance of ASP.NET Applications Significantly

This is webcast and you can join from anywhere. Just require a PC and internet connection. Register at the following site and you’ll get the attendee details

http://kolkatageeks.com/WebCast.aspx

Timing details – 07th April 2013, 2-3PM

N-tier architecture using WCF and ASP.NET and ASP.NET MVC

This will offline event and organised by C3 Corner at Noida on 13th April 2013. Please get the details from below link.

Learn WCF With C# Corner

Exciting feature for SQL devs in SQL 2012

This will be a offline event and organized by Delhi User Group and will be taking Place in Microsoft Office Gurgaon on 20th April 2013.

To connect with Delhi User Group (Group), join it on facebook at below link and get updated on all the events organised by DUG and join that interest you.

Connect with Delhi User group

Join with me on these events and you’ll also get to hear other Speakers in these event. Hope you all learn and enjoy.

Thanks,
Brij

Learning ASP.NET Signal R – Part 2

This is second post in the series on ASP.NET SignalR. You can access first post from the following link

Learning ASP.NET SignalR – Part 1

In this post, we’ll examine, How SignalR works on various environments. We’ll try dig it out with the help of an example.

First let me know, when you require real time update your UI?
A chat application?

Right. But it’s not the chat application only, you can use it at many other scenarios like any real time data requirement, collaborative applications, Real time loggers, Real Time dashboards, Games, Stock market, Real time news, Live match feeds etc… and many more.

But for this analysis, we’ll use chat application. And will discuss other scenarios in my next post.

So let’s create an chat sample application.

Let me tell you my environment. I am using VS2012 Pro for this development and my OS is Windows 8.

So to create a simple chat application. Start  File -> New Project-> ASP.NET Empty Web Applications and say name it SignalRChat

Now Tools -> Library Package Manager ->Package Manager Console.

A console will be opened and put the following command

install-package Microsoft.AspNet.SignalR

and Press enter. Wait for few seconds, it will install the SignalR and will download all the required libraries in your project. Add Global.asax in your project and add the following line in your Application_Start() method

RouteTable.Routes.MapHubs();

This is required to add the default hub route and it will be added at Client side. Now lets add a class say named ChatHub which implements Hub Class and it is available under the namespace Microsoft.AspNet.SignalR . Now add a method as

 public void Distribute(string name, string message)
        {
            // Call the broadcastMessage method to update all clients.
            Clients.All.broadcastMessage(name, message);
        }

Now it’s time add an HTML page. Let’s add Chat.htm. On this page add the following scripts and hub class

  <script src="/Scripts/jquery-1.8.2.min.js" ></script>
  <script src="/Scripts/jquery.signalR-1.0.0.js"></script>
  <script src="/signalr/hubs"></script>

Update the the version of the scripts file that is available in your solution. Now add the following javascript code in your HTML file,

  <script type="text/javascript">
         $(function () {
             // Declare a proxy to reference the hub.
             var chat = $.connection.chatHub;
             // Create a function that the hub can call to broadcast messages.
             chat.client.broadcastMessage = function (name, message) {
                 // Html encode display name and message.
                 var encodedName = $('<div />').text(name).html();
                 var encodedMsg = $('<div />').text(message).html();
                 // Add the message to the page.
                 $('#discussion').append('<li><strong>' + encodedName
                     + '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
             };
             // Get the user name and store it to prepend to messages.
             $('#displayname').val(prompt('Enter your name:', ''));
             // Set initial focus to message input box.
             $('#message').focus();
             // Start the connection.
             $.connection.hub.start().done(function () {
                 $('#sendmessage').click(function () {
                     // Call the Send method on the hub.
                     chat.server.distribute($('#displayname').val(), $('#message').val());
                     // Clear text box and reset focus for next comment.
                     $('#message').val('').focus();
                 });
             });
         });
    </script>

If you see the above script, first it creates the reference of HUB Class. This is actually, required to perform all the steps. It adds a method which receives the chat message.  It receives the message at run time and update the UI accordingly. And It also adds a event on the send button and call the distribute method on the server to broadcast the message. One thing, you keep in mind that it has a check whether the HUB is started or not. And Click event of Send button will be fired only if HUB is ready or it is ready to accept the request. Also we require to add some HTML Controls. It could be as

  <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" />
        <ul id="discussion">
        </ul>
    </div>

So now the code is ready to start. Let’s run the code. Now You’ll be prompt to put name and you can open the same URL on some other browser and starts chatting amongst browsers. So your code is running.

So this is a very simple application of Application. So now I’ll try to run the same application in different environment. Current browser is Firefox19 on windows 8. Let’s visit firebug net tab

FF19Chat

Now if you see the the above first red marked encircled area, there is a negotiation request sent to the server to negotiate the protocol that will be used. Again if you see the next encircled area where it is written transport=websockets  and also a connectionToken is there. It means websockets is supported and it is used here.

Now I am going to run the same application on different environment that has OS WinXP SP3 and IE8. So let’s run, now when see this

SignalRChatIE8

Now if you see here red encircled area, here the transport is foreverFrame. And when I ran this it was working as similar as I ran on Win8 and FF19 it was transport=websockets. Here also you can see the page is getting refreshed.

Now I will show it you on another browser on the winXp3 machine

SignalRChatfirefox15

So here if see here the encircled area and here is the transport is serverSentEvents.

You can see here, as I discussed in my first post in this series, that according to the supported technologies appropriate one is selected  based on the order that was pictorially shown and discussed.

So the whole Idea, in this post to explain you that SignalR provides complete abstraction over technology and you need to use the similar simple API to work on it. You don’t need to care about the underneath technologies and environment.

Now in my next post, I’ll discuss various scenarios, where you can use this technology and make best use of it.

So hope, you must have enjoyed this post a lot.

Thanks,
Brij

Accessing other domain web services via jQuery Ajax (CORS)

Now a days, most of the web developers are working on mainly Client side programming to make the web more responsive, intuitive and user friendly. So avoiding the code behind, accessing the server via Ajax, passing and getting the data in JSON format, generating the DOM elements at Client side etc becoming very common these days and these all prepared the ground for many Client side libraries to come up and that’s what we are seeing now a days.

One of the most popular Client side library, jQuery, provides a lot of wrapper methods for writing quick and easy Client side code. You guys must have used jQuery ajax to initiate a ajax call and passing data to and fro in JSON format. As you must be knowing that XMLHTTPRequest  is the base for all Client side ajax call. All the Client side libraries provides a wrapper over it for making any AJAX call. So I’ll start with an example

I have created an empty web application and added a web page . I also added a jQuery script file. I created one small web method GetRatingValues at code behind that returns a list of numbers (Gave a name called rating). So let’s see the code and get it running

So my aspx code is like

<form id="form1">
<div><input onclick="GetRatingData()" type="button" value="GetRatings" />
<div id="ratingDetails" style="display: none;">
<h1>Available Rating Values</h1>
<div id="ratingValues"></div>
</div>
</div>
</form>

And my javascript code is like

<script type="text/javascript" language="javascript">// <![CDATA[
        function GetRatingData() {
            GetRatingValues();
        }
        function AjaxSucceeded(result) {
            $("#ratingDetails").show();
            $("#ratingValues").html(result.d);
        }
        function AjaxFailed(result) {
            alert('Failed to load');
        }

        function GetRatingValues() {
            $.ajax({
                type: "Post",
                url: "First.aspx/GetRatingValues",
                contentType: "application/json; charset=utf-8",
                data: '',
                dataType: "json",
                success: AjaxSucceeded,
                error: AjaxFailed
            });
        }

// ]]></script>

And my web method at code behind is as

 [WebMethod()]
    public static string GetRatingValues()
    {
        JavaScriptSerializer ser = new JavaScriptSerializer();
        IList ratingList = new List() { "5", "4", "3", "2", "1" };
        string str = ser.Serialize(ratingList);
        return str;
    }

Now if you run the code and Click on the button. It’ll run perfectly fine and page will be displayed as

SamedomainAjaxCall

Now let’s have another scenario. I have added a simple HTML page (Test.html) in my solution and I have added the following script on my aspx page

 function GetHTML() {
            $.ajax({
                type: "GET",
                url: "Test.html",
                success: ShowHTML,
                error: AjaxFailed
            });
        }
        function ShowHTML(data) { alert(data); }
        function AjaxFailed(result) {
            alert('Failed to load');
        }

Now if you run this code. It’ll display the html content of the page. I ran it and it displayed as expected

GetAjaxHTML

Let’s also see the HTTP Headers that I have taken via firebug

HTTP Headers

GetRequest1

Also let’s see the response of the URL

Response

If you see the encircled area in both the above picture they are pointing to localhost.

If you see the URL in both AJAX call they are pointing to same domain. But have you ever tried to initiate an jQuery AJAX call to some other domain .

What I have done here, I am running my application from IIS and I added a domain for Testing (localtest.me) in IIS. So I changed the URL in my AJAX call as

OtherDomainNewBut now if you try to run this code, it would not run. Because now the URL targeting to other domain. Let’s see again the HTTP Headers and response.

GetRequestOther

Let’s see the Response

GetResponseOtherDomainNow if you see here in the above picture the encircled area, both are different and pointing to different domain and didn’t get any result.

But why?

As I already described that every AJAX request is built on XMLHTTPRequest object and XMLHTTPRequest has some security limitation. It follows same-origin policy, it means that any HTTP request using XMLHTTPRequest initiated by a web application, can be processed only if it loaded from same domain/origin. If it requests to any other domain it will not be successful.

But as now we make lots AJAX call and some times to third party web services, it becomes hurdle to our development. To overcome this issue W3C has come up with feature called Cross-Origin Resource Sharing (CORS) which enables cross site data transfer without compromising security. To use this , we require to add few new HTTP headers that allows to add set of other origins/domains and the content type that is required to transfer.

Also let’s understand what is meant by other domain/origin?

If I have a domains like mydomain.com and mydoman1.com so as it is clear from seeing that these are different domain. Similarly subdomains like abc.mydomain.com and xyz.mydomain.com are also considered as from different origin/domain. Also at certain times the url also contains port number so if the port number is different, it also be treated as from different origin.

So as a thumb rule, you can say if the portion of URL before first single slash is different, it would be considered as from different origin and same origin policy would not be applied.

So now, let’s again back to our example. To run our example, we need to add these custom headers.  ASP.NET provides a way to add these new headers by adding some config entry. so I added the following in my web.config

GetConfig

Now if we run the code it runs successfully. Let’s analyse again the HTTP Headers and Response.

GetrequestOtherSuccess

And the Response

GetresponseOtherSuccess

Now if you see the dark encircled area, they are pointing to different domain and yet got the response. But the successful result caused by the thin encircled area in header pic, which is a new header got added. And we made this entry in web.config

But what would happen if I change the URL that I used in my first sample as

 function GetRatingValues() {
            $.ajax({
                type: "Post",
                url: "http://localtest.me/TestCORS/First.aspx/GetRatingValues",
                contentType: "application/json; charset=utf-8",
                data: '',
                dataType: "json",
                success: AjaxSucceeded,
                error: AjaxFailed
            });
        }

And if you run it again, It would not run. because in my last example, I was using Get Request. For Post (type: “Post”)request I can  transfer some data back and forth to server. So here I need to define one more entry in web.config that will add another header in the request as

Postheader ConfigNow after adding it, if you run the code then it’ll run like a charm.

One more point, I’ll make a here that providing * for Access-Control-Allow-Origin is not a good Idea, because it allows to access any other domain URL so it’s if you specify the particular domains here.

Hope you all have enjoyed this post. Do share your feedback.

Thanks,
Brij

The requested content appears to be script and will not be served by the static file handler. : A Solution

Today, I faced one issue while working on one sample . And could not find solution in one go and error shown was not intuitive enough.

First let me share my environment. Windows 8 (64 bit), Visual Studio 2012, IIS8

I created an ASP.NET 2.0 web service using Visual Studio 2012 directly at IIS8. But as soon as, I tried to access my web service via browser I found the following error

ErrorAs you can see from the error, it does not point to any cause.

For this error there could be one issue that IIS is not registered with ASP.NET. So to register it, I opened the command prompt with run as administrator and navigated to the folder C:\Windows\Microsoft.NET\Framework\v2.0.50727. I navigated to framework version 2.0 because I was accessing the ASP.NET 2.0 webservice. Now I required to run the following command

aspnet_regiis -i

But as soon as I run the above command, I faced another error

errorcmd

Later, I found that my Operating System (Windows 8) that I am running is of 64 bit version. So again navigated 64bit version executable and it ran successfully

successfullyRanSo you can see above the message “Finished installing ASP.NET <2.0.50727>”.  Here in the above pic, if you see the red encircled area, I have ran here 64 bit version executable.

Also note, this issue arises only if you installed the IIS after installing Visual Studio.

Hope this would save lot of time of yours.

Thanks,
Brij

Microsoft Windows Identity Foundation Cookbook – Review

Hello All,

In this Post, I am reviewing a book on Windows Identity Foundation by Packt Publishing.

The content of this includes basic to advance topics of Windows Identity foundation. It has full of hands on examples with explanation which can give fair enough knowledge for working with Windows Identity Foundation.

But I feel, It could contain more explanation on the basics of Claims based Authentication, Windows Identity Foundation and some other topics as well. But as a developer, there is enough sample based examples that one can study and so some hands on. Being a developer, It is one of the key point that I need.

So if you have basic knowledge current Authentication and Authorization mechanism and also read n heard a lot about Claim based Authentication. And now if you want to hands on working knowledge then this bo0k will be very helpful for you.

Access control Service (ACS) is main component of Windows Azure and it provides the feature of Authentication and Authorization for Application hosted on Cloud. This book contain step by step examples for working with ACS 2.0.

Also I need to mention the system requirement for working with WIF. These are

  • Microsoft Windows Vista® SP1, Windows 7, Windows Server 2008 (32-bit or 64-bit), or Windows Server 2008 R2 (32-bit or 64-bit)
  • Microsoft Internet Information Services (IIS) 7.0 or 7.5
  • Microsoft .NET Framework 4.0
  • Microsoft Visual Studio® 2010 (excluding Express editions)
  • Windows Identity Foundation

You can get a book from here

http://www.packtpub.com/microsoft-windows-identity-foundation-cookbook/book

Thanks,
Brij

How to access the input control’s data at Server side during Client Callback : A useful trick

Client callback is one way to update the webpage without performing the full page postback. It maintains the Client state while updating the Webpage. During Client callback the webpage runs through modifies version of Page Life Cycle.

The LifeCycle of a page in Client Call Back is  as

Page Lifecycle iin Callback

If you want to learn  more about Client Callback, click here.

But the main drawback of  Client Callback, The input data is not posted from Client to Server. Also,  It does not maintain the view state during partial postback as you can see the Page life cycle of Client callbak it is not saved or SaveViewState event is not fired.

Lets see it with an example.

I have created a simple form to collect some information of an person data. And it has a submit button, which initiates a Callback. As

 <table>
 <tr><td><asp:Label id="lblFName" runat="server" Text="First Name" /> </td>
 <td><asp:TextBox ID="tbFName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblMName" runat="server" Text="Middile Name" /> </td>
 <td><asp:TextBox ID="tbMName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblLName" runat="server" Text="Last Name" /></td><td><asp:TextBox ID="tbLName" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblAge" runat="server" Text="Age" /></td><td><asp:TextBox ID="tbAge" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblMailId" runat="server" Text="Email" /></td><td><asp:TextBox ID="tbEMail" runat="server"></asp:TextBox></td></tr><tr>
 <td><asp:Label id="lblSex" runat="server" Text="Sex" /></td><td><asp:TextBox ID="tbSex" runat="server"></asp:TextBox></td></tr><tr>
 <td colspan="2"><input id="btnCallBack" type="button" value="Submit" onclick="InitiateCallBack();"/></td></tr>
</table>

Server side code is as

public partial class Callback : System.Web.UI.Page,ICallbackEventHandler
{
    string result;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsCallback)
            return;
        //Creating a reference of Client side Method, that is called after callback on server
        String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg",
            "ReceiveServerData", "");

        //Putting the reference in the method that will initiate Callback
        String callbackScript = "function CallServer(arg, context) {" +
            cbReference + "; }";

        //Registering the method
        Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
            "CallServer", callbackScript, true);
    }
    public void RaiseCallbackEvent(String eventArgument)
    {
        string firstName = tbFName.Text;
        //Read other data as well

    }
    public string GetCallbackResult()
    {
        return result;
    }
}

And the client side method is

function InitiateCallBack() {
     //Intiate the callback
     CallServer("",'');
}

// Called after the server side processing is done
function ReceiveServerData(arg, context) {
    //arg: hold the result
    //Updating the UI
    document.getElementById('divCallbacl').innerHTML = arg;
}

After filling this form, I submitted it. Now if you try to access the entered using control’s property, you would not get it.

Let’s dig it more and check the form collection, whether the data is passed from Client to server or not

So as you can see that the data is not passed in form collection

But let’s put the following lines of code in java-script, just before initiating the call for Callback as

 function InitiateCallBack() {
	__theFormPostCollection.length = 0;
        __theFormPostData = "";
        WebForm_InitCallback();

        //Intiate the callback
        CallServer("",'');
}

Now let’s run the code and submit the form as earlier.

Now let’s check the form collection.

What a surprise, we got all the input data in form collection. That’s nice.

Now access the data using control’s property.

and you got it.

Now let’s try to see, what does the extra lines of code does

//This Clear the earlier the old data in form collection.
__theFormPostCollection.length = 0;
//It sets the forms data to empty
__theFormPostData = "";
//This method builds the body of the POST request when the page loads. The body of the page is a string 
//(that is __theFormPostData) filled with the contents 
of the view state and all of the input fields in the form.
WebForm_InitCallback();

But I would suggest to use these line at caution. Use only when you need to collect the update from Page during Callback. If you don’t need to get some data or it is in readonly page, don’t use it it introduce extra overhead to your page and costs at performance point of view.

Hope you  all have enjoyed the post.

Writing asynchronous HTTP Module in ASP.NET 4.5

Today again, I am going to discuss , one of the new features that got enhanced in ASP.NET 4.5. And It is Asynchronous HTTP Module . And it’s going to be very useful if used meticulously.

First Just to give a brief Idea, why Asynchronous HTTPModules are important ?

As we all know, web is stateless. A Web page is created from scratch every time whenever it is posted back to the server. In traditional web programming, all the information within the page and control gets wiped off on every postback. Every request in ASP.NET goes through a series of events.

Every request is served by am HTTP handler and it goes a series of HTTPModules (HTTPPipeline) which can be read, update the request. A lot of features of ASP.NET like Authentication, Authorization, Session etc are implemented as HTTP Module in ASP.NET. Let’s have a view on the Request Processing

ASP.NET Request Processing : HTTPPipeline and HTTPHandler


Now as you can see the request is assigned to a thread T1 from the available threads is thread pool. And the request is passed through several HTTPModules and finally served my HTTPHandler and response is send back with the same thread (T1).

During the entire processing, same thread is engaged in serving  the same request and cannot be used by any another request till request processing completes.  During the request processing if any HTTPModules depends on some entities like I/O based operations, web services, Databases queries etc then it takes long to complete which makes the thread busy for long which makes asp.net thread will not do anything during that duration and will be useless.  In this kind of scenarios the throughput goes down rapidly.

In the above scenario, synchronous HTTPModule can degrade the site performance a lot. So if we can make  HTTPModules as asynchronous  that can increase the through put a lot.  In asynchronous mode, ASP.NET thread get released as soon as the control get passed to another component/module, it does not wait. And the thread becomes available in thread pool and can be used to serve another request. When the component completes its assigned task then it got assigned to new ASP.NET thread which completes the request. The flow can be graphically presented as

Working of an asynchronous HTTPModule

In the above picture, An asp.net thread T1 is assigned from threadpool to server the request. When the control got passed to File System to log message, asp.net thread got  released and when essage logging got completed, control passed to asp.net and it is assigned to another thread say T2 from thread pool.
In .NET Framework 4.o, there was some major enhancement made for asynchronous programming model. Any asynchronous operation is represents a Task and it comes under the namespace System.Threading.Tasks.Task.

In .NET 4.5, there are some new operator and keyword introduced that makes the life easy for implement Asynchronous feature. One is async keyword and await operator.

These two enables us to write the asynchronous code is similar fashion as we write for synchronous mode.

And these features can be easily used while writing HTTPModules and HTTPHandlers. We’ll be using these enhancements in writing our custom asynchronous HTTPModule.

In my sample as depicted in image, I am creating a module that writes some log messages in a text file for every request made.

So to create a Custom HTTPModule, Create a class library project. And create a class  say named LogModule which implements IHttpModule. For this you need to add a reference of Assembly System.Web.

LogModule would contains the methods discussed below.

We need to implement two methods Init and Dispose that are part of IHTTPModule interface.

Here first , I have written an asynchronous method that actually reads the information from the request and writes in the log file asynchronously . For this I have used WriteAsync of FileStream

private async Task WriteLogmessages(object sender, EventArgs e)
{
	HttpApplication app = (HttpApplication)sender;
        DateTime time = DateTime.Now;

        string line = String.Format(
        "{0,10:d}    {1,11:T}    {2, 32}   {3}\r\n",
        time, time,
        app.Request.UserHostAddress,
        app.Request.Url);
        using (_file = new FileStream(
            HttpContext.Current.Server.MapPath(
              "~/App_Data/RequestLog.txt"),
            FileMode.OpenOrCreate, FileAccess.Write,
            FileShare.Write, 1024, true))
        {
            line = line + "  ," + threaddetails;
            byte[] output = Encoding.ASCII.GetBytes(line);

            _file.Seek(_position, SeekOrigin.Begin);
            _position += output.Length;
            await _file.WriteAsync(output, 0, output.Length);
        }

}

Here you can see the await key word, what it means..

As per msdn “An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

await is used with some asynchronous method that returns task and is used suspend the execution of the method until the task completes and control is returned back to the caller to execute further. await should be used with the last expression of any code block.

And Init method would be like

public void Init(HttpApplication context)
{
        // It wraps the Task-based method
        EventHandlerTaskAsyncHelper asyncHelper =
           new EventHandlerTaskAsyncHelper(WriteLogmessages);

        //asyncHelper's BeginEventHandler and EndEventHandler eventhandler that is used
        //as Begin and End methods for Asynchronous HTTP modules
        context.AddOnPostAuthorizeRequestAsync(
        asyncHelper.BeginEventHandler, asyncHelper.EndEventHandler);

}

So apart from above these methods, we need to implement the dispose method.

Now compile your class library and use the reference in your ASP.NET website . Now as you must be knowing that we need to need to add the entry in the config file. So it’ll be as

<system.webServer>
<modules>
<add name="MyCustomHTTPModule" type="MyCustomHTTPModule.LogModule, MyCustomHTTPModule"/>
</modules>
</system.webServer>

Now when you run your application, you will see the logs are created in a text file in App_Data folder as mentioned path in the code.

Hope you all have liked this new feature.

Page.ClientScript.RegisterStartupScript is not working : A Solution

This is going to be a very short post but will be useful many developers.

You have registered some JavaScript block from server side. But it’s not working. Actually it’s not getting rendered on Client side when you see the PageSource. But the same code works in different projects/applications/pages. Say you have code like this

           Page.ClientScript.RegisterStartupScript(this.GetType(), "ShowStatus", "javascript:alert('Record is not updated');", true);
 

It is registering one one startup script that will be fired when the page will be loaded.
Say you have used at several time and it was working but now it is failing.  Similarly Page.ClientScript provide many other methods that will also not work.

One of the main reasons is, We start using Ajax on our pages. Ajax requires a ScriptManager to handle all the ajax related (Partial postback) tasks. Ajax requires lots of JavaScript code that is managed by the ScriptManager. And it must be noted on a single page only one instance of ScriptManager is allowed.

So whenever we have an instance of  ScriptManager on our page, we need to register the Script using ScriptManager. So you need to change the code like this

            ScriptManager.RegisterStartupScript(this, this.GetType(), "ShowStatus", "javascript:alert('Record is not updated');", true);

       

Now this code make the script start working. Similarly , we also need to change other Page.ClientScript methods to appropriate ScriptManager method.

Cheers,

Brij

Claim based Authentication and WIF : Part 2

This post is second part of my post on Claim based Authentication. This part mainly discusses WIF and demonstrates a sample step by step. You all can access my first post from here.

Claim based Authentication and WIF

In my last post I discussed the problems of current day’s authentication implementation, details about Claim based authentication and basic components of Claim based authentication. Now in this post, I’ll discuss about Windows Identity Foundation and the main concepts one by one with a sample.

What is Windows Identity Foundation(WIF):

First of all. I’ll say Windows Identity Foundation is a   Microsoft way to leverage the Claim based Authentication. Lets see the definition from msdn,

Windows Identity Foundation enables .NET developers to externalize identity logic from their application, improving developer productivity, enhancing application security, and enabling interoperability. Enjoy greater productivity, applying the same tools and programming model to build on-premises software as well as cloud services. Create more secure applications by reducing custom implementations and using a single simplified identity model based on claims. Enjoy greater flexibility in application deployment through interoperability based on industry standard protocols, allowing applications and identity infrastructure services to communicate via claims.

So we can say, Windows Identity foundation provides a set of classes which facilitates in implementing Claim based authentication.

Prerquisite:

To use WIF you need Windows 2003 server+ or Windows 7/8/Vista.

  • WIF for Win server 2003 download it from
    here
  • WIF for Win 7+ download it from
    here
  • WIF SDK download it from
    here

WIF SDK provides some visual studio template that helps in developing Claim
aware applications. These templates are

  • ASP.NET Security Token Service Web Site
  • Claims-aware ASP.NET Web Site
  • Claims-aware WCF Service
  • WCF Security Token Service

Above templates are available in New Website under File Menu.

Let’s discuss an Example

So today we will create an asp.net application(Relying Party Application-RP). And also
we’ll create a custom
Identity provider and we’ll use this identity provider for authentication of the user.

These are following main steps need to perform.

  • Create a Custom Identity Provider
  • Create an ASP.NET application
  • Create a trust between Identity provider and ASP.NET application

So lets first create an Identity Provider

Creating a Custom Identity Provider

So here I will create a step by step process to create a Custom Identity Provider.

- Open Visual studio-> Create new website ->select ASP.NET Security Token Service Web Site (I have selected the location HTTP
to host it at IIS directly)

Now your sample Identity provider is created. It provides the basic infrastructure for you. It includes one login page that actually authenticates the user and here forms authentication is used.

Create an ASP.NET application( Relying Party – RP):

I have created an ASP.NET application as below.

Now as this already create a inbuilt authentication module. You can remove it at all because we’ll not be using this. Or you can create an empty asp.net solution and some page as per needed. I have removed the account folder for the demo.

Create a trust between Identity provider and ASP.NET application(RP): This can be done using FedUtil provided by WIF SDK. Also from UI, we can add an STS reference in the ASP.NET website and make a trust relationship between Identity Provider and Relying Party. Look the following steps to add the reference

  • Add a STS Reference to ASP.NET website

  • This is First screen of FedUtil which displays the URI and location of ASP.NET website(RP)

  • If you have not hosted your ASP.NET website(RP) on SSL it will the following Warning. At Production all the communication between Identity Provider and ASP.NET website(RP) should happen over SSL only. Here for demo purpose, I didn’t use SSL. I clicked on Yes.

  • In this screen, It asks to select the STS ( Security Token Service). And has three option. As we have created the STS, we need to select the option “Use an existing STS”

To build the trust relationship, we need to provide the federation metadata provided Identity Provider.

  • Now we need to browse the FederationMetada xml file of the STS that we created.


FederationMetadata file resides in a special folder hierarchy “FederationMetadata/2007-06″ under the STSWebsite physical folder.

  • And Select the FederationMetdata. And Click next

  • Again as my Security Token Service(STS) is not hosted at SSL. So it is showing the below warning
    message. I just clicked Yes

  • Here it asks if one wants to encrypt the token. It should be encrypted on production.You require to provide a certificate for the encryption. Here I have selected the option “No Encryption” for the demo.

  • Now it shows all the claims passed by STS to RP. We can pass more claims from STS to RP as per our requirement. All the Claims is shown here while adding the STS reference at end. By default there are only two roles provided by STS (Name & Role)

  • This is the Summary screen, shows the details about STS and RP. One need to review and click finish.

Note: Here There is an option for to update the federation metadata on a routine basis. One need to know, if the STS is getting changes say Token or Claims etc. RP would only come to know about when federationmetadata will be updated, else say if someone removed a Claim and metadata is not updated it will allow to get the that Claim but actually at runtime you would nto get that claim which will not be a good condition.One should always have the metadata in updated form.

After clicking Finish. A folder FederationMetadata is added to ASP.NET website (Relying Party -RP) as below



Lets run the application:
Now if you run the application. It will throw an exception as

“Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.”

This is an issue with it and I have made a small post on it. You can get it resolved easily. Please check this

Now after changes it will run smoothly and It will take you at login page that is provided by STS. This is default login page provided STS, here you dont need to write password just put some name and click on login as below.

It will redirect to another page to STS which will actually initiate the process to create the token and claims. Then after creating it will be transferred to your website as authenticated user.

Now our application is running. As here in STS we have a sample login page the uses Forms authentication and by default authenticate every user. Here we can put our code, whether if we want to authenticate the user using windows authentication/Form authentication and use database this all we can and also we can get some data of the user from any store say DB here and that we can send using in Claims as per our requirement.

So Now here I’ll show, how to pass some more information to the user in Claims. So one can additional claims here. When you create a STS, there are four files get added in App_Code folder. One file named CustomSecurityTokenService.cs. In this file there is a method GetOutputClaimsIdentity actually creates the claims. We need to add the claims here ( I have added few)

             ///
<summary> /// This method returns the claims to be issued in the token.
 /// </summary>
    ///The caller's principal.
    ///The incoming RST, can be used to obtain addtional information.
    ///The scope information corresponding to this request.
    /// If 'principal' parameter is null.
    /// The outgoing claimsIdentity to be included in the issued token.
    protected override IClaimsIdentity GetOutputClaimsIdentity( IClaimsPrincipal principal, RequestSecurityToken request, Scope scope )
    {
        if ( null == principal )
        {
            throw new ArgumentNullException( "principal" );
        }
        IClaimsIdentity claimsIdentity = (IClaimsIdentity)principal.Identities[0];

        ClaimsIdentity outputIdentity = new ClaimsIdentity();

        // Issue custom claims.
        // Update the application's configuration file too to reflect new claims requirement.

        outputIdentity.Claims.Add( new Claim( System.IdentityModel.Claims.ClaimTypes.Name, principal.Identity.Name ) );

        outputIdentity.Claims.Add(new Claim(ClaimTypes.Role, "Manager"));
        //I added these custom claims
        outputIdentity.Claims.Add(new Claim(ClaimTypes.Email, "brij@gmail.com"));
        outputIdentity.Claims.Add(new Claim(ClaimTypes.Gender, "Male"));

        return outputIdentity;
    }
       

I have added two claims (Email, Gender )as above. These Claims will be available at ASP.NET website( Relying Party).
The same Identity provider can be used in multiple application.

Reading Claims at Relying Party(RP):

It’s easy to read the claims at Relying Party. To read the claims you need ClaimsIdentity of the logged in user and it is available in User Property. I have read the Claims at my page. I have created a dynamic table and shown the claim in that.

          IClaimsPrincipal claimsPrincipal = Page.User as IClaimsPrincipal;
        IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;

        // The code below shows claims found in the IClaimsIdentity.

        Table claimsTable = new Table();
        TableRow headerRow = new TableRow();

        TableCell claimTypeCell = new TableCell();
        claimTypeCell.Text = "Claim Type";
        claimTypeCell.BorderStyle = BorderStyle.Solid;

        TableCell claimValueCell = new TableCell();
        claimValueCell.Text = "Claim Value";
        claimValueCell.BorderStyle = BorderStyle.Solid;

        headerRow.Cells.Add(claimTypeCell);
        headerRow.Cells.Add(claimValueCell);
        claimsTable.Rows.Add(headerRow);

        TableRow newRow;
        TableCell newClaimTypeCell, newClaimValueCell;
        foreach (Claim claim in claimsIdentity.Claims)
        {
            newRow = new TableRow();
            newClaimTypeCell = new TableCell();
            newClaimTypeCell.Text = claim.ClaimType;

            newClaimValueCell = new TableCell();
            newClaimValueCell.Text = claim.Value;

            newRow.Cells.Add(newClaimTypeCell);
            newRow.Cells.Add(newClaimValueCell);

            claimsTable.Rows.Add(newRow);
        }

        divClaims.Controls.Add(claimsTable);
       

and now when you run the page it will be shown like

Now you can see that it is very easy to read the claims and this can be used in further processing.

I hope the above sample will help a lot. In my new post of this series. I will discuss another technique to implement use Claim based Authentication which is widely Used Called Identity Federation.

Thanks a lot

Exception while using Custom STS in ProcessSignInResponse – Windows Identity Foundation : A solution

This is just a small post. Last few days I was working on Custom Identity provider. I created a STS site using the Visual studio template “ASP.NET Security Token Service Website” .
I also created the my new website that was actually going to use the above STS as Identity Provider. I added the STS reference to my new website using VS IDE.
Now When I ran my application I was redirected first to Login page of STS that was as expected. I got happy but as soon as I clicked on login, there was an exception. And the exception message was

Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.”

Read more of this post

Follow

Get every new post delivered to your Inbox.

Join 85 other followers