DPS907 notes – Tue Oct 18

Introduction to security topics for your web services.

 

Test today

The weekly test will be done at the beginning of the class timeslot at 11:40am.

 

Code examples

The GitHub code example repository for this week, has assets that support this topic.

 

Before continuing, review your security knowledge

This task is very important.

Before continuing, please read the web apps notes page that introduces security topics, and study its related code examples while using Visual Studio.

It will probably take you an hour or two to get through that content.

Do it now.

Before continuing.

 

Security topics for ASP.NET Web API, introduction

In an ASP.NET Web API web service, we use the same security infrastructure – ASP.NET Identity – as we did for ASP.NET MVC web apps, although there are a few notable differences.

As a refresher, ASP.NET Identity is a system that handles three tasks:

  1. Identity management (e.g. user accounts)
  2. Authentication
  3. Authorization

 

Identity management uses the same storage system, ApplicationDbContext, and so on. However, a web service project that has been configured with security does not include the web app pages (for a browser) to handle user account creation or maintenance (e.g. password change). Instead, those are handled by web service endpoints.

To learn about authentication and authorization tasks in a web service, the following introduction was taken from a Microsoft post. It was edited to remove the parts that are not relevant to us. From Authentication and Authorization in ASP.NET Web API, by Mike Wasson, Microsoft:

You’ve created a web API, but now you want to control access to it.

  • Authentication is knowing the identity of the user. For example, Alice logs in with her username and password, and the server uses the password to authenticate Alice.
  • Authorization is deciding whether a user is allowed to perform an action. For example, Alice has permission to get a resource but not create a resource.

[Here is] …a general overview of authentication and authorization in ASP.NET Web API.

Authentication

Web API assumes that authentication happens in the host. … You can configure your project to use any of the authentication modules built in to [the standard Microsoft web server] IIS or [in] ASP.NET…

When the host authenticates the user, it creates a principal, which is an IPrincipal object that represents the security context under which code is running. The host attaches the principal to the current [request] thread… The principal contains an associated Identity object that contains information about the user.

If the user is authenticated, the Identity.IsAuthenticated property returns true. For anonymous requests, IsAuthenticated returns false.

Authorization

Authorization happens later in the pipeline, closer to the controller. That lets you make more granular choices when you grant access to resources.

  • Authorization filters run before the controller action. If the request is not authorized, the filter returns an error response, and the action is not invoked.
  • Within a controller action, you can get the current principal from the ApiController.User property. For example, you might filter a list of resources based on the user name, returning only those resources that belong to that user.

Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action.

You can apply the filter globally, at the controller level, or at the level of inidivual actions.

(Read the article’s section titled “Using the [Authorize] Attribute” for more information.)

 

What does all this mean?

“Authentication happens in the host”:

In our apps, the host is an OWIN server, which is a service layer between our app and IIS.

OWIN is a specification for communication between an app and a server.

Its goal is to decouple the app from the server. This would enable us, for example to use a different server, if we wanted to, for some reason.

There are two new commands – the first two – in the Register() method (in the WebApiConfig class, which is in the WebApiConfig.cs source code file in the App_Start folder), configure the app to use the OWIN server as host.

“The host attaches the principal to the current [request] thread”:

A successful authentication causes OWIN to create a ClaimsPrincipal object. It is attached to the current request thread. From that point on, it’s available for inspection.

“Authorization happens later in the pipeline, closer to the controller”:

The [Authorize] attribute appears just before controller declarations and action methods.

The code behind the [Authorize] attribute inspects the security principal to make a continue/fail decision.

 

Request-processing pipeline in a secure scenario

The following shows how an incoming request is handled, in sequence, in a secure scenario. Open the “HTTP Message Lifecycle” poster that was first introduced in the September 27 class notes.

  1. IIS receives the request, identifies it as request for an ASP.NET app, and passes it to…
  2. The ASP.NET runtime, which determines that the app as been configured to use OWIN
  3. OWIN, acting as the app’s host/server, begins handling the request
  4. An HTTP Request object is created (seen as an HttpRequestMessage object in the ASP.NET runtime)
  5. The route (request URI) is inspected, if OK, continue…
  6. The controller is determined, and initialized/instantiated
  7. The controller action (method) is determined
  8. Authentication happens (using a OWIN module/component)
  9. Authorization happens for the selected controller action (if it fails, HTTP 401 or 403)
  10. Model binding happens, which extracts data from the HTTPRequestMessage
  11. The controller action is invoked/executed

