Category Archives: ASP.Net

How To : Using the Proxy Pattern to implement Code Access Security

There are many ways to secure different parts of your application. The security of running code in .NET revolves around the concept of Code Access Security (CAS).

CAS

CAS determines the trustworthiness of an assembly based upon its origin and the characteristics of the assembly itself, such as its hash value. For example, code installed locally on the machine is more trusted than code downloaded from the Internet. The runtime will also validate an assembly’s metadata and type safety before that code is allowed to run.

 

There are many ways to write secure code and protect data using the .NET Framework. In this chapter, we explore such things as controlling access to types, encryption and decryption, random numbers, securely storing data, and using programmatic and declarative security.

 

Controlling Access to Types in a Local Assembly

 

Problem

You have an existing class that contains sensitive data, and you do not want clients to have direct access to any objects of this class. Instead, you want an intermediary object to talk to the clients and to allow access to sensitive data based on the client’s credentials. What’s more, you would also like to have specific queries and modifications to the sensitive data tracked, so that if an attacker manages to access the object, you will have a log of what the attacker was attempting to do.

Solution

Use the proxy design pattern to allow clients to talk directly to a proxy object. This proxy object will act as gatekeeper to the class that contains the sensitive data. To keep malicious users from accessing the class itself, make it private, which will at least keep code without the ReflectionPermissionFlag. MemberAccess access (which is currently given only in fully trusted code scenarios such as executing code interactively on a local machine) from getting at it.

The namespaces we will be using are:

 
 
  using System;
    using System.IO;
    using System.Security;
    using System.Security.Permissions;
    using System.Security.Principal;

Let’s start this design by creating an interface, as shown in Example 17-1, “ICompanyData interface”, that will be common to both the proxy objects and the object that contains sensitive data.

Example 17-1. ICompanyData interface

 
 
internal interface ICompanyData
{
    string AdminUserName
    {
        get;
        set;
    }

    string AdminPwd
    {
        get;
        set;
    }
    string CEOPhoneNumExt
    {
        get;
        set;
    }
    void RefreshData();
    void SaveNewData();
}

The CompanyData class shown in Example 17-2, “CompanyData class” is the underlying object that is “expensive” to create.

Example 17-2. CompanyData class

 
 
internal class CompanyData : ICompanyData
{
    public CompanyData()
    {
        Console.WriteLine("[CONCRETE] CompanyData Created");
        // Perform expensive initialization here.
        this.AdminUserName ="admin";
        this.AdminPd ="password";

        this.CEOPhoneNumExt ="0000";
    }

    public str ing AdminUserName
    {
        get;
        set;
    }

    public string AdminPwd
    {
        get;
        set;
    }

    public string CEOPhoneNumExt
    {
        get;
        set;
    }

    public void RefreshData()
    {
        Console.WriteLine("[CONCRETE] Data Refreshed");
    }

    public void SaveNewData()
    {
        Console.WriteLine("[CONCRETE] Data Saved");
    }
}

The code shown in Example 17-3, “CompanyDataSecProxy security proxy class” for the security proxy class checks the caller’s permissions to determine whether the CompanyData object should be created and its methods or properties called.

Example 17-3. CompanyDataSecProxy security proxy class

 
 
public class CompanyDataSecProxy : ICompanyData
{
    public CompanyDataSecProxy()
    {
        Console.WriteLine("[SECPROXY] Created");

        // Must set principal policy first.
        appdomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.
           WindowsPrincipal);
    }

    private ICompanyData coData = null;
    private PrincipalPermission admPerm =
        new PrincipalPermission(null, @"BUILTIN\Administrators", true);
    private PrincipalPermission guestPerm =
        new Pr incipalPermission(null, @"BUILTIN\Guest", true);
    private PrincipalPermission powerPerm =
        new PrincipalPermission(null, @"BUILTIN\PowerUser", true);
    private PrincipalPermission userPerm =
        new PrincipalPermission(null, @"BUILTIN\User", true);

    public string AdminUserName
    {
        get
        {
            string userName = ";
            try
            {
                admPerm.Demand();
                Startup();
                userName =coData.AdminUserName;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("AdminUserName_get failed! {0}",e.ToString());
            }
            return (userName);
        }
        set
            {
            try
            {
                admPerm.Demand();
                Startup();
                coData.AdminUserName = value;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("AdminUserName_set failed! {0}",e.ToString());
            }
        }
    }

    public string AdminPwd
    {
        get
        {
            string pwd = ";
            try
            {
                admPerm.Demand();
                Startup();
                pwd = coData.AdminPwd;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("AdminPwd_get Failed! {0}",e.ToString());
            }

            return (pwd);
        }
        set
        {
            try
            {
                admPerm.Demand();
                Startup();
                coData.AdminPwd = value;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("AdminPwd_set Failed! {0}",e.ToString());
            }
        }
    }

    public string CEOPhoneNumExt
    {
        get
        {
            string ceoPhoneNum = ";
            try
            {
                admPerm.Union(powerPerm).Demand();
                Startup();
                ceoPhoneNum = coData.CEOPhoneNumExt;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("CEOPhoneNum_set Failed! {0}",e.ToString());
            }
            return (ceoPhoneNum);
        }
        set
        {
            try
            {
                admPerm.Demand();
                Startup();
                coData.CEOPhoneNumExt = value;
            }
            catch(SecurityException e)
            {
                Console.WriteLine("CEOPhoneNum_set Failed! {0}",e.ToString());
            }
        }
    }
    public void RefreshData()
    {
        try
        {
            admPerm.Union(powerPerm.Union(userPerm)).Dem and();
            Startup();
            Console.WriteLine("[SECPROXY] Data Refreshed");
            coData.RefreshData();
        }
        catch(SecurityException e)
        {
            Console.WriteLine("RefreshData Failed! {0}",e.ToString());
        }
    }

    public void SaveNewData()
    {
        try
        {
            admPerm.Union(powerPerm).Demand();
            Startup();
            Console.WriteLine("[SECPROXY] Data Saved");
            coData.SaveNewData();
        }
        catch(SecurityException e)
        {
            Console.WriteLine("SaveNewData Failed! {0}",e.ToString());
        }
    }

    // DO NOT forget to use [#define DOTRACE] to control the tracing proxy.
    private void Startup()
    {
        if (coData == null)
        {
#if (DOTRACE)
            coData = new CompanyDataTraceProxy();
#else
            coData = new CompanyData();
#endif
            Console.WriteLine("[SECPROXY] Refresh Data");
            coData.RefreshData();
        }
    }
}

When creating thePrincipalPermissions as part of the object construction, you are using string representations of the built-in objects (“BUILTIN\Administrators”) to set up the principal role. However, the names of these objects may be different depending on the locale the code runs under. It would be appropriate to use the WindowsAccountType.Administrator enumeration value to ease localization because this value is defined to represent the administrator role as well. We used text here to clarify what was being done and also to access the PowerUsers role, which is not available through the WindowsAccountType enumeration.

If the call to the CompanyData object passes through the CompanyDataSecProxy, then the user has permissions to access the underlying data. Any access to this data may be logged, so the administrator can check for any attempt to hack the CompanyData object. The code shown in Example 17-4, “CompanyDataTraceProxy tracing proxy class” is the tracing proxy used to log access to the various method and property access points in the CompanyData object (note that the CompanyDataSecProxy contains the code to turn this proxy object on or off).

Example 17-4. CompanyDataTraceProxy tracing proxy class

 
 
public class CompanyDataTraceProxy : ICompanyData
{    
    public CompanyDataTraceProxy() 
    {
        Console.WriteLine("[TRACEPROXY] Created");
        string path = Path.GetTempPath() + @"\CompanyAccessTraceFile.txt";
        fileStream = new FileStream(path, FileMode.Append,
            FileAccess.Write, FileShare.None);
        traceWriter = new StreamWriter(fileStream);
        coData = new CompanyData();
    }

    private ICompanyData coData = null;
    private FileStream fileStream = null;
    private StreamWriter traceWriter = null;

    public string AdminPwd
    {
        get
        {
            traceWriter.WriteLine("AdminPwd read by user.");
            traceWriter.Flush();
            return (coData.AdminPwd);
        }
        set
        {
            traceWriter.WriteLine("AdminPwd written by user.");
            traceWriter.Flush();
            coData.AdminPwd = value;
        }
    }

    public string AdminUserName
    {
        get
        {
            traceWriter.WriteLine("AdminUserName read by user.");
            traceWriter.Flush();
            return (coData.AdminUserName);
        }
        set
        {
            traceWriter.WriteLine("AdminUserName written by user.");
            traceWriter.Flush(); 
            coData.AdminUserName = value;
        }
    }

    public string CEOPhoneNumExt
    {
        get
        {
            traceWriter.WriteLine("CEOPhoneNumExt read by user.");
            traceWriter.Flush();
            return (coData.CEOPhoneNumExt);
        }
        set
        {
            traceWriter.WriteLine("CEOPhoneNumExt written by user.");
            traceWriter.Flush();
            coData.CEOPhoneNumExt = value;
        }
    }

    public void RefreshData()
    {
        Console.WriteLine("[TRACEPROXY] Refresh Data");
        coData.RefreshData();
    }

