| Mika's profileMika's Digital GardenBlogSkyDrive | Help |
|
Mika's Digital GardenPublic folders
July 04 Token Authentication for ASP.NETFinally I found some time to realize an idea I've been working on in my head for a while. The idea is to extend the authentication mechanism in ASP.NET and add one more layer of security by adding token authentication functionality to selected parts of a web application. In practice, this works so that when a user requests for a resource on a web site that is configured to be protected by token authentication, the user is redirected to a login page that sends a token to the user in some way, and then waits for the user to enter the token on the login page. If the token matches the token that was sent to the user, the user is authenticated and allowed access to the protected resource. I packed this functionality into a class library that you can download and use free of charge on the MSDN Code Gallery at http://code.msdn.microsoft.com/tokenauthentication. The class library allows you to customize several things by developing your own classes and implement specific interfaces in those classes. The interfaces that you can use to customize the functionality are:
With this class library, you can use any authentication mechanism supported by ASP.NET, as long as you use some kind of authentication to authenticate your users and that the identity of the authenticated user is accessible from the This is probably not a solution that could be used in the enterprise, not very widely at least, but it is a simple and quick way of adding a bit more security to your web applications. Consider for instance an Extranet scenario where you as a service provider also host an Active Directory or other user directory where you store user names and passwords for your customers' employees. How can you make sure that when an employee changes jobs, that employee no longer has access to certain areas of your Extranet? By requiring your Extranet users to log on also using token authentication and sending the token to their e-mail boxes, you also make sure that the user has access to that e-mail box. Then of course you have to control what e-mail addresses you accept and how you allow the users to change their e-mail addresses. You could of course require token authentication to the page that allows a user to change her e-mail address. This way you ensure that the user has access to the old e-mail box before changing to a new e-mail box. There are of course other use cases for this kind of a token authentication. You could of course also create your own custom token sender that would send the token to your users mobile phones by using Outlook Mobile Services, for instance. Then you would ensure that the user has physical access to the mobile phone with the number returned by the address resolver that you have configured for your application. In addition to the sample ASP.NET application that is included with the source code on MSDN Code Gallery, I've also tried this solution on a standard MOSS 2007 web application that uses Windows Authentication. In MOSS, I have not tried this with Forms Authentication, but in the sample ASP.NET application, token authentication also works with Forms Authentication, so at least in theory, it should work with Forms Authentication in MOSS as well. Hope you find this useful, or at least amusing. See also the links below. // Mika April 25 Fighting the Global Climate Change
Get more details about Pasi's campaign on his website and join the Pasi Toiviainen support group on Facebook. // Mika November 07 ASP.NET Templated ControlsYou have probably many times noticed when writing the markup for ASP.NET pages that some ASP.NET controls allows you to inject your own HTML markup into certain locations. These controls are called templated controls. Have a look at the following sample markup. <asp:DataList runat="server"> <HeaderTemplate>Header of List</HeaderTemplate> </asp:DataList> The In one of the projects I am working on, I wanted to create such a templated control as well in order to allow the developers using my control to insert their own markup in between the markup generated by my control, so I started to find out how to create such a control. I found many resources on the net that explained in quite detail what you need to do to create a templated control, but none of the resources I found had a complete code listing available. All resources had split up the code with explaining text in between, making it very hard to grasp the whole picture. In this article I'll start with a very simple templated control with its full listing and build on that further down the article giving you an idea of what you could do with a templated control. Templated Control #1So, let's start off with the simples of templated controls. The code listing below is the full listing of the two classes you need to create in order to implement a templated control.
TemplatedControl1 (C#)
using System; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; namespace WebControlsProto1 { public class TemplatedControl1 : WebControl , INamingContainer { [Browsable(false)] [TemplateContainer(typeof(ContentContainer1))] [PersistenceMode(PersistenceMode.InnerProperty)] public ITemplate ContentTemplate { get; set; } protected override void CreateChildControls() { if (null != this.ContentTemplate) { ContentContainer1 template = new ContentContainer1(); this.ContentTemplate.InstantiateIn(template); this.Controls.Add(template); } } public class ContentContainer1 : Control, INamingContainer { } } } The first and natural thing to do would of course be to create a class that represents your control, i.e. the The templated control itself need to inherit from the This would allow you to use this control on an ASP.NET page like this: Markup Sample
<cc1:TemplatedControl1 ID="TemplatedControl11" runat="server">Now, this control would not do that much actually, but you probably start to get the picture. Templated Control #2The following control is a bit of an elaboration to the previous in the sense that it creates a
TemplatedControl2 (C#)
using System; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace WebControlsProto1 { public class TemplatedControl2 : WebControl, INamingContainer { public TemplatedControl2() : base(HtmlTextWriterTag.Fieldset) { } public string Heading { get; set; } [Browsable(false)] [TemplateContainer(typeof(ContentContainer2))] [PersistenceMode(PersistenceMode.InnerProperty)] public ITemplate ContentTemplate { get; set; } private HtmlGenericControl Legend = new HtmlGenericControl("legend"); protected override void CreateChildControls() { this.Controls.Add(this.Legend); if (null != this.ContentTemplate) { ContentContainer2 template = new ContentContainer2(); this.ContentTemplate.InstantiateIn(template); this.Controls.Add(template); } } protected override void Render(HtmlTextWriter writer) { this.Legend.InnerText = this.Heading; this.Legend.Visible = !string.IsNullOrEmpty(this.Heading); base.Render(writer); } public class ContentContainer2 : Control, INamingContainer { } } } Now this starts already to provide you with a bit more functionality, but you are still abstracting away the inner workings of the control. As in the previous example, you would use this control in your ASP.NET markup as shown in the sample below. Markup Sample
<cc1:TemplatedControl2Templated Control #3The next thing that I wanted to do was to add support for using this control programmatically instead of from markup. This means that when you add new controls to the Controls collection of your templated control, they would be added as child controls to the control representing the template. The full code listing for this class is shown below. TemplatedControl3 (C#)
using System; using System.ComponentModel; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace WebControlsProto1 { public class TemplatedControl3 : WebControl, INamingContainer { public TemplatedControl3() : base(HtmlTextWriterTag.Fieldset) { } public string Heading { get; set; } [Browsable(false)] [TemplateContainer(typeof(ContentContainer3))] [PersistenceMode(PersistenceMode.InnerProperty)] public ITemplate ContentTemplate { get; set; } public override ControlCollection Controls { get { return this.Content.Controls; } } private HtmlGenericControl Legend = new HtmlGenericControl("legend"); private ContentContainer3 Content = new ContentContainer3(); protected override void CreateChildControls() { base.Controls.Add(this.Legend); if (null != this.ContentTemplate) { this.ContentTemplate.InstantiateIn(this.Content); } HtmlGenericControl div = new HtmlGenericControl("div"); div.Attributes["class"] = "content"; base.Controls.Add(div); div.Controls.Add(this.Content); } protected override void Render(HtmlTextWriter writer) { this.Legend.InnerText = this.Heading; this.Legend.Visible = !string.IsNullOrEmpty(this.Heading); base.Render(writer); } public class ContentContainer3 : Control, INamingContainer { } } } In the C#
TemplatedControl3 c3 = new TemplatedControl3(); c3.Heading = "Programmatic Stuff"; c3.Controls.Add(new LiteralControl("Programmatic Text")); this.Panel1.Controls.Add(c3); Now this is all quite simple, but still powerful. However, I wanted to have also the following features in my templated control.
FieldSet ControlSo in order to create such a component, we first need to create a very brief "specification" for that component. I'll call it the Below is a sample listing of how you would use the Code Listing
<cc1:FieldSet runat="server" Label="Fields 1"> <cc1:Field runat="server" Label="Field 1" Value="My Value" /> <cc1:FieldSet runat="server" Label="Fields 2"> <cc1:Field runat="server" Label="E-mail" Value="john.doe@internet.com" /> <cc1:Field runat="server" Label="Mobile" Value="1234567" /> </cc1:FieldSet> </cc1:FieldSet> The following code listing shows the code behind the FieldSet and Field controls.
FieldSet and Field Controls
using System; using System.Collections; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; namespace WebControlsProto1 { [ControlBuilder(typeof(FieldSetControlBuilder))] [ParseChildren(false)] [PersistenceMode(PersistenceMode.InnerProperty)] public class FieldSet : WebControl , INamingContainer { public FieldSet() : base("fieldset") { } public string Label { get; set; } private HtmlGenericControl Legend = new HtmlGenericControl("legend"); protected override void CreateChildControls() { this.Controls.AddAt(0, this.Legend); } protected override void Render(HtmlTextWriter writer) { this.Legend.InnerText = this.Label; this.Legend.Visible = !string.IsNullOrEmpty(this.Label); base.Render(writer); } } [ControlBuilder(typeof(FieldControlBuilder))] public class Field : WebControl , INamingContainer { public Field() : base("div") { } public string Label { get; set; } public string Value { get; set; } Label LabelControl = new Label(); TextBox Textbox = new TextBox(); protected override void CreateChildControls() { base.Controls.Add(this.LabelControl); base.Controls.Add(this.Textbox); this.Textbox.ID = "TextBox"; this.LabelControl.AssociatedControlID = "TextBox"; } protected override void Render(HtmlTextWriter writer) { this.LabelControl.Text = this.Label; this.LabelControl.Visible = !string.IsNullOrEmpty(this.Label); this.Textbox.Text = this.Value; base.Render(writer); } } public class FieldSetControlBuilder : ControlBuilder { public override bool HasBody() { return true; } public override Type GetChildControlType(string tagName, IDictionary attribs) { if (string.Equals("FieldSet", tagName, StringComparison.OrdinalIgnoreCase)) { return typeof(FieldSet); } if (string.Equals("Field", tagName, StringComparison.OrdinalIgnoreCase)) { return typeof(Field); } return null; } } public class FieldControlBuilder : ControlBuilder { public override Type GetChildControlType(string tagName, IDictionary attribs) { if (string.Equals("Field", tagName, StringComparison.OrdinalIgnoreCase)) { return typeof(Field); } return null; } } } Applying these samples that I've showed you to your own requirements will give you a very powerful way of creating controls that will provide a lot of functionality (depending of course on the code you write) to your developers but still allow them to have a high degree of control on the layout of the HTML elements produced by the control. // Mika September 21 Creating a simple WCF ServiceThere are probably millions of articles written about WCF, so I'm not trying to write about anything new and brilliant related to that subject. This is more or less a note to myself so that I don't forget all the things that I dug up during a project where I implemented a couple of WCF services. If this article provides any help to you, then great. One of the requirement for the project was to create a set of WCF services, host them in an ASP.NET application, and also enable the services to be queries using HTTP GET by adding the parameters to the operations as query string parameters in the URL to the service operation. The Sample Solution
The solution contains the following three projects:
To have a closer look at this sample solution, you can download it from the link below. The ContractThe first thing we're going to have a look at is the contract. In addition to the normal way of creating service contracts, i.e. by creating an interface, decorating the interface with the using System.ServiceModel; using System.ServiceModel.Web; namespace WcfContractLibrary { /// <summary> /// Defines a very simple service contract. /// </summary> [ServiceContract( Namespace = "http://namespaces.org/2008/09/simpleservicecontract.xsd" )] public interface ISimpleService { [OperationContract] [WebGet] string HelloClient(string name); } } One more thing that you need to note; since you are going to invoke the operation with HTTP GET requests, the parameter types on your operations must be of simple type such as strings, integers, booleans etc. This unfortunately also means nullable types. So, stick to clean, simple and not nullable types. The ConfigurationThe logical thing would be to talk about the service implementation, but related to HTTP GET access to your services, there is nothing special about the service implementation. You simply implement a service contract interface and configure it for use in your application. Regarding the configuration, there are two things you need to note.
To take a closer look at this, the service must specify and endpoint similar to the one below. <endpoint address="" binding="webHttpBinding" bindingNamespace="http://namespaces.org/2008/09/simpleservice.xsd?webHttpBinding" contract="WcfContractLibrary.ISimpleService" behaviorConfiguration="DefaultEndpointBehavior" /> Then behaviour configuration for this enpoint looks like this. <behavior name="DefaultEndpointBehavior"> <webHttp /> </behavior> Accessing the ServiceBy creating a service contract and configuring it as described above (and naturally implementing the service contract interface), you can access the service by creating HTTP GET requests, for instance directly in your browser. In the sample solution described above, the URL to invoke an operation would be: http://localhost:12868/SimpleService.svc/HelloClient?name=World This would invoke the Hosting in ASP.NETWhen you host your services in an ASP.NET application, you can utilize ASP.NET services just as you did when you created ASP.NET Web Services (ASMX files). However, when you host a WCF service in an ASP.NET application, those services are not available to you by default. There is not To be able to get a context using the <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> You also need to decorate your service class with the If you want to use ASP.NET compatibility in your WCF services, I strongly recommend that you create two versions of your service; one version that is a "clean" WCF service that can be hosted in any process, and then another service that inherits from the "clean" WCF service and overrides the operations in which you want to use ASP.NET related services, such as caching. I've demonstrated this also in the sample solution, which you can download at the beginning of this article. ConclusionAs I wrote in the beginning of this article, I started poking around this subject in a project where one requirement was that the service must be accessible using HTTP GET. The reason for that was that we wanted to make our service accessible from just about any kind of application, such as a Flash application. I'm not a Flash expert in any way, so I might be wrong saying that Flash does not have Web Service and SOAP support, but there are other application environments where this support does not exist. One thing that probably any application environment can do is to create HTTP requests and parse XML. I did not find one article that would have explained all of this information in the same way, so I thought I write it down for future reference. Hopefully you will find this useful as well. // Mika August 07 Generic Diff FormatA few years ago I stumbled across this specification from W3C, the Generic Diff Format or GDIFF for short. It's a specification that defines a binary format for describing the difference between two streams of binary data. Since any data such as strings, images etc. can be represented as a stream of binary data (i.e. a stream of bytes), GDIFF can be used to represent the difference between any two streams of data. For example, if you have two streams of data, Usage ScenariosProbably the most useful area for GDIFF would be different kinds of versioning applications, such as document and content management systems, source code storage etc. In such systems you could apply GDIFF to store different versions of the same document using reverse delta, where you store only the latest version of a document in full. To get to older versions, you need to get the full version (the latest) and then apply one GDIFF to that. For instance, you have a document with4 versions, v1 through v4. To get to those different versions, you apply the following logic.
When you store a new version (v5) of this document, you only have to do the following things:
Older versions do not have to be modified. The ImplementationA few years back when I first discovered the GDIFF spec I tried for a while to create code that would produce GDIFFs. At that time I did not get anything done that was worth saving, probably because I did not put my mind into it properly. However, a couple of weeks ago I was talking with one of my colleagues and this topic just came up again, and I thought why not give it a go one more time. The result including source code can be found on CodePlex at http://www.codeplex.com/GDIFF. Please feel free to download the source code and give your input to it using either the Issue Tracker or the dicussion board. If you feel like joining the development, please send me a line and I'll add you to the project as a contributor. Code ExamplesI've created a separate page on the project wiki where I'm writing examples on how to use the GDIFF library in your code. Please have a look at the page here. |
||||
|
|