(Then, the response is prepared, and returned to the user/requestor.)

 

Visual Studio standard project template for a security-aware web service

As you would expect, Visual Studio has a standard project template for a security-aware web service.

Start Visual Studio. Create a new project; in the “New Project” dialog, choose “ASP.NET Web Application”, name it “SecurityTest“, and click OK.

On the “Select a template” dialog, make sure that “Web API” is selected. It will add folders and core references for both MVC and Web API. On the right, make sure that “Authentication” is set to “Individual User Accounts”, and click OK.

The resulting project will be security-aware. At this point in time, it does NOT have any user accounts defined. However, its Values controller is protected by an [Authorize] attribute.

This is a good starting point for the rest of our discussion. Before continuing, use the package manage console to “update-package”, so that you have up-to-date components. Then, build/compile, and load the project in a browser so that you know that it works.

 

Transition your knowledge of web apps security
to the web services context

As a user of the web, you have experience with many different web apps that have security components.

As a web programmer, you have some experience with some security-related coding tasks. In BTI320 / INT322, you designed and created a credential store, to hold usernames and passwords. In addition, you coded a login form, and the credential validation process. An access control list based scheme was used to protect resources. Simple, but not real-world.

In BTI420 / INT422, you used the ASP.NET Identity components to do most of the work described above. The Authorize attribute was used on controllers and methods, and you learned that the security infrastructure took care of controlling access to resources.

 

But in general, how does security work in a web app?

The most common scheme in web apps – and used by ASP.NET Identity – is that the authentication (credential validation) process creates an HTTP cookie. The cookie holds information about the authenticated user, but does not include sensitive or secret data. After a successful authentication, the server delivers the cookie with the response, and the browser saves the cookie in its cookie store.

How do you know this? Login to a security-aware ASP.NET MVC web app. Then, use the browser’s developer tool or inspector to examine the cookies collection for that web app/site. You will see a cookie named “.AspNet.ApplicationCookie“. The browser will include the cookie with every subsequent request to that web app/site.

 

How does security work for a web service?

Well, a user does not use a browser to interact with the web service. Therefore, we cannot use an HTTP cookie.

Instead, an access token is used.

Instead of using an HTML Form for login, a user/requestor could send a specially-formatted “authenticate” request to a specific resource in the web service that handles authentication. The authentication (credential validation) process creates an access token. Like a cookie, an access token holds information about the authenticated user, but does not include sensitive or secret data. The token is delivered as the response, to the user/requestor. The user/requestor must then take some action to save the token.

On subsequent requests to the web service, the user/requestor must send the token in an Authorization header. The ASP.NET Identity components implement the OAuth2 authorization framework, so the format of the header is:

Authorization: Bearer _VL-_nDUmUydRHeeRV9LNzuN3ZGrg0Ty1V_0Jt4gWBw4... (etc.)

 

Hands-on inspection of a web service project’s
security components

In this section, you will learn about a web service project’s security components, by inspecting the “SecurityTest” project that you created above.

Also, download and open the ProjectWithSecurity code example. It has been marked up with “Attention” task list tokens, so be sure to open/display the Visual Studio Task List too.

Now you can compare the two, just to satisfy yourself that the code example project is the same as your SecurityTest project.

 

Loading (starting) the app and its security components

When the app loads for the first time, the ASP.NET runtime looks for OWIN components in the web app.

In the root of the project, there is a Startup.cs source code file, and a Startup class inside (that has a split implementation; the other part is in App_Start/Startup.Auth.cs).

Running the Configure() method causes the security components to load:

  • Identity storage (in the database)
  • Identity management component (including password rules etc.)
  • Cookie handling (for browser clients)
  • Access token handling (OAuth2, for web service clients)

 

Identity storage (in the database)

Notice that the project includes an IdentityModels.cs source code file. It includes an ApplicationUser class, and a data context class, ApplicationDbContext.

When the database is accessed for the first time, the security components cause the security-related database tables to be created.

 

Identity management (user account create, change)

