4

I am using ASP.NET Identity. It works well but I would like to add in a parent to the AspNetUsers table. In my case I would like to have each user belong to an organization. At this point I am just looking for some ideas to see if others have seen implementations that would allow this.

Has anyone seen any implementations that do this. I would like to get some tips on how I could implement this functionality.

Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427
  • Your question is not completely clear. What is "Parent to a table"? perhaps if you explain a bit more about your requirements, it'll be easier to answer. – trailmax Jul 10 '15 at 11:27
  • The idea you are talking about sounds close to Active Directory implementations. Here we can provide Role based authorization to a particular Web application. User need to part of that group to access that application. – Atanu Roy Jul 24 '15 at 06:03
  • BTW, what do you mean by 'belong to organisation' ? Is this any logical partition that we generally have in Identity and access management portals. – Atanu Roy Jul 24 '15 at 06:07
  • to have better control, you should use your own implementation, [see how easy is to do it on my answer](http://stackoverflow.com/questions/5701673/custom-membershipprovider-in-net-4-0/5702000#5702000). – balexandre Jul 24 '15 at 06:36
  • @balexandre your answer talks about MembrshipProvider. The question is about Asp.Net Identity and these are not the same: MembershipProvider is getting replaced by Identity and they are not backwards compatible. – trailmax Jul 24 '15 at 15:57

1 Answers1

3

I'm presuming you are using default EF implementation of Identity storage.

Identity is very flexible and can be bent into many shapes to suit your needs.

If you are looking for a simple parent-child relationship, where every user would have a parent record (such as Company), one of the ways to implement that is to add company reference to user class:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.AspNet.Identity.EntityFramework;


public class ApplicationUser : IdentityUser
{
    public ApplicationUser()
    {
    }

    [ForeignKey("CompanyId")]
    public Company Company { get; set; }
    public int CompanyId { get; set; }
}


public class Company
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CompanyId { get; set; }
    public String Name { get; set; }

    public virtual ICollection<ApplicationUser> Users { get; set; }
}

This will put a foreign key on users to companies. But from here next course of action depends on what is required in your application. I would imagine that you'll have some sort of restriction for users depending on what company they belong to. For quick company retrieval you can store CompanyId in a claim when logging in the user.
Default implementation of ApplicationUser has GenerateUserIdentityAsync method. You can modify this as following:

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        identity.AddClaim(new Claim("CompanyId", CompanyId.ToString()));
        return userIdentity;
    }

Then on every request you'll be able to access this CompanyId claim from the cookie:

    public static int GetCompanyId(this IPrincipal principal)
    {
        var claimsPrincipal = principal as ClaimsPrincipal;
        //TODO check if claims principal is not null

        var companyIdString = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == "CompanyId");
        //TODO check if the string is not null

        var companyId = int.Parse(companyIdString); //TODO this possibly can explode. Do some validation
        return companyId;
    }

And then you'll be able to call this extension method from almost anywhere of your web application: HttpContext.Current.User.GetCompanyId()

trailmax
  • 34,305
  • 22
  • 140
  • 234