    public void SaveNewData()
    {
        Console.WriteLine("[TRACEPROXY] Save Data");
        coData.SaveNewData();
    }
}

The proxy is used in the following manner:

 
 
   // Create the security proxy here.
    CompanyDataSecProxy companyDataSecProxy = new CompanyDataSecProxy( );

    // Read some data.
    Console.WriteLine("CEOPhoneNumExt: " + companyDataSecProxy.CEOPhoneNumExt);

    // Write some data.
    companyDataSecProxy.AdminPwd = "asdf";
    companyDataSecProxy.AdminUserName = "asdf";

    // Save and refresh this data.
    companyDataSecProxy.SaveNewData( );
    companyDataSecProxy.RefreshData( );

Note that as long as the CompanyData object was accessible, you could have also written this to access the object directly:

 
 
    // Instantiate the CompanyData object directly without a proxy.
    CompanyData companyData = new CompanyData( );

    // Read some data.
    Console.WriteLine("CEOPhoneNumExt: " + companyData.CEOPhoneNumExt);

    // Write some data.
    companyData.AdminPwd = "asdf";
    companyData.AdminUserName = "asdf";

    // Save and refresh this data.
    companyData.SaveNewData();
    companyData.RefreshData();

If these two blocks of code are run, the same fundamental actions occur: data is read, data is written, and data is updated/refreshed. This shows you that your proxy objects are set up correctly and function as they should.

Discussion

The proxy design pattern is useful for several tasks. The most notable-in COM, COM+, and .NET remoting-is for marshaling data across boundaries such as AppDomains or even across a network. To the client, a proxy looks and acts exactly the same as its underlying object; fundamentally, the proxy object is just a wrapper around the object.

 

A proxy can test the security and/or identity permissions of the caller before the underlying object is created or accessed. Proxy objects can also be chained together to form several layers around an underlying object. Each proxy can be added or removed depending on the circumstances.

 

For the proxy object to look and act the same as its underlying object, both should implement the same interface. The implementation in this recipe uses an ICompanyData interface on both the proxies (CompanyDataSecProxy and CompanyDataTraceProxy) and the underlying object (CompanyData). If more proxies are created, they, too, need to implement this interface.

 

The CompanyData class represents an expensive object to create. In addition, this class contains a mixture of sensitive and nonsensitive data that requires permission checks to be made before the data is accessed. For this recipe, the CompanyData class simply contains a group of properties to access company data and two methods for updating and refreshing this data. You can replace this class with one of your own and create a corresponding interface that both the class and its proxies implement.

 

The CompanyDataSecProxy object is the object that a client must interact with. This object is responsible for determining whether the client has the correct privileges to access the method or property that it is calling. The get accessor of the AdminUserName property shows the structure of the code throughout most of this class:

 
 
  public string AdminUserName
    {
        get
        {
            string userName = ";
            try
            {
                admPerm.Demand( );
                Startup( );
                userName = coData.AdminUserName;
            }
            catch(SecurityException e)
            {
               Console.WriteLine("AdminUserName_get ailed!: {0}",e.ToString( ));
            }
            return (userName);
        }
        set
        {
            try
            {
                admPerm.Demand( );
                Startup( );
                coData.AdminUserName = value;
            }
            catch(SecurityException e)
            {
               Console.WriteLine("AdminUserName_set Failed! {0}",e.ToString( ));
            }
        }
    }

Initially, a single permission (AdmPerm) is demanded. If this demand fails, a SecurityException, which is handled by the catch clause, is thrown. (Other exceptions will be handed back to the caller.) If the Demand succeeds, the Startup method is called. It is in charge of instantiating either the next proxy object in the chain (CompanyDataTraceProxy) or the underlying CompanyData object. The choice depends on whether the DOTRACE preprocessor symbol has been defined. You may use a different technique, such as a registry key to turn tracing on or off, if you wish.

 

This proxy class uses the private field coData to hold a reference to an ICompanyData type, which can be either a CompanyDataTraceProxy or the CompanyData object. This reference allows you to chain several proxies together.

In the marketSenior C# & SharePoint Developer in the market

10 years experience in various industries

BSC Degree in Computer Science (Cum Laude)

tomas.floyd@outlook.com

https://sharepointsamurai.wordpress.com

 

The CompanyDataTraceProxy simply logs any access to the CompanyData object’s information to a text file. Since this proxy will not attempt to prevent a client from accessing the CompanyData object, the CompanyData object is created and explicitly called in each property and method of this object.

Advertisements

DRY Architecture, Layered Architecture, Domain Driven Design and a Framework to build great Single Web Pages – BiolerPlate Part 1

DRY – Don’t Repeat Yourself! is one of the main ideas of a good developer while developing a software. We’re trying to implement it from simple methods to classes and modules. What about developing a new web based application? We, software developers, have similar needs when developing enterprise web applications.

Enterprise web applications need login pages, user/role management infrastructure, user/application setting management, localization and so on. Also, a high quality and large scale software implements best practices such as Layered Architecture, Domain Driven Design (DDD), Dependency Injection (DI). Also, we use tools for Object-Releational Mapping (ORM), Database Migrations, Logging… etc. When it comes to the User Interface (UI), it’s not much different.

Starting a new enterprise web application is a hard work. Since all applications need some common tasks, we’re repeating ourselves. Many companies are developing their own Application Frameworks or Libraries for such common tasks to do not re-develop same things. Others are copying some parts of existing applications and preparing a start point for their new application. First approach is pretty good if your company is big enough and has time to develop such a framework.

As a software architect, I also developed such a framework im my company. But, there is some point it feels me bad: Many company repeats same tasks. What if we can share more, repeat less? What if DRY principle is implemented universally instead of per project or per company? It sounds utopian, but I think there may be a starting point for that!

What is ASP.NET Boilerplate?

http://www.aspnetboilerplate.com/

ASP.NET Boilerplate [1] is a starting point for new modern web applications using best practices and most popular tools. It’s aimed to be a solid model, a general-purpose application framework and a project template. What it does?

  • Server side
    • Based on latest ASP.NET MVC and Web API.
    • Implements Domain Driven Design (Entities, Repositories, Domain Services, Application Services, DTOs, Unif Of Work… and so on)
    • Implements Layered Architecture (Domain, Application, Presentation and Infrastructure Layers).
    • Provides an infrastructure to develop reusable and composable modules for large projects.
    • Uses most popular frameworks/libraries as (probably) you’re already using.
    • Provides an infrastructure and make it easy to use Dependency Injection (uses Castle Windsor as DI container).
    • Provides a strict model and base classes to use Object-Releational Mapping easily (uses NHibernate, can work with many DBMS).
    • Implements database migrations (uses FluentMigrator).
    • Includes a simple and flexible localization system.
    • Includes an EventBus for server-side global domain events.
    • Manages exception handling and validation.
    • Creates dynamic Web API layer for application services.
    • Provides base and helper classes to implement some common tasks.
    • Uses convention over configuration principle.
  • Client side
    • Provides two project templates. One for Single-Page Applications using Durandaljs, other one is a Multi-Page Application. Both templates uses Twitter Bootstrap.
    • Most used libraries are included by default: Knockout.js, Require.js, jQuery and some useful plug-ins.
    • Creates dynamic javascript proxies to call application services (using dynamic Web API layer) easily.
    • Includes unique APIs for some sommon tasks: showing alerts & notifications, blocking UI, making AJAX requests.

Beside these common infrastructure, the “Core Module” is being developed. It will provide a role and permission based authorization system (implementing ASP.NET Identity Framework), a setting systems and so on.

What ASP.NET Boilerplate is not?

ASP.NET Boilerplate provides an application development model with best practices. It has base classes, interfaces and tools that makes easy to build maintainable large-scale applications. But..

  • It’s not one of RAD (Rapid Application Development) tools those provide infrastructure for building applications without coding. Instead, it provides an infrastructure to code in best practices.
  • It’s not a code generation tool. While it has several features those build dynamic code in run-time, it does not generate codes.
  • It’s not a all-in-one framework. Instead, it uses well known tools/libraries for specific tasks (like NHibernate for O/RM, Log4Net for logging, Castle Windsor as DI container).

Getting started

In this article, I’ll show how to deleveop a Single-Page and Responsive Web Application using ASP.NET Boilerplate (I’ll call it as ABP from now). This sample application is named as “Simple Task System” and it consists of two pages: one for list of tasks, other one is to add new tasks. A Task can be related to a person, can be completed. The application is localized in two languages. Screenshot of Task List in the application is shown below:

A screenshot of 'Simple Task System'

Creating empty web application from template

ABP provides two templates to start a new project (Even if you can manually create your project and get ABP packages from nuget, template way is much more easy). Go to www.aspnetboilerplate.com/Templates to create your application from one of twotemplates (one for SPA (Single-Page Application), one for MPA (classic, Multi-Page Application) projects):

Creating template from ABP web site

I named my project as SimpleTaskSystem and created a SPA project. It downloaded project as a zip file. When I open the zip file, I see a solution is ready that contains assemblies (projects) for each layer of Domain Driven Design:

Project files