The Account controller has actions that enable a user to register for a new account, and other tasks.

Study the Register method.

Next, study the account binding models, for objects sent to the account controller as parameter arguments/values.

Finally, study the account view models, for objects returned by account controller actions.

 

The OWIN authentication component

The ApplicationOAuthProvider class (in the Providers folder) performs authentication-related tasks.

The app’s “token endpoint” – at URI http://host.example.com/token – is mapped (by default) to the GrantResourceOwnerCredentials() method.

When sending a POST request to that endpoint, the requestor must use this content type:

Content-Type: application/x-www-form-urlencoded

Three data items must be sent in the request’s entity body:

  1. grant_type=password
  2. username= (whatever user name you have)
  3. password= (whatever password…)

The data items must be formatted to match the content type, for example:

grant_type=password&username=user1@example.com&password=Password123!

More info about interacting with the web service is presented next.

 

Interacting with a security-aware web service

Use Fiddler to interact with a security-aware web service.

Load and run the ProjectWithSecurity code example.

Open and view the EntityBodyData.txt source code file, which has example data that you can use.

 

Create a new user account

Create a new request:

  • POST
  • URI is /api/account/register
  • Content type is application/x-www-form-urlencoded
  • The entity body data is in this format…
    Email=admin@example.com&Password=Password123!&ConfirmPassword=Password123!

Alternatively, you can send JSON.

If successful, it will respond with HTTP 200 and an empty entity body.

 

Authenticate (login) – which means “request an access token”

Create a new request:

  • POST
  • URI is /token
  • Content type is application/x-www-form-urlencoded
  • The entity body data is in this format…
    grant_type=password&username=student8@example.com&password=Password123!

If successful, it will respond with HTTP 200 and an entity body that has the access token and other data. It will look something like this:

{
  "access_token":"Ll49GG3k1bKjl0R-K2NHOFh(...very long string was truncated...)",
  "token_type":"bearer",
  "expires_in":1209599,
  "userName":"student8@example.com",
  ".issued":"Fri, 14 Oct 2016 17:57:30 GMT",
  ".expires":"Fri, 28 Oct 2016 17:57:30 GMT"
}

 

Using the access token in future requests

Right now, if you simply request the content of the values controller (i.e. GET /api/values), it will respond with HTTP 401. Why? Look at the controller. It has the [Authorize] attribute.

How do you include authorization information in your request?

By adding a properly-formatted request header. Here’s how:

  1. Create an “Authorization” request header
  2. Its value will be the word “Bearer”…
  3. …a space, and…
  4. …the VALUE of the access token

For example:

Authorization: Bearer Ll49GG3k1bKjl0R-K2NHOFh16s5LblQbC...(etc., a long string)

 

What’s inside the access token?

In the ProjectWithSecurity, there’s a controller that will decode/decrypt the access token, and show you the contents.

Send a GET request – with authorization – to /api/authinfo.

 

Accessing info about the authenticated user/requestor at runtime

Most students will recall this topic from their ASP.NET web apps course.

After a successful authentication, the authentication process (on the server) will create a data package and return it in the response. The data package includes information about the authenticated user, but it does not include sensitive or secret data. It definitely includes the user name, and the user’s claims.

If the authentication was initiated by using a browser and a web app, the data package that’s returned is an HTTP cookie.

Alternatively, if the authentication was initiated by using an HTTP client (e.g. Fiddler), the data package that’s returned is an access token.

On subsequent requests, the data package – cookie or token – is sent with the request. In a web app, the browser handles this task automatically. When you are using Fiddler (or programming an HTTP client on, for example, an iPhone app), you must do this task.

When a web service receives a request with a token, the security infrastructure validates the token. If valid, it creates an IPrincipal object, and attaches it to the request. That way, information about the authenticated user is available to your code, as the request makes its way through the request-processing pipeline.

In your code, how do you get access to the authenticated user information? The User property.

In a controller, it’s simply the top-level User property. Also, if you want to determine whether a request is authenticated, the Request.IsAuthenticated property will tell you.

In a manager module, it’s the HttpContext.Current.User property. Also, if you want to determine whether a request is authenticated, the HttpContext.Current.Request.IsAuthenticated property will tell you.

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

%d bloggers like this: