DPS907 notes – week 7 – Oct 19 and Oct 29

Introduction to security topics for your web services.


Agenda for the Friday class

Here is the agenda for the Friday class:

  • Review and transition your web app security knowledge
  • Inspecting and interacting with a security-aware web service
  • Reintroduction to claims, and custom claims


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.

Read them now, before continuing.

Welcome back.


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, from 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.


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 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 (the web server program).

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 week 4 class notes.

Notice tasks numbered 8 and 9:

  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

Important: You cannot send application/json data to that authentication endpoint.

You must send application/x-www-form-urlencoded data.


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 you have)

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


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…

Alternatively, you can send JSON.

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

Note: Please use dev as the user name for the account that you – the software developer – will use to test features of the app with a high level of privilege.

In the past, you may have been advised or tempted to use “admin”. However, the word “admin” is more applicable to the “IT administration” role. As a result, “dev” and “admin” are really two different roles, with often-different security profiles.


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…

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...)",
  ".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.



( end of Friday content; Monday content is next )

Please note that study week is between our Friday and Monday classes. 
The content below will be highlighted on Monday, October 29. 



Agenda for the Monday class

Here’s the agenda for the Monday class:

  • Claims, a re-introduction
  • Custom claims
  • Work on the assignment


A re-introduction to claims

It is likely that you worked with claims in your ASP.NET MVC web apps programming course. Your professor recommends that you review the content from the February 22 notes, specifically, these sections:

  • “Problem, and solution”, and
  • “Introduction to claims”

Read them now, before continuing.

Welcome back.


So, a claim is defined as follows:

A claim is a a statement that one subject makes about itself or another subject.

Therefore, a statement is descriptive information about a subject.

A subject is a participant in the lifetime of an application. A subject could be a human user, or a corporate body, or a programmable object (e.g. a security provider).


Claims management and issuance, in a web service project

In the web apps course, you learned that claims are managed and issued by an identity authority (which is the ASP.NET Identity system in our app).

Then, a claim can be used by an application for any of these reasons:

  1. To provide descriptive information (e.g. full name)
  2. To control access to a resource
  3. To control the permission to perform tasks or activities
  4. etc.

For our web services, claims are packaged in an access token, after a user successfully authenticates. Therefore, the result of a successful authentication is an access token, that (among other data) includes claims.


Creating claims, and custom claims

In the web app course’s SecurityClaimsIntro code example, you learned how to work with some of the standard (predefined, “well known”) claim types.

In the RegisterViewModel – which describes the package of data in a “register new user account” request – had these additional claim-related properties added:

  • GivenName – for the standard “…givenname” claim type
  • Surname – for the standard “…surname” claim type
  • Role – for the standard “…role” claim type

You also saw how the Register() POST-handling method in the AccountController was changed, so that these new claims could be configured for the new user account.

Finally, you saw how to use the [Authorize] attribute to control access to methods in the HomeController. (Study the use of the attribute on the controller declaration, and on each method declaration.)

In summary, the process to handle the standard claim types is well understood, and you have had enough practice with that.

How are custom claim types handled?

The same way:

  1. Modify the view/resource model, so that it includes properties for the custom claim types
  2. Modify the account-creation code (in the controller), so that it processes and configures the new claims
  3. In a controller or manager, test for the presence of the custom claim, when necessary


A new filter for authorizing custom claims

The Web API framework does not include an [Authorize] filter for custom claims. However, we can easily create one. Your professor has written a class that you can use (yes, you have permission) to authorize custom claims.

Get the CustomAuthorizeAttribute.cs source code file from this week’s GitHub repository folder. Save it in your Controllers folder, and edit its namespace to match the name of whatever project it’s part of.

Then, use it as follows. For example, assume that you’re looking for an “eye colour” claim type, with the value “blue”. In a controller, maybe before a method signature, add the new [AuthorizeClaim] attribute:

[AuthorizeClaim(ClaimType = "EyeColour", ClaimValue = "Blue")]
public IHttpActionResult Get()
  // etc.


Handling AND and OR conditions when using [Authorize] or [AuthorizeClaim] attributes

Yes, you can handle AND and OR conditions. How?


AND condition:
A method will run if it has a list of Authorize attributes that are ALL true:

// If ALL listed conditions are true, then authorization will succeed
[Authorize(Roles = "Employee")]
[AuthorizeClaim(ClaimType = "EyeColour", ClaimValue = "Blue")]
public IHttpActionResult Get()
  // etc.


OR condition:
A method will run if its Authorize attribute has several values, as a comma-separated string, of which ANY are true:

// If ANY value is true, then authorization will succeed
[Authorize(Roles = "Student, Mentor")]
public IHttpActionResult Get()
  // etc.


Work on the assignment

Work on the next assignment.
























































%d bloggers like this: