DPS907 notes – Tue Nov 28

Work with user accounts and claims.

 

Today, Thursday, and next week

This week – today and Thursday – we will learn more about working with user accounts and claims in a web service. As a preview, we will alternate, mix, and iterate our coverage of these two topics, simply because we need to know something about one before working with the other.

The next assignment will be released later this week, likely. It will be due about two weeks from now, on December 11 (instead of being due next Monday).

Next week, as a preview, we plan to separate two tasks – identity management and authentication – out into a dedicated “security provider” app. Then, we can create lightweight and nimble apps that are security-aware, but much simpler in their design and implementation.

 

Theme for today, and code examples

After learning more about secured web services, we can cover some topics that build a stronger foundation, user account initialization and management, and claims management. We’ll need some knowledge and skills there before moving on to next week’s topics.

Code examples for today include:

ManageClaims – learn about a design for structured or guided claims management

ManageUserAccounts – learn how a “user accounts manager” can manage user accounts

 

How a security-aware app loads (starts up)

At this point in time, you are probably somewhat aware about how a security-aware app loads (or starts up). We may cover this in more detail next week, but here (below) is the simplified sequence of steps that happen when an app loads into server memory:

  1. In the HttpApplication subclass, the Application_Start() method runs
  2. (for Web API project…) In the WebApiConfig class, the Register() method runs
  3. In the Startup class, the Configuration method runs, which calls the ConfigureAuth() method
  4. The user account database is initialized, as are the user manager and sign in manager components

Why is this information useful now?

So that we can initialize a new app with one or more user accounts, in code. That’s the goal.

 

Initialize a new app with user accounts

The security-aware project templates, for web app and web service projects, are configured to enable user account creation, out of the box, with no code changes. It just works, successfully. However, the result is unsatisfactory, because you have to really know what you’re doing, it does take some effort, and the resulting user account(s) do not have the configuration settings (e.g. claims) that are typically needed in a new app.

So, it would be nice to programmatically create new and fully-configured user accounts, when the app loads for the first time. Here’s how we will do that task.

First, recall (from above) the sequence of steps that happen when an app loads into server memory. We will plan to do our user account creation task at the end of that sequence. More about that soon.

Next, let’s create a static class that can check whether any users have been defined already. If no user accounts are found, then it will create the first user. We’ll make that user an administrative/manager-type user, specifically a user account manager. (That role may indeed be different from other system-admin-related roles.)

In the Models folder, create a new class named IdentityInitialize. Make it a static class. Add one static method, LoadUserAccounts. (We may add other methods in the future.)

Here’s some sample code. As its comment states, change any of the data below to better match your app’s needs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
// added...
using Microsoft.AspNet.Identity.EntityFramework;
using System.Security.Claims;
using System.Threading.Tasks;

namespace SecMVC2.Models
{
  public static class IdentityInitialize
  {
    // Load user accounts
    public static async void LoadUserAccounts()
    {
      // Get a reference to the objects we need
      var ds = new ApplicationDbContext();
      var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(ds));

      // Add the user(s) that the app needs when loaded for the first time
      // Change any of the data below to better match your app's needs
      if (userManager.Users.Count() == 0)
      {
        var uam = new ApplicationUser { UserName = "uam@example.com", Email = "uam@example.com" };
        var uamResult = await userManager.CreateAsync(uam, "Password123!");
        if (result.Succeeded)
        {
          // Add claims
          await userManager.AddClaimAsync(uam.Id, new Claim(ClaimTypes.Email, "uam@example.com"));
          await userManager.AddClaimAsync(uam.Id, new Claim(ClaimTypes.Role, "UserAccountManager"));
          await userManager.AddClaimAsync(uam.Id, new Claim(ClaimTypes.GivenName, "User Account"));
          await userManager.AddClaimAsync(uam.Id, new Claim(ClaimTypes.Surname, "Manager"));
        }
      // Can add more users here
      // For example, "dev"
      }
    }
  }
}

 

Notice what we just did: We created a new user, with some very specific claims. We are saying that the app will have a role claim, UserAccountManager, which denotes a special role or status.

Now, open and edit the ConfigureAuth method in the startup class (in the App_Start\Startup.Auth.cs source code file).

Call the method that you wrote above, after the user and sign in managers have been initialized. For example:

public void ConfigureAuth(IAppBuilder app)
{
  // Configure the db context, user manager and signin manager to use a single instance per request
  app.CreatePerOwinContext(ApplicationDbContext.Create);
  app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
  // You will see the following in an app that has UI for login
  app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

  // Initialize user accounts for the app
  IdentityInitialize.LoadUserAccounts();

  // etc. (other code continues below)

 

Introduction to this week’s work with claims

Today and this week, we will break new ground in our course work. It’s based on the claims topic that was introduced last week and in Assignment 6: We need to design a way that we can work with and manage custom claims.

First, let’s re-visit claims, specifically the standard and well-known claims. Yes, there are claims for names and identifiers. And, we have role claims, which were created to help transition knowledge from the past.

Here’s a few recommendations for designing and managing role claims:

Attempt to limit the number of roles that are created in an app. There should be a fairly small number. Over time, the number of roles should not grow too much or too frequently.

A role should be used to broadly describe a fairly large number of users who share a access- or use-oriented goal in your app. For example, a public-facing app could have an Employee role, a Customer role, and an (office or workplace) Administrator role. Consider a role to be a coarse-grained way to design large or overview access or use categories.

Until further notice, do NOT use roles for any of the following purposes:

  • Fine-grained access control to a resource
  • Permission to perform an activity
  • Descriptive or personalization information

Instead, capture these purposes by using custom claims.

Is this a best practice?

No. This is guidance. We will experiment with this approach, and see what happens.

 

Custom claims design

It is reasonable to expect that the number of custom claims – their types and values – will be numerous in a busy app. As a result, we should attempt to introduce some structure and limits in our initial design. That way, we strike a balance between having a detailed roadmap to a destination, and having no idea where to go next.

So, let’s design an initial approach for our custom claims…

 

…for access control

In an app, we often want to control access to a resource. A high-level way is to use a role claim. However, we often need a finer-grained approach. For example, consider your role as a student here at Seneca.

If an app had resources that were intended to be accessed by School of ICT students, should we introduce a role? Probably not, for several reasons. First, we would then be tempted to create roles for each and every other School at the College, so there would be dozens. Next, it doesn’t add much to the overall conversation about “roles” and their membership.

Let’s take this example a step further: Assume that the same app had resources that were intended to be accessed only by those in the CPA and BSD academic programs. Another role? No. (The College has about 140+ academic programs. Way too many to be considered for roles.)

This scenario is ideal for using custom claims. The big initial question is “what claim types and values should we design? for this purpose?”

How about using a claim type of “OU”. We borrow this concept from directory services, and specifically an organizational unit, or OU. The concept of an OU is quite flexible, and can help solve problems from many different knowledge domains.

Looking again at the scenario above, we could create several OU values:

  • OU = FASET (Faculty of Applied Science and Engineering Technology)
  • OU = SICT (School of ICT – could be used for students, and for faculty)
  • OU = Faculty (faculty member, who would also have an “Employee” role claim)
  • OU = Advisor (for staff and faculty who do student advising in their job)
  • OU = CPA (those attached to the CPA academic program)
  • OU = Level1 (new students in level/semester 1)
  • etc.

 

…for permissions

In an app, we often want some activities to be done only by those with permission. Again, a high-level way is to use a role claim. However, a medium-sized app could have many resources with dozens of activities possible (familiar CRUD activities, as well as commands). Again, a poor match for roles.

This scenario is also ideal for using custom claims. What claim types and values should we design for this purpose?

In assignment 6, we suggested using “Task” as a claim type.

If we continue to use the College scenario/domain from above, we could create several “Task” values:

  • Task = TimetableView (for students, and academic advisors)
  • Task = PhotoEditor (can upload a photo for a user account)
  • Task = GradebookEdit (for faculty, when a course is running)
  • Task = GradebookView (for faculty, and for students in the course)
  • etc.

 

…for descriptions

Some apps need user account data that is not used for the access control and activity permission purposes discussed above. Maybe the data expresses a preference, maybe it’s descriptive, maybe it’s used for interaction personalization – the possibilities are many.

Again, this scenario is ideal for using custom claims. What claim types and values should we design for this purpose?

Well, we do not offer any prescriptive guidance here. However, in an app, as you gain experience, if you can blend your use of role and custom claims – including OU and Task – then the app’s reason-for-being will probably suggest some useful descriptive or personalization claim types.

 

In summary…

For access control, we suggest using a custom claim type name of “OU”.

For task/activity permission, we suggest using a custom claim type name of “Task”.

For descriptions, we do not have guidance about the name of the claim type. It really will depend upon the app and its problem domain.

 

Summary, and what’s next

Today, you learned a way to prepare or configure a new web service with pre-configured user accounts.

Then, we discussed the purpose and design of custom claims.

On Thursday, we’ll continue making progress, by designing, configuring, and implementing a way to manage user accounts, and manage custom claims.

Next week, as a preview, we plan to separate two tasks – identity management and authentication – out into a dedicated “security provider” app. Then, we can create lightweight and nimble apps that are security-aware, but much simpler in their design and implementation.

 

No new assignment will be released today

No new assignment will be released today, so nothing is due next week, on December 4.

Later this week, it is likely that the next assignment will be released, and it will have a due date of December 11.

 

 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

Advertisements
%d bloggers like this: