Archive

Archive for the ‘2011 Fall DPS907’ Category

SOAP XML Web Services on WCF – with EF data model

December 2, 2011 Leave a comment

This post will teach you to add an Entity Framework data model to a WCF Service (SOAP XML Web Service).

It is the second in a two-part series. This document was most recently updated in December 2011.

.

Introduction

In the previous post, you learned how to create a simple SOAP XML Web Service, by using the WCF Service item template. Here, you will learn how to add an Entity Framework data model to a service.

The scope of this post is modest. We will NOT be presenting a general-purpose n-tier approach. Part of the reason is that we cover this topic – SOAP XML Web Services – as a minor part of the overall course, in about three class and lab sessions.

We will, however, take advantage of the overall design and approach to modern SOAP XML Web Services development. The protocol and the standards, combined with the tooling, make it surprisingly easy to get good results with a reasonable amount of learning and effort.

.

Configuration of our solution

We will use a copy of the Northwind database in our solution.

For this task, we will also organize our work by using “projects”. (In past tasks, we have used the “web site” as the container.) We need a project feature – the ability to easily hard-code a port number for the ASP.NET Development Server – to simplify our learning task.

The image to the right shows the desired result for this section of the post.

To get started, create a new project, which will simply be a solution “container”:

File > New > Project…

On the left-side navigator, under Installed Templates, choose:

Visual C# > Other Project Types > Visual Studio Solutions

In the center panel, choose Blank Solution. At the bottom of the dialog, enter an appropriate name (e.g. “WebServiceSolution”), and select a location (which will be a file system location).

The solution’s folder/directory will be a container for two projects:

  1. A web service
  2. A client that will call the web service

.

Continue by creating the web service. In Solution Explorer, right-click the solution, then choose Add > New Project…

On the left-side navigator, under Installed Templates, choose Visual C#.

In the center panel, choose WCF Service Application. At the bottom of the dialog, enter an appropriate name (e.g. “WebService”), and make sure its location is the solution folder/directory from above.

Next, we need to configure a static port for the web service. This will ease our development process. Right-click the project, and choose Property Pages. On the Web tab, choose/select a fixed/static port. Save (Ctrl+S) your changes.

Continue by creating the client. In Solution Explorer, right-click the solution, then choose Add > New Project…

On the left-side navigator, under Installed Templates, choose Visual C# > Web.

In the center panel, choose ASP.NET Empty Web Application. At the bottom of the dialog, enter an appropriate name (e.g. “Requestor”), and make sure its location is the solution folder/directory from above.

Next, we should configure a static port for the client. As above, this will ease our development process. Right-click the project, and choose Property Pages. On the Web tab, choose/select a fixed/static port. Save (Ctrl+S) your changes.

Before continuing, compare your work to the image shown above. Build/compile, to make sure that there are no errors or warnings.

Note about build/compile:

The build/compile step is important for a “project”. If you change your markup or your code, you must do a build/compile. If you don’t, your changes will not be implemented in the exe/dll.

This is different from a “web site”, which has a build/compile-on-demand feature.

.

Important WCF Service principles

You have learned some basic principles of a WCF Service, and how it implements a SOAP XML Web Service:

  • The “A” in “ABC”, address, is the publicly-accessible endpoint of your service.
  • The “B”, binding, is (obviously) HTTP, as a SOAP XML Web Service.
  • The “C”, contract is defined in the service interface, and implemented in the service class. A service contract will define the service’s operations, and a data contract will define the shape of the data that the service works with.

.

There are a number of other principles that affect our design and coding decisions, covered next.

For custom types (e.g. our own types, and/or the types that describe the Northwind entities, like Product, Supplier, Category, etc.), you must define a data contract. This enables the serializer, DataContractSerializer, to do its work. A data contract requires you to mark a class with attributes.

If the type defines a circular reference, then the data contract attribute must be:

[DataContract(IsReference=true)]

However, the framework will also support unmarked types. This enables us to use POCO (Plain Old CLR Objects) types, such as those generated by the Entity Framework editor’s code generator.

To use POCO types with an Entity Framework data model, the entity names much match.

Each property must match up too (names and types). A property’s POCO type must be concrete (i.e. it cannot be an Interface). A property cannot use the “virtual” modifier.

Incidentally, for your information, the support for unmarked types is an example of “coding by convention“. This software design paradigm is present in other areas of WCF Service development.

For best results, you must configure the context to disable (i.e. set to false) proxy generation, and lazy loading. (If you need eager loading, then use Include() in the query.)

In a client, when a Service Reference is created, the client has a definition of the web service class, and all of its operations. From the client’s perspective, return types can include:

  • Scalar / primitive types
  • Generic dictionary
  • Entity types (more on this in the next section)
  • Collections, which are materialized as arrays (of… whatever type the web service sends)

.

Implementing these principles

Now that the principles have been established, we can begin our implementation. Here is a preview of our work:

In the web service project, we will create an Entity Framework data model.

Next, we will generate entity classes. These classes must be edited, to follow the “unmarked types” principles above.

Then, we will define and implement service operations (i.e. methods).

In the client project, we will add a Service Reference. This will create a proxy of the web service. What’s interesting is that the client will have a definition for the web service class, and all of its operations, and it will have definitions for the entity types.

We emphasize here again: As a result of the Service Reference creation, the client will have definitions for the entity types. This will enable the client to work with instances (and collections) of entity types. Put another way, the client will be able to (for example) fetch a specific “Product” or “Employee”, enable the browser user to edit it, and return/save the changes, all while knowing the object’s properties and structure.

.

Scope of our in-class efforts

As noted above, we will work with a copy of the Northwind sample database. The Entity Framework data model will include three entities: Product, Category, Supplier.

The web service will include these operations:

  • Return the number of products in the data store (as an integer)
  • Return a list of supplier names (as strings)
  • Return a collection of categories
  • Return a specific category
  • Accept and save an edited/changed category

.

Data model and generated classes

In the web service project, create an Entity Framework data model. Include only these database tables in the data model:

  • Products
  • Categories
  • Suppliers

.

Build/compile your work before continuing. Note that you may have to use the NuGet Package Manager to get the EntityFramework package.

Next, generate entity classes. Use the DbContext generator. Note that you may have to download this generator template.

Then, edit the entity classes. Follow the “unmarked types” principles above:

  • Properties must be concrete types (not interfaces)
  • Properties cannot be virtual

.

Suggestion: The Category class includes a Picture property. In our example today, we will not need it. Therefore, mark that property with the [IgnoreDataMember] attribute.

(You can delete/remove the text templates – the .tt files – if you wish. If you need to re-generate your classes later, you can always do so.)

.

Work on the web service

As the comment suggests, you may want to re-factor your code, to change “Service1″ to “Service” (i.e. without the digit “1″).

In your web service interface, define the service operations (methods).

Next, implement the methods in the web service class. Pay attention to the return types. Use the general approach and technique you used while working on your WCF Web API services.

Build/compile your work before continuing, and ensure that the results are clean (no errors or warnings). Run the service, to ensure that you see the service start page.

.

Work on the client

Add a Service Reference to the project. A suggested name is “RemoteService”. The process will create a namespace – RemoteService – and classes for the web service itself (ServiceClient), as well as the entity classes.

Add an ASP.NET Web Form (Default.aspx) to the project. You will use this page to show the results of web service requests, and/or as a launcher to other pages that do the work.

Build/compile your work before continuing, and ensure that the results are clean (no errors or warnings). View the page in a browser after you do this.

.

Summary and wrap-up

The .NET Framework, and Visual Studio, work together to enhance your productivity when creating a SOAP XML Web Service.

Get more practice by completing Lab 5.

.


.

.

.

SOAP XML Web Services on WCF – introduction

November 30, 2011 Leave a comment

This post will introduce you to SOAP XML Web Services on WCF.

It is the first in a two-part series. This post uses an in-memory (per-instance) data store. The next post will use a persistent data store, accessed through the Entity Framework.

This document was most recently updated in November 2011.

.

Introduction

At this point in the semester, you have some experience with one of the two styles of web services, RESTful. SOAP XML Web Services is the other style that you’ll encounter. Here are some key ideas that will help you get oriented with SOAP XML Web Services:

  • The plain-text data interchange format is XML
  • The XML conforms to SOAP
  • Often, a SOAP XML Web Service is published on a single (URL) endpoint
  • The service includes one or more methods; each method may accept parameters, and may return data
  • Service discovery is built in to the specification/standard
  • Requestors use GET or POST requests to interact with the web service
  • Requestors can use the service discovery feature to create a proxy class that models the web service (in fact, this is typical with most programming platforms)

.

On the Microsoft Web Platform, WCF technology is used to create SOAP XML Web Services. Version 4 of the .NET Framework improved the design and coding experience, and we will use version 4 in this two-part series. Scan the following article, and read about the WCF and web services topics:

What’s new in WCF 4 article

FYI – legacy versions of the Microsoft Web Platform used “asmx” item types to host SOAP XML Web Services. They were easy to create, but they were a solution for a very limited set of use cases. Do not use “asmx” item types for new web services. Scan the following article to read about the differences:

Legacy info on the difference between asmx and wcf web services

.

What is a WCF Service?

In Visual Studio 2010, a SOAP XML Web Service is created as a WCF Service. The following will introduce WCF Service concepts and topics.

A WCF Service is a program that exposes one or more endpoints, each of which exposes one or more service operations.

An endpoint specifies:

  1. An address where the service can be found (e.g. http://host.domain.com/contacts.svc)
  2. A binding that tells the client how to communicate with the service (e.g. HTTP)
  3. A contract that defines the service’s functionality (e.g. it will do “this task” and “that task”)

.

Creating a WCF Service

You create a WCF Service in Visual Studio 2010. It is an (item type) that you can add to a Project or a Web Site.

A Web Site is software and resources that you create in a specific folder/directory. A Web Site must be hosted on a web server (e.g. either the ASP.NET Development Server, or a Microsoft Web Platform server). You can deploy a Web Site using a simple copy operation. The web server will compile and execute an endpoint upon request.

.

A Project is software and resources that you create in a specific folder/directory. A Project can be hosted on a web server, or on another kind of host (e.g. an executable, or a Windows Service). You must compile (build) the project (which creates an executable, either a dll or an exe) before you deploy it.

.

The default WCF Service item type (that you create with Visual Studio 2010) will create three software objects:

1. A publicly-accessible endpoint

2. A C# code-behind for the (above) publicly-accessible endpoint, which implements…

3. A C# interface that describes the “service contract” and “service operations”

.

The following sections include important information about each object.

.

Publicly-accessible endpoint

You pick the name (e.g. “Contacts”), it adds a “svc” extension (e.g. “Contacts.svc”).

You don’t add code to this endpoint.

.

C# code-behind for the (above) publicly-accessible endpoint

This code file is located in the App_Code folder/directory.

For example, continuing to use the name above, it will be called “Contacts.cs”.

.

C# interface that describes the “service contract” and “service operations”

A “service contract” is an agreement to define and provide a number of “service operations”. An interface is used as the code container for both. By convention in the .NET Framework, an interface name begins with an upper-case letter “I”. The second letter is also upper-case.

For example, continuing to use the name above, the interface will be called “IContacts.cs”.

Each “service operation” is a method. The method will have a return value, and a parameter list.

Although not required, it is a best practice to use an interface to declare the “service contract” and “service operations”.

What is the relationship between the interface and the (class) implementation?

  • The interface defines the service’s methods.
  • The implementation contains code for these methods.

.

Method return values and parameters

As noted earlier, a method will have a return value, and a parameter list.

The types must be serializable (obviously).

Primitive types are serializable by default. Many other types in the .NET Framework are also serializable by default.

If you create your own types (e.g. Product, Supplier, Contact, Address, Customer, etc.), then you typically “mark” your types (with “attributes”) to define a “data contract”.

A “data contract” is an agreement to define and provide a number of “data members”. The default WCF Service item type adds the “data contract” to the interface code container.

For example, continuing to use the name above, it will be added to “IContacts.cs”.

Each type is a class (as it always is). You typically add the [DataContract] attribute to the class.

Public properties are used to define the publicly-accessible data members.

Each serializable property gets the [DataMember] attribute.

.

Creating a client requestor

When working on RESTful web services earlier in the semester, you learned that you could interact with your web service by using a browser, or an HTTP requestor like your Lab 1, Fiddler, or your service’s HTTP Test Client.

With SOAP XML Web Services, some of the same techniques can be used. However, the message packaging format is SOAP XML, which can be inconvenient to manually enter into a request.

Another approach is to create a client requestor. Conceptually, it will be similar to your Lab 1, because it will be able to make a request to the web service, and receive (and process) the response. That’s what we’ll do here, by creating an ASP.NET Web Forms client requestor.

The key concept is to create a proxy, which will “model” the web service. Visual Studio has built-in tooling for this. Right-click the (web site) root, and select “Add Service Reference”. This will enable you to connect to the web service, discover its functionality, and have Visual Studio create a local proxy of your web service’s classes.

Then, in your web form code-behind, you simply 1) create an instance of the proxy, and 2) call its methods.

.

On your own – create a web service, and a client requestor

Your task:

In a new empty web site, create a service with two methods.

Method 1 will simply return your name (firstname last name) as a string.

Method 2 will return a collection (of strings) of your current-semester Seneca course codes (e.g. WSA500, SYS566, etc.).

In another new empty web site, create a (Default.aspx) web form that will call and display the data from the web service. Use Label web server controls for the data.

.

Preview of the topics we’ll cover in the next lecture

A blogger’s two-part series:

service create, and service consume (from Silverlight)

Another blogger’s article, some ideas are OK

Another blogger’s article on “what is an interface

WCF and EF on StackOverflow - data contracts

.

Reference articles

Learn C# page

Interfaces - C# Programming Guide

Inheritance - C# Programming Guide

C# Language Fundamentals

.


.

.

.

Creating sequence diagrams

October 31, 2011 Leave a comment

In this document, we briefly describe a few different ways to create sequence diagrams.

This post was most recently updated in October 2013. It is intended for programmers in a degree-level academic program that focuses on software development. This post will likely be updated a few times in the near future, to add more detail and information.

.

A brief survey of sequence diagram creation toolsets

Students in Seneca’s ICT software development programs learn to use Rational Rose to create sequence diagrams, and other software system design modeling assets.

Visual Studio 2012 Ultimate Edition now includes tooling that enables the creation of sequence diagrams.

Online, there are many tools that are offered, in both free and pay-for versions. In the following section, we’ll look at one of these tools.

.

Websequencediagrams.com

Websequencediagrams.com is an online tool that enables you to create and save sequence diagrams. Its syntax is easy and discoverable. It enables you to save your work in a PNG image, a PDF, or as source text. It also provides online tooling, via an API.

A recent post by the author (Web service security principles – OAuth 2.0 example) included two sequence diagrams.

The source text for the first diagram is below:

.

participant Resource\nOwner as RO
participant "Web\nBrowser" as ClientUI
participant Client\nApp as Client
participant Authorization\nServer as AS
participant Resource\nServer as RS

RO->ClientUI: [1] want protected resource
activate RO
activate ClientUI

ClientUI->Client: [2] GET protected resource
activate Client

Client-->ClientUI: [3] HTTP 302 redirect
deactivate Client
deactivate ClientUI

ClientUI->AS: [4] GET authentication UI
activate ClientUI
activate AS
AS-->ClientUI: [5] respond with authentication UI

ClientUI-->RO: [6] view authentication UI

RO->ClientUI: [7] enter credentials
ClientUI->AS: [8] POST the credentials

AS-->ClientUI: [9] HTTP 302 redirect to redirection endpoint
deactivate AS
deactivate ClientUI

ClientUI->Client: [10] GET auth grant exchanged
activate ClientUI
activate Client

Client->AS: [11] POST request access token
activate AS

AS-->Client: [12] respond with access token
deactivate AS

Client-->ClientUI: [13] HTTP 302 redirect
deactivate Client
deactivate ClientUI

ClientUI->Client: [14] GET protected resource
activate Client
activate ClientUI

Client->RS: [15] GET protected resource (with access token)
activate RS

RS-->Client: [16] respond with the resource
deactivate RS

Client-->ClientUI: [17] render resource in browser

deactivate Client
ClientUI-->RO: [18] view the resource
deactivate ClientUI

deactivate RO

.

The source text for the second diagram is below:

.

participant Resource\nOwner as RO
participant "Web\nBrowser" as ClientUI
participant Client\nApp as Client
participant Authorization\nServer as AS
participant Resource\nServer as RS

RO->ClientUI: [1] want protected resource
activate RO
activate ClientUI

ClientUI->Client: [2] GET protected resource
activate Client

Client->RS: [15] GET protected resource (with access token)
activate RS

RS-->Client: [16] respond with the resource
deactivate RS

Client-->ClientUI: [17] render resource in browser

deactivate Client
ClientUI-->RO: [18] view the resource
deactivate ClientUI

deactivate RO

.

.

.

.

.

.

.

Brief introduction to securing a WCF Web API service with an access token

October 30, 2011 Leave a comment

This post is a brief introduction to securing a WCF Web API service with an access token.

This document was most recently updated in October 2011. It is intended to be used by entry-level web service programmers.

.

Overview of the scenario

Token-based schemes are often used for web services that require security. Recently, in class/lecture, we described many of the relevant security principles, and the implementation components, using the OAuth 2.0 Authorization Protocol as an example.

This post includes code that illustrates the bare essentials of handling an access token.

Warning – The code below is NOT a reference sample, or a best practice example. It simply illustrates the concept, in a clearly-understandable manner. Also, it does NOT deal with authentication and authorization issues, authorization stores, or the other “moving parts” that a full and complete solution includes.

.

Sample service code

Use your template to create a new WCF Web API service. Code the service class as follows:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
// Web service namespaces
using System.ServiceModel;
using System.ServiceModel.Web;
// Additional namespaces
using System.Net;
using System.Net.Http;
using Microsoft.ApplicationServer.Http.Dispatcher;
using System.Net.Http.Headers;

[ServiceContract]
public class Operations
{
    // Custom authorization token
    public string customToken { get; set; }

    // Collection of access tokens, which will be an in-memory "authorization store"
    protected List<string> AccessTokenStore;

    // Constructor
    public Operations()
    {
        this.customToken = HttpContext.Current.Request.Headers["X-ICTtoken"];

        // Un-comment the following if you want to protect the whole service
        //if (this.customToken != "whatever")
        //    throw new HttpResponseException(HttpStatusCode.Forbidden);

        // Create an in-memory "authorization store", with a few access tokens
        AccessTokenStore = new List<string>();
        AccessTokenStore.Add("triUt6ustoeQ");
        AccessTokenStore.Add("KOEn4Ejouqle");
        AccessTokenStore.Add("rIuv5u7hoeno");
        AccessTokenStore.Add("y7UcIeJ9eCIa");
        AccessTokenStore.Add("Joestievief9");
    }

    // Remove this method from an in-production (deployed) web service
    [WebGet(UriTemplate = "")]
    public string ServiceRoot()
    {
        return "Append /test to the URI to use the HTTP Test Client";
    }

    [WebGet(UriTemplate = "example1")]
    public List<string> Example1(HttpRequestMessage request)
    {
        // Get the authorization header
        AuthenticationHeaderValue auth = request.Headers.Authorization;
        // The scheme should be "Bearer", and the parameter should be the access token

        if (auth == null)
        {
            throw new HttpResponseException(HttpStatusCode.Unauthorized);
        }
        else
        {
            // Create a response object
            List<string> response = new List<string>();
            // Report the results
            response.Add("The authorization scheme was: " + auth.Scheme);
            response.Add("The parameter was: " + auth.Parameter);

            // Check if the access token is in the store
            if (AccessTokenStore.Find(t => t == auth.Parameter) == null)
            {
                response.Add("The access token was NOT FOUND in the authorization store");
            }
            else
            {
                response.Add("This is a valid access token");
            }

            return response;
        }
    }

}

.

Test your service

Run the HTTP Test Client for the service.

Request the “example1″ URI. It should respond with 401 unauthorized.

Now, add an “authorization header”:

Authorization:Basic foobar

The response should appear as follows:


<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <string>The authorization scheme was: Basic</string>
  <string>The parameter was: foobar</string>
  <string>The access token was NOT FOUND in the authorization store</string>
</ArrayOfString>

.

Next, change the authorization header:

Authorization:Bearer rIuv5u7hoeno

(or one of the valid authorization codes)

The response should appear as follows:


<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <string>The authorization scheme was: Bearer</string>
  <string>The parameter was: rIuv5u7hoeno</string>
  <string>This is a valid access token</string>
</ArrayOfString>

.


.

.

.

Web service security principles – OAuth 2.0 example

October 30, 2011 Leave a comment

This post discusses web service security principles, using the OAuth 2.0 Authorization Framework.

This document was most recently updated in October, 2013. It is intended for entry-level web service programmers.

.

Introduction to the scenarios

This post describes the use of a web service to deliver resources to requestors. The web service’s resources will be protected, and requestors must use the OAuth 2.0 Authorization Framework. Two scenarios are described:

1. The first scenario covers the use case where a client app, which does not yet have a valid access token, requests a protected resource.

2. The second scenario covers the use case where a client app, which has a valid access token, requests a protected resource.

A separate client app, perhaps an ASP.NET web app, would be used to request resources from the web service. Users of the client app will be able to request their own resources after authenticating.

.

OAuth 2.0 Authorization Framework information

The OAuth 2.0 Authorization Framework is described in draft-ietf-oauth-v2.

A gentle overview of OAuth can be found in this Wikipedia article.

It is currently a “draft” specification, RFC 6749, and is on the standards track. A related RFC 6750 covers access token usage.

OAuth defines four roles:

oauth-resource-ownerResource owner

An entity (e.g. an end user, typically a person, or a proxy such as credentials in a secure/trusted store) capable of granting access to a protected resource.

.

oauth-resource-serverResource server

A server that hosts a protected resource. It responds to requests by validating an access token.

.

oauth-client-appClient

Also known as a client app, this is an application that makes requests for a protected resource, on behalf of the resource owner, and with its authorization.

.

oauth-authorization-serverAuthorization server

A server that authenticates resource owners, client apps, and issues access tokens.

.

OAuth is a framework that enables a client app to use an access token to request a protected resource. The access token is issued to the client app by an authorization server, with the approval of the resource owner.

There are two defined types of client apps:

  1. Confidential – Capable of maintaining confidentiality of client app credentials.
  2. Public – Not capable of maintaining confidentiality of client app credentials.

.

There are four defined flows or scenarios that enable a resource owner to authorize the issuance of an access token:

  1. Authorization code – A resource owner is able to authenticate directly with an authorization server, and passes on an “authorization code” to the client app.
  2. Implicit – For client apps which are implemented in a browser using a scripting language (such as JavaScript).
  3. Resource owner password credentials – Where there is a high degree of trust between the resource owner and the client app (e.g. a trusted client app on a resource owner’s mobile device).
  4. Client credentials – For access to protected resources that are under the control of the client app (and not any specific/individual resource owner).

.

This post will cover the first flow/scenario, “authorization code”, with a “confidential” client.

.

Terminology and assumptions for the scenarios

This post uses terminology from the OAuth documents, plus the following:

UI = user interface

Web browser = an HTTP requestor application that renders HTML content

Client app = web app, an executable that runs on a web server (this is the OAuth ‘client’)

.

The following diagram is a high-level overview of the software components in the scenarios.

Web service as a resource server v2

.

The authorization server and the resource server share an authorization store. The authorization store holds the following kinds of information collections:

  • resource owner credentials
  • client app credentials (which has a client app identifier that will be used by the web browser)
  • authorization grant (which has a limited lifetime and scope)
  • access token (which has a limited lifetime and scope)

.

Notice that a client app is a distinct entity or construct. It must have its own identity that’s separate from a resource owner. A client app can be used by different resource owners.

.

For the following scenarios, the reader can assume that the resource owner credentials and the client app credentials already exist. Further, the authorization server has the programming, UI, and endpoints that enable the maintenance of these credentials.

The reader can also assume that the authorization server has the programming, UI, and endpoints that enable the maintenance of authorization grants and access tokens.

.

Scenario – first request for a protected resource

This scenario covers the use case where a client app, which does not yet have a valid access token, requests a protected resource.

This scenario is documented on a sequence diagram, shown below. Each signal is identified with a number in square brackets, [#], and you will find them in the text that follows.

.

How was this sequence diagram created? Click here and read this post for details. 

.

A resource owner, using a web browser, begins interacting with content in a client app. This begins a new “session” between the resource owner‘s user-agent (the web browser), and the client app.

The resource owner performs an action (e.g. clicks on a link or a button) [1] in the web browser, which causes a “GET protected resource” request to be created. The web browser sends the request to the client app [2].

Note: The web browser does NOT typically have/show the protected resource URIs from the resource server. The client app typically publishes (HTML) links that are in its domain, and maintains the mapping/lookup in its executable code.

In other words, you will typically NOT see this kind of link in the HTML markup of the web browser:

http://resourceserver.com/customer/3/

Instead, you will see this kind of link:

http://clientapp.com/customer/3

.

The client app asks “does this session have a valid access token?”

The answer will be “no”, because this is the first request for a protected resource.

Next, the client app asks “does the request from the web browser have a valid authorization grant?”

Again, the answer will be “no” (because this is the first request for a protected resource).

Consequently, the following sequence will be initiated, which will result in the acquisition of a valid access token:

  1. The resource owner authenticates with the authorization server
  2. The authorization server delivers an authorization grant to the client app
  3. The client app requests that the authorization server exchange the authorization grant for an access token

.

Before continuing, the essence of the original “GET protected resource” request must be retained. The sequence (below) will include three (3) HTTP 302 redirects, and we will be unable to persist the original request in a query string parameter.

There are several state persistence schemes available to us. For example, the client app can save this information in session state. Or, it can be sent (in the following response) as a web browser cookie. Whatever scheme you select as the programmer, you just need to retrieve the value later, when you need it.

.

Sequence step 1: The resource owner authenticates with the authorization server

The client app responds back [3] to the web browser with the following:

  1. a 302 redirect status code
  2. a “location” header with the URI of the authorization server‘s authentication UI, and the following query string key-value pairs…
    • response_type=code – for a typical interaction
    • client_id= the client app identifier
    • redirect_uri= a previously-established (between the client app and the authorization server) “redirection endpoint”

.

The web browser creates a new request, [4] “GET authentication UI”, and sends it to the (above) URI of the authorization server‘s authentication UI.

Note: The authorization server‘s authentication UI may be a specially-created page/interface, solely for the use of resource owners who want to authorize a client app. Alternatively, it may be the page/interface that is used by other general interactive users of the resource server.

.

The authorization server validates the request (to ensure that all required key-value pairs are present), and responds with the authentication UI [5], which will typically be an HTML form. (The key-value pairs are retained, in the URI query string, or in the authorization server‘s state management and persistence system.)

.

The resource owner views the form [6], enters their credentials [7], and submits them (typically with a button click). The web browser creates a [8] “POST resource owner credentials” request, and sends the request to the authorization server.

After successfully authenticating, the authorization server responds back [9] to the web browser with the following:

  1. a 302 redirect status code
  2. a “location” header with the URI of the client app‘s redirection endpoint, and the following query string key-value pair…
    • code= the authorization grant (known as the authorization code) that was generated by the authorization server

.

Sequence step 2: The authorization server delivers an authorization grant to the client app

The web browser now has a valid authorization grant.

Using the URI from the response’s “location” header, the web browser creates a new request, [10] “GET authorization grant exchanged”, and sends it to the client app.

The client app inspects the request, which was received on the redirection endpoint, and asks “does the request from the web browser have a valid authorization grant?”

The answer will be “yes” (because a valid authorization grant was received on the redirection endpoint).

Before responding to the web browser, the client app continues with the following.

.

Sequence step 3: The client app requests that the authorization server exchange the authorization grant for an access token

A valid authorization grant can be exchanged for an access token. Therefore, the client app will create a new request, [11] “POST request access token“, and send it to the “token endpoint” on the authorization server. The request includes:

  1. an “authorization” header, which includes the client app credentials
  2. HTML form-encoded key-value pairs for the following parameters…
    • grant_type=authorization_code
    • code= the authorization grant (known as the authorization code) that was generated by the authorization server
    • redirect_uri=the previously-established (between the client app and the authorization server) redirection endpoint

.

The authorization server will inspect the request. It validates the client app credentials (with a lookup to the authorization store). It validates the authorization grant (with a lookup to the authorization store). If successful, it responds with an access token [12].

The access token consists of a number of parameters, serialized as a JSON object, in the message body of an HTTP 200 response. The parameters include:

  • access_token – string – the actual access token
  • token_type – string – for example, “bearer”
  • expires_in – integer, optional – the lifetime, in seconds, of the access token

.

Now that the client app has a valid access token, it typically persists it in session state.

The client app is now ready to respond to the “GET authorization grant exchanged” request from the web browser (in sequence step 2 above).

The client app creates a response [13] that includes the following information, and sends it to the web browser:

  1. a 302 redirect status code
  2. a “location” header with the URI of the original “GET protected resource” request (which may be retrieved from a web browser cookie, or the client app‘s session state)

.

Upon receipt, the web browser creates a [14] “GET protected resource” request, and sends it to the client app.

As above (when we started this journey), the client app asks “does this session have a valid access token?”

This time, the answer will be “yes”.

The client app creates a [15] “GET protected resource (with access token)” request, and sends it to the resource server. It includes:

  1. a request URI for the actual resource
  2. an “authorization” header that includes 1) the token_type, and 2) the access_token values

.

After validating the access token, the resource server responds back to the client app with the requested resource [16].

The client app now has the protected resource that was originally requested. The protected resource is rendered for the web browser [17], where it can be viewed [18] by the resource owner.

.

Scenario – subsequent requests for protected resources

This scenario covers the use case where a client app, which has a valid access token, requests a protected resource.

This scenario is documented on a sequence diagram, shown below. Each signal is identified with a number in square brackets, [#], and you will find them in the text that follows. The numbers used for the signals are the same as you saw in the first sequence diagram (but signals 3 through 14 inclusive aren’t there, because this scenario’s client app has a valid access token).

.

The resource owner performs an action (e.g. clicks on a link or a button) [1] in the web browser, which causes a “GET protected resource” request to be created. The web browser sends the request to the client app [2].

As above, the client app asks “does this session have a valid access token?”

As you would expect, the answer will be “yes”.

The client app creates a [15] “GET protected resource (with access token)” request, and sends it to the resource server. It includes:

  1. a request URI for the actual resource
  2. an “authorization” header that includes 1) the token_type, and 2) the access_token values

.

After validating the access token, the resource server responds back to the client app with the requested resource [16].

The client app now has the protected resource that was originally requested. The protected resource is rendered [17] for the web browser, where it can be viewed by the resource owner [18].

.

.

.

.

.

.

.

.

.

.

Handle hypermedia in a WCF Web API service

October 11, 2011 Leave a comment

You have worked with XML and JSON in WCF Web API services. This post will introduce you to the handling of hypermedia.

Read more…

WCF Web API service, with EF data model, supporting POST, PUT, DELETE (on an ASP.NET web site)

October 3, 2011 Leave a comment

This post builds upon the topics in WCF Web API service with an Entity Framework data model. We add the ability to support POST, PUT, and DELETE operations.

Read more…

Follow

Get every new post delivered to your Inbox.

Join 43 other followers