Created project’s runtime is .NET Framework 4.5.1, I advice to open with Visual Studio 2013. The only prerequise to be able to run the project is to create a database. SPA template assumes that you’re using SQL Server 2008 or later. But you can change it easily to another DBMS.

See the connection string in web.config file of the web project:

<add name="MainDb" connectionString="Server=localhost; Database=SimpleTaskSystemDb; Trusted_Connection=True;" />

You can change connection string here. I don’t change the database name, so I’m creating an empty database, named SimpleTaskSystemDb, in SQL Server:

Empty database

That’s it, your project is ready to run! Open it in VS2013 and press F5:

First run

Template consists of two pages: One for Home page, other is About page. It’s localized in English and Turkish. And it’s Single-Page Application! Try to navigate between pages, you’ll see that only the contents are changing, navigation menu is fixed, all scripts and styles are loaded only once. And it’s responsive. Try to change size of the browser.

Now, I’ll show how to change the application to a Simple Task System application layer by layer in the coming part 2

Using jQuery Mobile and ASP.NET to Pass Data from one Page to another

ASP.NET developers working on either Web Forms or ASP.NET MVC can integrate jQuery Mobile into their Web sites to create rich mobile Web apps. jQuery Mobile is a lightweight JavaScript framework for developing cross-platform mobile/device Web applications.

In mobile application development, you as a developer must think about how to utilize available space in the best possible manner. For this purpose sometimes the UI needs to be divided in separate pages. In such cases, you may need to transfer value(s) entered in one page, on the second page for the further processing.

Consider a scenario where the end user is asked to select the Product Category on Page 1 and based upon that, Page 2 displays products under that category. To get this done, values must be passed from page 1 to page 2.

In jQuery Mobile, $.mobile object provides the changePage() method which accepts the page url as a first parameter and the values to be transferred as a second parameter using JSON based data. In this article, we will see, how values are passed from one page to another in an ASP.NET application.

Step 1: Open Visual Studio and create a new ASP.NET empty web application, name it as ‘ASPNET_Mobile_PassingValuesAcrossPages’. In this application, using the NuGet Package Manager, add the latest jQuery and jQuery Mobile libraries.

Step 2: To the project, add a new class file, name it as ‘ModelClasses.cs’ and add the following classes in it:

public class Category {     public int CategoryId { get; set; }     public string CategoryName { get; set; } }

public class Product {     public int ProductId { get; set; }     public string ProductName { get; set; }     public int Price { get; set; }     public int CategoryId { get; set; } }

public class CategoryDataStore : List<Category> {     public CategoryDataStore()     {         Add(new Category() { CategoryId = 1, CategoryName = “Food Items” });         Add(new Category() { CategoryId = 2, CategoryName = “Home Appliances” });         Add(new Category() { CategoryId = 3, CategoryName = “Electronics” });         Add(new Category() { CategoryId = 4, CategoryName = “Wear” });     } }

public class CategoryDataSource {     public List<Category> GetCategories()     {         return new CategoryDataStore();     } }

public class ProductDataStore : List<Product> {     public ProductDataStore()     {         Add(new Product() { ProductId = 111, ProductName = “Apples”, Price = 300, CategoryId = 1 });         Add(new Product() { ProductId = 112, ProductName = “Date”,   Price = 600, CategoryId = 1 });         Add(new Product() { ProductId = 113, ProductName = “Fridge”, Price = 34000, CategoryId = 2 });         Add(new Product() { ProductId = 114, ProductName = “T.V.”,   Price = 30000, CategoryId = 2 });         Add(new Product() { ProductId = 115, ProductName = “Laptop”, Price = 72000, CategoryId = 3 });         Add(new Product() { ProductId = 116, ProductName = “Mobile”, Price = 40000, CategoryId = 3 });         Add(new Product() { ProductId = 117, ProductName = “T-Shirt”, Price = 800, CategoryId = 4 });         Add(new Product() { ProductId = 118, ProductName = “Jeans”, Price = 700, CategoryId = 4 });     } }

public class ProductDataSource {     public List<Product> GetProductsByCategoryId(int catId)     {         var Products = from p in new ProductDataStore()                        where p.CategoryId == catId                        select p;

        return Products.ToList();     } }

The above code provides Category and Product entities with data stored in it. The Product is a child of the Category class.

Step 3: In the project, add a WEB API controller class with the following code:

public class CategoryProductController : ApiController {     CategoryDataSource objCatDs;     ProductDataSource objPrdDs;

    public CategoryProductController()     {         objCatDs = new CategoryDataSource();         objPrdDs = new ProductDataSource();     }

    public IEnumerable<Category> Get()     {         return objCatDs.GetCategories();     }

    public IEnumerable<Product> Get(int id)     {         return objPrdDs.GetProductsByCategoryId(id);     } }

Step 4: To define routing for the WEB API class, add a new Global Application Class (Global.asax) in the project and add the following code in the Application_Start method:

protected void Application_Start(object sender, EventArgs e) {     RouteTable.Routes.MapHttpRoute(     name: “DefaultApi”,     routeTemplate: “api/{controller}/{id}”,     defaults: new { id = System.Web.Http.RouteParameter.Optional }     ); }

Step 5: Add two HTML pages, name them as Page_Category.html and Page_Products.html.

Task 6: In both the HTML pages, add the jQuery and jQuery Mobile references:

<link href=”Content/jquery.mobile.structure-1.3.1.min.css” rel=”stylesheet” /> <link href=”Content/jquery.mobile.theme-1.3.1.min.css” rel=”stylesheet” /> <script src=”Scripts/jquery-2.0.2.min.js”></script> <script src=”Scripts/jquery.mobile-1.3.1.min.js”></script>

Add the following HTML in the Page_Category.html page:

<div data-role=”page” id=”catpage”>     <div data-role=”header”>         <h1>Select Category from List</h1>     </div>     <div data-role=”content”>         <div>             <select  id=”lstcat” data-native-menu=”false”>                 <option>List of Categories…..</option>             </select>         </div>         <br />         <br />         <input type=”button” data-icon=”search”            value=”Get Products”  data-inline=”true” id=”btngetproducts” />     </div> </div>

The above code defines a page using <div>  whose data-role attribute is set to page. This page contains a <select> for displaying list of categories in it and an <input> button with a click event on which the control will be transmitted to Page_Products.html page.

In the age_Category.html add the following script. The method loadlistview will make a call to WEB API and retrieve categories. These categories will be added into the <select> with id as lstcat. This method will be executed when the pageinit event is executed. On the click event of the button, the Category Value and Name will be passed to the Page_Products.html.

<script type=”text/javascript”> $(document).on(“pageinit”, “#catpage”, function () {

//Pass the data to the other Page $(“#btngetproducts”).on(‘click’, function () {     var categoryId = $(“#lstcat”).val();     var categoryName = $(“#lstcat”).find(“:selected”).text();     $.mobile.changePage(“Page_Products.html”, { data: { “catid”: categoryId ,”catname”:categoryName}}); });

loadlistview();

///Function to load all categories function loadlistview() {         $.ajax({         type: “GET”,         url: “/api/CategoryProduct”,         contentType: “application/json; charset=utf-8”,         dataType: “json”     }).done(function (data) {         //Convert JSON into Array         var array = $.map(data, function (i, idx) {             return [[i.CategoryId, i.CategoryName]];         });

        //Add each Category Name in the ListView         var res = “”;         $.each(array, function (idx, cat) {             res += ‘<option value=”‘ + cat[0] + ‘”>’ + cat[1] + ‘</option>’;         });         $(“#lstcat”).append(res);         $(“#lstcat”).trigger(“change”);

    }).fail(function (err) {         alert(“Error ” + err.status);     }); } }); </script>

Just look at this piece of code:

$.mobile.changePage(“Page_Products.html”, { data: { “catid”: categoryId ,”catname”:categoryName}});

This code is responsible for passing the CategoryId and Name using JSON expression to the Page_Products.html.

Step 7: Open Page_Products.html and add the following HTML markup:

<div data-role=”page” id=”prodpage” data-add-back-btn=”true”> <div data-role=”header”>         <h1>Products in Category</h1>         <span id=”catName”></span>     </div>          <table style=”border:double” data-role=”table” id=”tblprd”>         <thead>             <tr>                 <td style=’width:100px’>                     ProductId                 </td>                 <td style=’width:100px’>                     ProductName                 </td>                 <td style=’width:100px’>                     Price                 </td>             </tr>         </thead>         <tbody>         </tbody>     </table> </div>

Here the <div> with id as prodpage is set with the attribute as data-role=page. The attribute data-add-back-btn=true, will add the BACK button on the page. On click of this button, we can move back to the Page_Category.html. This is the default style set in jQuery Mobile.

Now here the important thing is how to read values which are send from Page_Category.html in the URL, on the Page_Product.html page. Unlike ASP.NET, in jQuery there is no simple way to read the values passed from one page to another. To read these values we will create a readUrlHelper helper method. This method reads the URL and using JavaScript string functions, reads the Key/Value pairs passed from the Page_Category.html. On the Page_Products.html, add this method using <script> inside the page created using <div> with id as prodpage.

//This helper function will read the URL as //string and provides values for parameters //in the URL function readUrlHelper(pageurl, queryParamName) {     var queryParamValue = “”;

    //Get the Total URL Length     var stringLength = pageurl.length;

    //Get the Index of ? in URL     var indexOfQM = pageurl.indexOf(“?”);

    //Get the Lenght of the String after ?     var stringAfterQM = stringLength – indexofQM;

    //Get the remaining string after ?     var strBeforeQM = pageurl.substr(indexofQM + 1, stringAfterQM);

    //Split the remaining String based upon & sign     var data = strBeforeQM.split(“&”);

    //Iterate through the array of strings after split     $.each(data, function (idx, val) {         //Split the string based upon = sign         var queryExpression = val.split(“=”);

        if (queryExpression[0] == queryParamName)         {             queryParamValue = queryExpression[1];             //If the Query String has Data in Concatination then replace the             //’+’ by blank space ‘ ‘             queryParamValue =  queryParamValue.replace(‘+’, ‘ ‘);         }     });

    return queryParamValue

}

To retrieve the Products based upon the CategoryId, add a new method loadproducts inside the prodpage. This methods makes a call to the WEB API service and passes the CategoryId. This method also makes a call to the generatetable helper method to generate HTML table to display products in it based upon the JSON data received by the loadproducts method:

//Method to make call to WEB API and retrieve //Products based upon the CategoryId. function loadproducts(id) {

    $.ajax({         type: “GET”,         url: “/api/CategoryProduct/” + id,         contentType: “application/json; charset=utf-8″,         dataType: “json”     }).done(function (data) {         generatetable(data);     }).fail(function (err) { }); } //Method to generate HTML table rows from the JSON data function generatetable(data) {

    //Convert JSON into Array     var array = $.map(data, function (i, idx) {         return [[i.ProductId, i.ProductName,i.Price]];     });     var tblbody = $(“#tblprd > tbody”);

    var tblhtml = “”;     //Generate the Table for each Row     for (var i = 0; i < array.length; i++) {         tblhtml = tblhtml + “<tr>”;         for (var j = 0; j < array[i].length; j++) {         tblhtml = tblhtml + “<td style=’width:100px’>” + array[i][j] + “</td>”;        }         tblhtml = tblhtml + “</tr>”;     }

    tblbody.append(tblhtml);     $(“#tblprd”).table(“refresh”);

}

Now inside the prodpage subscribe to the pageshow event which will make a call to the readUrlHelper method and loadproducts method

var catId; $(“#prodpage”).on(“pageshow”, function (e) {     var pgurl = $(“#prodpage”).attr(“data-url”);     //Read the value for catid passed from the Page_Category.html     catId = readUrlHelper(pgurl, “catid”);     //Read the value for catname passed from the Page_Category.html    var catName = readUrlHelper(pgurl,”catname”);

   $(“#catName”).text(catName);

   loadproducts(catId);

});

The above code read the CategoryId and CategoryName passed by the Page_Category.html and based upon it the Products are displayed on the page.

Make the Page_Category.html as a startup page and run the application (IE9, FireFox or Chrome) or in Opera Mobile Emulaor.

On Page-Category.html select Categories as below:

jquery-mob-categories

When you click on Get Products , you will be navigated to the Page_Products.html with the following url:

http://localhost:5506/Page_Products.html?catid=1&catname=Food+Items

The URL contains key and value for CategoryId (catid=1) and CategoryName (catname=Food+Items)

In the Page_Products.html, the readUrlHelper method will read CategoryId and CategoryName and based upon this data, Products will be displayed as below:

jquery-transfer- values

Conclusion: In a Mobile application it is very important for the developer to manage the UI and take care of data communication across these pages. If the data passed is complex (more than one key/value pair) then the URL must be read very carefully. In this article, we saw how we can use jQuery Mobile and ASP.NET to transfer values from one page to another.

Creating users in the Authentication system

Introduction

In this blog post, I will give you an overview on how to create users in WAP and have them sign in. As you might already know, the Authentication and Authorization processes are separated into their own entities making the stack flexible enough to plug in your own custom Authentication system (eg. AD FS).

In an Express installation, the authentication is performed at the Admin and Tenant Authentication Sites (where the users enter their credentials) and the authorization is performed at the Service Management API layer. Hence, information about a user needs to be added at both these locations for users to be able to both sign in and get access to their subscriptions.

This blog will give you information on how to create a user in the Tenant Authentication Site and in the Service Management API layer.

Note: If you have other Identity Providers plugged into your system, you should create users appropriately in that system apart from creating the user in the Service Management API layer. The section on creating users in the Tenant Authentication site will not apply to you.

If you have a custom Identity Provider plugged into your WAP stack, you should follow the appropriate steps to add the user into that identity system. This section is applicable only if you use the out-of-the-box Tenant Authentication Site.

The Tenant Authentication Site uses an out-of-the-box ASP.NET Membership Provider to provide identities. Therefore, you can use the standard ASP.NET Membership APIs to create users in the database. You can find more info on Membership Provider here:  http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.aspx

The information required by the ASP.NET Membership API is specified in the App.Config. This includes specifying the Connection String to the Membership Database and some information that describes the configuration of the ASP.Net Membership Provider. Replace the Connection String in the code below to point to your database and use the appropriate authentication method.

   1: 
   2:   
   3:   
   4: 
   5: 
   6:   
   7:     
   8:       
   9:       applicationName="/" 
  19:            passwordCompatMode="Framework40"
  20:            connectionStringName="WapMembershipDatabase"
  21:            passwordFormat="Hashed" />
  22:     
  23:

Note: If you have been using the Preview version of the Windows Azure Pack, you have to update your user creation logic to use SHA-256 encryption for your password hashes (specified by the ‘hashAlgorithmType’ value in the App.Config.

Once this is done you have to call the CreateUser() method to create the user in the Membership Database. Note that I am specifying the email address as the username as expected by the ASP.Net Membership Provider.

   1: Membership.CreateUser(emailAddress, password, emailAddress);

Creating users in the Service Management API

This is the second step that enables authorization of the user. Windows Azure Pack provides you with PowerShell cmdlets that facilitate user creation in the API layer. That apart, you can also use the Admin APIClient interfaces that are available as a part of the Sample code found at http://www.microsoft.com/en-us/download/details.aspx?id=41146

Both the methods involve getting an Identity token for the Administrator, and posting a create user call to the Service Management API layer.

PowerShell

You can use the Get-MgmtSvcToken token to get the token from the Windows Authentication Site. If you are using other identity Providers, you must obtain the token appropriately.

   1: $token = Get-MgmtSvcToken -Type 'Windows' -AuthenticationSite 'https://myenvironment:30072' -ClientRealm 'http://azureservices/AdminSite'

Once you have the identity token, you can use the Add-MgmtSvcUser cmdlet to create a Tenant user.

   1: Add-MgmtSvcUser  -AdminUri 'https://myenvironment:30004' -Token $token -Name 'user@address.com' -email 'user@address.com' -State 'Active'

Note: If you are using this snippet in a test environment with self-signed certificates, don’t forget to use the –DisableCertificateValidation parameter.you shouldn’t need this in production environments that have certificates from a trusted  CA

The Admin API Client Sample provides you with an easy interface to perform all the Admin actions for the Windows Azure Pack. As mentioned above, you can download the API Client from the Windows Azure Pack: Service Management API Samples page. The following example will use a method found as a part of the API Client solution. Apart from using the API Client, you can also make a raw Http call directly to the API layer using the reference at How to Create a Windows Azure Pack Tenant User .

Use the App.Config file to specify the application settings (Alternatively, you can specify these within the main method).

   1: 
   2:   windowsAuthEndpoint" value="https://myenvironment:30072" />
   3:   
   4:   
   5:   
   6:   
   7:

Read the values from the App.Config and use the snippet below to create a user in the API layer.

Note: The TokenIssuer.GetWindowsAuthToken() method is present in the API Clients solution that can be downloaded from the Windows Azure Pack: Service Management API Samples page.

   1: string windowsAuthEndpoint = ConfigurationManager.AppSettings["windowsAuthEndpoint"];
   2: string adminDomainName = ConfigurationManager.AppSettings["adminDomainName"];
   3: string adminUsername = ConfigurationManager.AppSettings["adminUsername"];
   4: string adminPassword = ConfigurationManager.AppSettings["adminPassword"];
   5: string adminApiEndpoint = ConfigurationManager.AppSettings["adminApiEndpoint"];
   6: string username;
   7: string password;
   8: var token = TokenIssuer.GetWindowsAuthToken(windowsAuthEndpoint, adminDomainName, adminUsername, adminPassword);
   9: using (var myAdminClient = new AdminManagementClient(new Uri(adminApiEndpoint), token))
  10: {
  11:    var userInfo = new User()
  12:    {
  13:         Name = emailAddress,
  14:         Email = emailAddress,
  15:         State = UserState.Active,
  16:     };
  17:     return myAdminClient.CreateUserAsync(userInfo).Result;
  18: }

In Summary, Creation of users in WAP involves two steps:

  1. Creating users in the Authentication system – requires username, password and other information required to identify the user
  2. Creating users in the Service Management API layer – requires the username that will be provided by the Authentication system

You can download the sample at http://go.microsoft.com/fwlink/?LinkId=324039