Token-based Authentication – Part 2

OpenID Connect

The OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.

OAuth2 & Authentication.png

So what is the relationship between OpenID Connect and OAuth 2?

OAuth is for authorization. We want to give an application access to a third part resource on our behalf. So we are delegating an access token that can hold information for resource server.

But we have some problems with OAuth 2 Authentication:

oauth2 problem.png

OpenID Connect is a specification that aims at the target that we don’t need to know any specifics about the authentication provider. The OpenID Connect is built on OAuth. They use the authorization code flow for server-based applications and the implicit flow for client based applications.

OpenID Connect Flows.png

 

OpenID step 1.png

scopes-claims

 

openid-authentication-step-2

 

openid-consent

 

openid-authorization-response

openid-token-request

openid-token-response

Except for the access token, the OpenID Connect has an ID Token from the token endpoint. There are four very import claims in there.

  • Issuer: OpenID Connect provider
  • Subject identifier the user
  • Audience identifier whom this token is for
  • expiration

The token is signed obviously, so the client must validate the token at this point. So once the client has validated the ID Token, he knows that the response came back from the authorization server was actually for his own application.

OpenID Connect UserInfo request.pngOpenID Connect UserInfo response.png

bearer token.png

Token-based Authentication – Part 1

 

purpose-of-a-security-token

 

The purpose of a security token is real to produce a data structure that contains information about the issuer, recipient and the subject (claims)

The consumers know the key that the issuer uses for signing the token and can use that key to validate the token, and if the validation succeeds, the resources can use the claims inside of the token.

JWT Structure and Format

JWT.png

JWT Structure.png

How to Product a Token

Producing a token.png

We use a class called the JWTSecurityTokenHandler to serialise the token. And then we can just transmit that via arbitrary means we can put on a header in an HTTP request, in the query string or even put it in a cookie.

consuming a token.png

JWT is easy to

  • create
  • transmit
  • parse
  • validate

Mandatory in OpenID Connect

OAuth2

From the high-level overview, the problem OAuth wants to solve is

Resource Owner (human owns the backend data) may run an application (Client) to access the backend data

oath2 player.png

OAuth2 Flows – with User Interaction

Authorization Code Grant ( server=rendered web applications )

  • Web application Clients
    1. Request authorization
    2. Request Token
    3. Access resource

Implicit Grant (native applications)

  • Native / Local clients
    1. Request authorization & token
    2. Access resource

Resource owner password Grant

  • Trusted clients
    1. Request token with resource owner credentials
    2. Access resource

Client Credentials Grant

  • Client to Service communication
    1. Request token with client credentials
    2. Access resource

OAuth2 Flows in Details

Authorization Code Grant

authorization code grant.png

Step 1a: Authorization Request

authorization request.png

We are using a certain query string format that is called the client ID. The clients are trying to register at the authorization server. Once the client is authorised, the client will be redirected to the resources.

When the GET request arrives in our authorization server:

Step 1: Authentication

google authentication.png

Step 2: Consent

consent-screen

 

If the user clicked the Allow Access button, then the authorization server will redirect to the callback URI, presenting the application with a so-called authorization code

authorization response.png

The authorization code is not the actual access token. We don’t transmit the ex-token prevent the token leak over the agent.

token-request

token-responseThe last step is that the client has a direct communication between the Authorization Server and the Client Application. The Client Application has authenticated with the Authorization Server. And then, the client application sends the authorization code to the authorization server. If the authorization server is happy with the code, the client application will request authorization in the first place. The authorization server sends back a token response.

There are two types of tokens. One is called access token that is a short-lived token. Another type of token is called refresh token. The fresh token is optional.

Access and Refresh Token

access token.png

The access token is short-living token. What will happen when the access token has expired?

Option 1: start the trip again to the authorization server

Option 2: using the refresh token that is a long lift token. The application can use the refresh token to request new access tokens.

refreshing the token.png

Client Mangement

Becuase of the refresh token has very long life, many authorization-serves provide a self-service way to revoke the access for the client application.

Implicit Grant

When we implement the Implicit Grant, we don’t have to give our master key to the application, but rather to the authorization server.

implicity grant step1.png

implicity grant step2.png

IMPORTANT: We don’t have the callback question mark,  we have a callback hash, and that is called hash fragment encoded. Meaning these parameters on the URL will never be sent to some server. So everything after the hash fragment is intended for local consumption and does NOT send to a server by a browser.

implicit grant step3.png

Resource Owner Password Grant

Resource Owner Password grant is considered for trusted applications or even trusted devices. But this time the client applications collect the credentials itself instead of the authorization server.

resource owner password step 1.png

resource owner password step 2.png

resource owner password step 3.png

Resource Owner credentials are exposed to client

Still better to store access/refresh token on device than password

Client Credentials Grant

client credential grant.png

Web API Security Architecture

Authentication & Authorization

Authentication and Authorization in Web API V1:

security-pipeline-v1

In V1, the authentication layer is tied with IIS and HttpMessageHandler. In other words,  the authentication is highly dependent on the OS platform and we cannot take our API and host it, like outside of IIS.

Web API V2 Security Pipeline:

security pipeline v2.png

OWIN is an open source project and Microsoft builds its framework on top of that specification called Katana. OWIN is like a hosting adapter. So regardless if Web API runs in IIS or self-host, it’s the  OWIN adapter which extracts away the Web API from its actual host.

In the Web API V2, Microsoft uses the OWIN to implement the authentication methods, for example, token-based authentication or support for social login providers like Goole or Facebook, it’s all happening now at the OWIN layer.

There is another situation if we do not want to implement the authentication in the low-level OWIN layer, we can move our authentication logic closer to the controllers. And that’s so-called authentication filter.As we’ll see, most of the time authentication filters are used to invoke OWIN-based authentication logic.

Authorization Filter is the place in the pipeline where we can recheck the request before actual business logic like model binding, validation, and the controller itself.

OWIN/Katana Hosting

Classic Hosting

classic host.png

OWIN Hosting

owin system hosting.png

Pure OWIN Hosting

pure owin hosting.png

When we are building the modern Web API application, we should build them in a way that they do not have any security dependencies on a specific host, but rather on the OWIN layer.

OWIN Middleware

owin-middleware

katana middleware.png

MessageHandler

MessageHandlers are kind of a low-level interface as well you basically derived from the class called DelegatingHandler. We can implement one or override one method called SendAsync

MessageHandler.png

we get passed in the request, and then we get back the response, and in between, we can do all kinds of logic and manipulation. For example, we can use the very popular framework called Thinktecture AuthenticationHandler, which is part of the Thinktecture.IdentityModel, which had basically all the features of passing a header, passing a query string, passing a cookie, and turning that into a claims principle.

thinktecture authentication handler.png

 

MessageHandlers in Web API V2 has not used anymore for building authentication.

Authentication Filter

Authentication Filter is part of the Web API framework, so they know about routes and controllers, action methods and etc. They can be used to build Web API specific authentication methods. It’s more used for invoking Katana Authentication Middleware.

Technically, we register the middleware in the pipeline and we can use it from within the Web API. For example:

authentication-filter

This line of code means that we are going to use the Bearer Authentication Middleware for all our controllers and the implementation of a token, typically a chart-based token.

Authorization Filter

Determines if a resource needs authentication

  • [AllowAnonymous] to skip authorization for an action
  • emits the 401 status code, if unsuccessful

authorization-filter

Accessing the Client Identity

In the Web API V2, we use a new concept: RequrestContext

  • hangs off the HttpRequestMessage
  • ApiController.User is now a shortcut to the request context
  • potentially the user could be null

 

C# Events, Delegates and Lambdas

The Role of Events, Delegates and Event Handlers

Before we embark on creating delegates and events, we are going to discuss the relationships between them.

tan-can

The role of Events

The fundamentals of what events are, and what they are used for.

  • Events are notifications
  • Play a central role in the .NET framework
  • Provide a way to trigger notifications from end users or from objects

Events signal the occurrence of an action/notification. When objects raise events, they don’t need to explicitly know the object that will handle the event.

Most events are going to have EventArgs. When events are triggered, the event data that gets routed from point A to point B.

The Role of Delegates

In fact, without delegates, events well, they wouldn’t be useful at all because we wouldn’t have a way for the event data to get from point A, the event raiser, to the point B, the event listener.

delegate

delegate_example

The Role of Event Handlers

event-handler

Creating Delegates, Events and EventArgs

Creating a Delegate

Using the delegate keyword to define custom delegates.


public delegate void WorkPerformedHandler(int hours, WorkType workType);

creating_delegates

Handler Method:


public delegate void Manager_WorkPerformed(int hours, WorkType workType);

The parameters of delegates must match the parameters in the handler method.

delegate-base-class

Multicast Delegate:

  • Can reference more than one delegate function
  • Tracks delegate references using an invocation list
  • Delegates in the list are invoked sequentially

Creating a Delegate Instance

creating-delegate-instance

Invoking a Delegate Instance

invoking-a-delegate-instance

– Add Multiple Delegate to an Invocation List

multicast-delegates-to-an-invocation-list

Returning a Value Using a Delegate

delegate-return-value

Defining an Event

Events can be defined in a class using the event keyword. For instance:

public event WorkPerformedHandler WorkPerformed;

event-definition

event-with-add-or-remove

define-event

Once an event has been defined, we need a way to raise the event. Now we are going to jump into some more details on how we can actually raise these events.

Raising Events

Events are raised by calling the event like a method:

if (WorkPeerformed != null){
WorkPerformed(8, WorkType.GenerateReports);
}

Another option is to access the event’s delegate and invoke it directly:

WorkPerformedHandler del = WorkPerformed as WorkPerformedHandler;
if(del != null){
del(8, WorkType.GenerateReports);
}

An example of raising event:

raising-event

Creating an EventArgs Class

eventargs

We can create a custom EventArgs by inheriting the EventArgs classIn the custom EventArgs, we should pass the necessary parameters via its contribution.

EventHandler.png

After creating the new EventArgs, we can use EventHandler<T> to build our event for Worker class.

Handling Events

define and attach event handlers.png

Attach Event Handler.png

Delegate Inference

delegate inference.png

Lambdas, Action and Func<T, TResult>

Lambdas and Delegates

Lambdas provide a concise way to define handler methods as you work with events and delegates.

lambda event.png

Action<T> and Func<T,TResult>

Action and Func are both useful build-in delegate in the .NET Framework, the only difference between them is that Func <T,TResult> return a value.

The Example of Action<T>:

action T.png

The Example of Func<T, TResult>:

Func T.png

Chapter 2. Mongo DB CRUD and Mongo Shell – Part One

2. CRUD and Mongo Shell

MongoDBCRUD which stands for an operation of creating, read, update, and delete documents.

In Mongo DB, we called these operations in different names:

Create – Insert
Read – Find
Update – Update
Delete – Remove

All of these operations are function-based methods, which means that Mongo DB’s CRUD operations exist as methods/functions in programming language APIs, not as a separate language like T-SQL.

2.1 Create Operations

Create or insert operations add new documents to a collection. The MongoDB provides the following methods:

  • db.collection.insert()
  • db.collection.insertOne() new in version 3.2
  • db.collection.insertMany() new in version 3.2

In MongoDB, insert operations target a single collection. All write operations in MongoDB are atomic on the level of a single document

For more information on atomicity, transaction and concurrency control will be discussed in later chapters.

insert

In the new version 3.2, there are two functions are added – insertOne() and insertMany(). What’s the differences between three of these functions?

Behavior

If the collection does not exist, insert operations will create the collection.

Returns

Insert(): returns a WriteResult object, like WriteResult({“nInserted”: 1 }). The nInserted field specifies the number of documents added. If the operation encounters an error, the WriteResult object will contain the error information.

InsertOne(): returns a document with the status of the operation:

{
    &amp;quot;acknowledged&amp;quot;: true,
    &amp;quot;insertedId&amp;quot;: ObjectId(&amp;quot;5742045ecacf0ba0c3fa82b0&amp;quot;)
}

InsertMany(): returns a document with the status of the operation:

{
    &amp;quot;acknowledged&amp;quot; : true,
    &amp;quot;insertedIds&amp;quot; : [
        ObjectId(&amp;quot;57420d48cacf0ba0c3fa82b1&amp;quot;),
        ObjectId(&amp;quot;57420d48cacf0ba0c3fa82b2&amp;quot;),
        ObjectId(&amp;quot;57420d48cacf0ba0c3fa82b3&amp;quot;)
    ]
}

2.2 Query Documents

Query Method

  • db.collection.findOne()
  • db.collection.find() this method returns a cursor to the matching document.

db.collection.find(<query filter>, <projection>)

Return only one document

If we just want to get one document from your collection. db.collection.findOne() is the best choice.

findOne

Select All Document in a Collection

db.collection.find({}) or db.collection.find()

Specify Query Filter Conditions

Specify Equality Condition

<field> : <value> expressions are used to select all documents that contain the <field> with the specified <value>:

{<field1> : <value1>, <field2> : <value2>, …}

Specify Conditions Using Query Operators

A query filter document can use the query operators to specify conditions in the following form:

{ <field1>: { <operator1>: <value1> }, … }

$in : Either … Or … operator (comparison operators)

collection.find

OR Conditions

$or : a logical OR conjunction so that the query selects the documents in the collection that match at least one condition.

orCondition

AND Conditions

Implicitly, a logical AND combination connects the clauses of a compound query so that the query selects the documents in the collection that match all the conditions.

andCondition

Specify AND as well as OR Conditions

and_orCondition

Using regex and $exists

$exists

exists

$regex

regex

Query on Embedded Documents

When the field holds an embedded document, a query can either specify an exact match on the embedded document or specify a match by individual fields in the embedded document using the dot notation.

db.users.find( { favorites: { artist: &amp;quot;Picasso&amp;quot;, food: &amp;quot;pizza&amp;quot; } } )
db.users.find( { &amp;quot;favorites.artist&amp;quot;: &amp;quot;Picasso&amp;quot; } )

Query on Arrays

When the field holds an array, you can query for an exact array match or for specific values in the array. If the array holds embedded documents, you can query for specific fields in the embedded documents using dot notation.

If you specify multiple conditions using the $elemMatch operator, the array must contain at least one element that satisfies all the conditions.

Chapter 1. About MongoDB

mongodb

1. Introduction

1.1 What is Mongo DB

Mongo DB is a document-based no SQL database, which stores data records as BSON documents. BSON is a binary representation of JSON documents.

{
  "_id" : ObjectId("579c7b2ce3faa846045fead1"),
  "headline" : "Apple Reported Second Quarter Revenue Today",
  "date" : "2016-7-30",
  "author" : {
      "name" : "Bob Walker",
      "title" : "Lead Business Editor"
  },
  "copy" : "Apple beat Wall St expections by reporting...",
  "tag" : ["APPL","Earnings","Cupertino"],
  "comments" : [
    {"name" : "Frank","comment" : "Greate Story"},
    {"name" : "Wendy","comment" : "When can I buy an Apple watch"}
  ]
}

1.2 JSON

Before we discuss the BSON documents, we need to know how many types of data type is supported by JSON document. So we can compare features of JSON and BSON. According to the information from http://www.json.org, the JSON document only supports:

  • object: wrapped by “{}”
  • array: wrapped by “[]”
  • string
  • number
  • boolean
  • null

1.3 BSON

WHY does Mongo DB store the BSON documents? According to the BSON Specificationthe BSON basic data types is including:

  • byte
  • int32
  • int64
  • double
{
  "_id" : ObjectId("579c7b2ce3faa846045fead1"),
  "headline" : "Apple Reported Second Quarter Revenue Today",
  "date" : ISODate("2016-7-30"),
  "view" : 1132,
  "author" : {
      "name" : "Bob Walker",
      "title" : "Lead Business Editor"
  },
  "copy" : "Apple beat Wall St expections by reporting...",
  "tag" : ["APPL","Earnings","Cupertino"],
  "comments" : [
    {"name" : "Frank","comment" : "Greate Story"},
    {"name" : "Wendy","comment" : "When can I buy an Apple watch"}
  ]
}

1.4 Mongo Shell

1.  using the mongo command to launch the Mongo Shell in the command prompt

>mongo

Ensure that the MongoDB is running before attemping to start the mongo shell

mongod –dbpath “c:\mongodb\data\db”

2. To display the database that you are using:

>db

To list the available databases, use the helper show dbs.

3. The CRUD option in the shell

  • db.collection.find()
  • db.collection.update()
  • db.collection.insert()
  • db.collection.remove()

The Mongo DB supports complex CRUD functions, and we are going to discuss them in details.

1.5 MongoDB is Schemaless

Let’s take  a look at the example of the users’ collection in the database:

schemaless

This feature is entirely different from the relational database. We can see that two of these documents own different structure.

Entity Validation in Entity Framework

Why do we need to validate entity? Because we cannot trust the input from the User Interface. Before we save changes (Create / Update data) in the database, the first and the most important thing is check the validation of data that is posted from the client side. Once the validation is failed, the program should response to client side accordingly.

Four levels of EF’s Data Validation

There are four methods can be applied to check the validation of input data.

The four EF data validations are:

  • Data Annotations and Fluent API, e.g. [MaxLength(150)] to check the maximum length of a string. Or modelBuilder.Entity<Blog>().Property(p => p.BloggerName).HasMaxLength(10); 
  • IValidatableObject. This is a method where to can code your own checks.
  • ValidateEntity. A DbContext method that allows access to the database while checking.
  • DbContext.GetValidationErrors Explicitly triggering validation

Data Annotation & Fluent API

One of the most significant function of Data Annotation and Fluent API is configuring the entity classes. The Code First uses the annotation from the System.ComponentModel.DataAnnotations assembly. These features have be discussed in the “Entity Framework: Convention“. If you are interested in these, please check it out. Another feature of the Data Annotation is data validation for the client side and server side. We could enable the Client Validation in web.config file.

<appSettings>
  <add key="ClientValidationEnabled"value="false"/> 
  ... 
</appSettings>

Let’s take a look the difference between Data Annotation and Fluent API
Data Annotation:

[Required, Column(TypeName = "decimal"),MaxLength(50)]
public int Discount { get; set; } 

Fluent API:

modelBuilder.Entity<Product>().Property(p => p.Discount)
  .IsRequired()
  .HasMaxLength(50)
  .HasColumnType("decimal")
  .HasPrecision(5,4);

The HasPrecision is unavailable for Data Annotation.
Validation errors thrown based on the Fluent API configurations will not automatically reach the UI, but we can capture it in code and then respond to it accordingly. We will discuss how to catch and response the Errors in ValidateEntity parts.

 

IValidatableObject

IValidatableObject is an interface that lives in System.ComponentModel.DataAnnotations. Once we inherit this interface, you can add a validate method for server-side validation in our Entity Framework classes. This method will call during SaveChanges or we can call ourselves any time we want to validate the classes. The advantage is that it allows more complex tests to be written than can be achieved the data annotations.

For example: comparing two fields

public class Blog : IValidatableObject
   {
       public int Id { get; set; }
       [Required]
       public string Title { get; set; }
       public string BloggerName { get; set; }
       public DateTime DateCreated { get; set; }
       public virtual ICollection<Post> Posts { get; set; }

       public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
           if (Title != BloggerName) yield break;
            yield return new ValidationResult ("Blog Title cannot match Blogger Name", new[] { "Title", "BloggerName" });
       }
}

Unlike the validation provided by the Fluent API, this validation result will be recognized by the View and the exception handler. Because both property names have been set in the ValidationResult, the MVC HtmlHelpers display the error message for both of those properties.

DbContext.ValidateEntity

ValidateEntity is more powerful and complex than previous validation procedures. In the DbContext, we can override the ValidateEntity method and add our own tests. The powerful thing about ValidateEntity is that we can access the current DbContext, which means we can look at the database when doing validation.

public class MyDbContext : DbContext
    {
        public MyDbContext() : base("name=MyDatabase")
        {
        }
       public DbSet<Post> Posts { get; set; }
       public DbSet<Blog> Blogs { get; set; }
       public DbSet<Comment> Comments { get; set; }

       protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
        {
            var result = new DbEntityValidationResult(entityEntry, new List<DbValidationError>());
           if (entityEntry.Entity is Post && entityEntry.State == EntityState.Added)
           {
                var post = entityEntry.Entity as Post;

               //check for uniqueness of post title 
                if (Posts.Count(p => p.Title == post.Title) > 0)
                {
                    result.ValidationErrors.Add(new DbValidationError("Title", "Post title must be unique."));
                }
            }
            return result.ValidationErrors.Count > 0 ? result : base.ValidateEntity(entityEntry, items);
        }
    }

DbContext.GetValidationErrors

DbContext.GetValidationErrors will trigger all of the validations, those defined by annotations or the Fluent API, the validation created in IValidatableObject (e.g., Blog.Validate), and the validations performed in the DbContext.ValidateEntity method.
The following code will call GetValidationErrors on the current instance of a DbContext. ValidationErrors are grouped by entity type into DbValidationRestuls. The code iterates first through the DbValidationResults returned by the method and then through each ValidationError inside.

try
{
   ...
}
catch(DbEntityValidationException dbEx)
{
  foreach (var validationResults in db.GetValidationErrors()) 
  {
    foreach (var error in validationResults.ValidationErrors) 
    { 
       Debug.WriteLine( "Entity Property: {0}, Error {1}",
                              error.PropertyName,
                              error.ErrorMessage); 
    }
  }
}

Reference:

Entity Framework Validation: https://msdn.microsoft.com/en-us/data/gg193959.aspx

Catch Bad Data in Entity Framework: https://www.simple-talk.com/dotnet/.net-framework/catching-bad-data-in-entity-framework/

Programming Entity Framework: DbContext by Julia Lerman and Rowan Miller