Secure ASP.NET WebAPI 2 using ASP.NET Identity membership DB with OAuth 2

Code Download.

What we will use:
  • OAuth 2.0 middleware
  • ASP.NET WebAPI 2.2
  • ASP.NET Identity 2.1 membership
  • Authentication Project Template: Individual Account
  • SPA using knockoutjs (optional)

OAuth 2.0 terminology:

  • Resource: Some piece of data that can be protected. e.g. Controller/Controller’s Action method.
  • Resource server: The server that hosts the resource.
  • Resource owner: The entity that can grant permission to access a resource. Typically the user.
  • Access token: A token that grants access to a resource.
  • Bearer token: A special type of access token which a client doesn’t need a cryptographic key to use it. For that reason, it should only be used over a HTTPS, and with short expiration time.
  • Authorization server: A server that gives out Bearer/Access tokens.
  • Client: The app that wants access to the resource. e.g. a web browser, native app.
  • OAuth 2.0 Access Token Retrieval – Grant types:
  • Authorization Code Grant
  • Implicit Grant
  • Resource Owner Password Credentials Grant – we will be using this!
  • Client Credentials Grant
  • JWT Tokens

note: A Resource server and Authorization server can be part of the same ASP.NET application.

Using Resource Owner Password Credentials Grant:

image

Architecture

image

Let’s get the Bearer/Access token from Authorization Server

Setup:

In StartupAuth.cs,

PublicClientId = “self”;
OAuthOptions = new OAuthAuthorizationServerOptions
{
    TokenEndpointPath = new PathString(“/Token”),
    Provider = new ApplicationOAuthProvider(PublicClientId),
    AuthorizeEndpointPath = new PathString(“/api/Account/ExternalLogin”),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
    // Note: Remove the following line before you deploy to production:
    AllowInsecureHttp = true
};

// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);

The TokenEndpointPath property is the URL path to the authorization server endpoint. That’s the URL that app uses to get the bearer tokens. e.g. “/Token”

The Provider property specifies ApplicationOAuthProvider which provide access to the ASP.NET Identity membership database via the UserManager

Flow:

image

  1. To get an access token, the app sends a request to ~/Token.
  2. The OAuth middleware calls GrantResourceOwnerCredentials on the ApplicationOAuthProvider (which implements OAuthAuthorizationServerProvider).
  3. The provider calls the ApplicationUserManager which derives from ASP.NET Identity’s UserManager to validate the credentials with the ASP.NET Identity membership db and create a claims identity.
  4. If that succeeds, the provider creates an authentication ticket, which is used to generate the Bearer token.

Sample Request/Response

Javascript

var loginData = {
    grant_type: ‘password’,
    username: self.loginEmail(),
    password: self.loginPassword()
};

$.ajax({
    type: ‘POST’,
    url: ‘/Token’,
    data: loginData
}).done(function (data) {
    self.user(data.userName);
    // Cache the access token in session storage.
    sessionStorage.setItem(tokenKey, data.access_token);
}).fail(showError);

Notice that we store the token in session storage, to use later when sending requests to the API. Unlike some forms of authentication (such as cookie-based authentication), the browser will not automatically include the access token in subsequent requests. The application must do so explicitly. That’s a good thing, because it limits CSRF vulnerabilities
HTTP Request

POST https://localhost:44305/Token HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer:
https://localhost:44305/
Content-Length: 68

grant_type=password&username=alice%40example.com&password=Password1!

HTTP Response

HTTP/1.1 200 OK
Content-Length: 669
Content-Type: application/json;charset=UTF-8
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 01:22:36 GMT

{
  access_token“:”imSXTs2OqSrGWzsFQhIXziFCO3rF…”,
  token_type“:”bearer”,
  “expires_in”:1209599,
  “userName”:”alice@example.com”,
  “.issued”:”Wed, 01 Oct 2014 01:22:33 GMT”,
  “.expires”:”Wed, 15 Oct 2014 01:22:33 GMT”
}

Log Out

Because the browser does not cache the credentials or the access token, logging out is simply a matter of “forgetting” the token, by removing it from session storage:

self.logout = function () {
    sessionStorage.removeItem(tokenKey);
}

Let’s get the protected Resource from WebAPI Resource Server

Setup:

In the WebApiConfig.cs Register method, the following code sets up Bearer Token authentication for the Web API pipeline:

config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

The SuppressDefaultHostAuthentication method tells Web API to ignore any authentication(e.g. MVC cookies authentication) that happens before the request reaches the Web API pipeline, either by IIS or by OWIN middleware. That way, we can restrict Web API to authenticate ONLY using bearer tokens.

The HostAuthenticationFilter class enables authentication using bearer tokens.

Flow:

image

  1. The HostAuthenticationFilter calls the OAuth middleware to validate the token.
  2. The middleware converts the token into a claims identity.
  3. At this point, the request is authenticated but not authorized.
  4. The AuthorizationFilter [Authorize] examines the claims identity.
  5. The controller returns the protected resource. Otherwise, the client receives a 401 (Unauthorized) error.
Sample Request/Response
Javascript

// If we already have a bearer token, set the Authorization header.
var token = sessionStorage.getItem(tokenKey);
var headers = {};
if (token) {
    headers.Authorization = ‘Bearer ‘ + token;
}

$.ajax({
    type: ‘GET’,
    url: ‘api/values/1′,
   
headers: headers
}).done(function (data) {
    self.result(data);
}).fail(showError);

HTTP Request

GET https://localhost:44305/api/values/1 HTTP/1.1
Host: localhost:44305
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0
Accept: */*
Authorization: Bearer imSXTs2OqSrGWzsFQhIXziFCO3rF…
X-Requested-With: XMLHttpRequest

HTTP Response
A failed one when Bearer token is missing or incorrect:

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
WWW-Authenticate: Bearer
Date: Tue, 30 Sep 2014 21:54:43 GMT
Content-Length: 61

{“Message”:”Authorization has been denied for this request.”}

A success one:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Wed, 01 Oct 2014 01:41:29 GMT
Content-Length: 45

“Hello from Action Method, alice@example.com.”

Reference: http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api

Azure WebJobs Walkthrough with Visual Studio

image

  1. Create an ASP.NET WebApp
  2. At project node, Add “New Azure WebJob Project”
  3. Choose project type: Continuous/OnDemand/Schedule
    1. Continuous:
      1. A JobHost.RunAndBlock(); in void Main().
      2. A method for [QueueTrigger/BlobTrigger(queuename)] to dequeue message from queue
    2. On Demand/Schedule:
      1. A JobHost.Call(methodname, value) in void Main().
      2. A method for [Queue/Blog(queuename)] to enqueue  message to the queue
  4. Publish WebApp and/or WebJob projects to Azure. And you will find the WebJob deployed under the WebApp App_Data folder
  5. Configuration: Add Azure Storage Connection String to Live Azure Web Site.
    1. Go to Server Explorer –> Storage to get Storage Connection String
      • image
      • image
    2. Go to  Websites –> Settings, create 2 entries AzureWebJobsStorage & AzureWebJobsDashboard. And select Custom from the Database Type column.
      • image
  6. Debug Contiuous WebJob: In Server Explorer, goto your WebJob and make sure it is started.
    1. Attach Debugger. Set your breakpoints.
      1. image
    2. View static Logs.
  7. Run OnDemand WebJob to send message to the queue which will in turn trigger any breakpoints in the continuous WebJob.
    1. image

Ref:

https://github.com/Azure/azure-webjobs-sdk-samples

http://blogs.msdn.com/b/webdev/archive/2014/11/12/new-developer-and-debugging-features-for-azure-webjobs-in-visual-studio.aspx

Manage Azure using Windows PowerShell with publishsettings file

 

Use the certificate method

The Azure module includes cmdlets that help you download and import the certificate.

  • The Get-AzurePublishSettingsFile cmdlet opens a web page on the Azure Management Portal, from which you can download the subscription information. The information is contained in a .publishsettings file.

  • The Import-AzurePublishSettingsFile imports the .publishsettings file for use by the module. This file includes a management certificate that has security credentials.

e.g.

Import-AzurePublishSettingsFile “c:\mydownloaded.publishsettings”

Get-AzureAccount

Get-AzureSubscription

Stop-AzureVM -ServiceName “myServiceName” -Name “myName” -StayProvisioned

Azure Active Directory for MVC & WebAPI

image

Azure Friday

Update:

Connect() – This video provides a quick overview of Azure Active Directory from a developer’s standpoint and gives a glimpse of the new identity features in Visual Studio 2015 that make it easy to secure applications with Azure AD.

Secure a MVC application using Azure Active Directory AD Authentication with Visual Studio 2015

Here is the instruction on using Visual Studio 2015 preview to add Azure Active Directory SSO to an existing MVC Application.

1. Create an Azure Active Directory

2. Add user(s) to directory

3. Right-click the project and click “Configure Azure AD Authentication”

image

4. Enter your Active Directory Domain Name e.g. yourid.onmicrosoft.com  This will integrate an Application to the Active Directory

image

5. Click the Application Link and click the Configure Tab and change the “Reply Url” to your webiste’s Url so Azure AD know where to send the SAML authentication tokens after successfully authenticated the Users.

e.g. https://mywebapp.azurewebsites.net/

6. optional update the [Authorize] attribute in the controllers

7. optional add the login/logout/username html to the view. e.g. add @Html.Partial(“_LoginPartial”) to _layout.cshtml

8. Finally publish the WebApp to Azure. Right click on project and click “Publish…”

Katana–OWIN implementation from Microsoft

Katana Architecture

The Katana component architecture divides an application into four logical layers, as depicted below: host, server, middleware, and application. The component architecture is factored in such a way that implementations of these layers can be easily substituted, in many cases, without requiring recompilation of the application.

image

An example of components from different layers
  • Host: IIS/ASP.NET, OwinHost.exe, Self-Host/Custom-Host(e.g. Windows Service)
  • Server: SystemWeb(ASP.NET pipeline), HttpListener (OwinHost/Self-Host/Custom-Host)
  • Middleware: Web API, SignalR, Nancy
  • Application: Your Application.

http://www.asp.net/aspnet/overview/owin-and-katana

Documentation: http://katanaproject.codeplex.com/documentation

 

owin

Azure Scheduler–run jobs on simple or complex recurring schedules

image

Scheduler

Run your jobs on simple or complex recurring schedules
  • Call services inside or outside of Azure
  • Run jobs on any schedule—now, later, or recurring
  • Use Azure Storage queues for long-running or offline jobs
  • Management REST API

Get Started using Scheduler MSDN

Videos: