High Level Dependencies

IdentityDependency.png
ElCamino.AspNet.Identity.Dynamo.dll acts as the data access layer under the Microsoft.AspNet.Identity.Core.dll classes UserManager and RoleManager by implementing the necessary interfaces on the UserStore and RoleStore respectively. These classes consume the IdentityCloudContext and the other Identity Model classes described below to persist the user and role information according to the business logic dictated by the respective UserManager and RoleManager classes.

UserStore and RoleStore Classes

IdentityUserStoreRoleStore.png

IdentityCloudContext and Connections

IdentityCloudContext that enables access to the DynamoDB service and exposes the tables. The IdentityCloudContext default constructor will look for the IdentityConfigurationSection in the web.config which is new in version 1.0.0.0. If this configuration section is not found, the storage connection string under the ConnectionStrings key "DynamoConnectionString" which is a deprecated option that will be phased out in lieu of the configuration section or the new IdentityCloudContext(IdentityConfiguration config) overload. The new IdentityConfiguration class is Json serializable for ease of loading/saving these settings.
New in 1.0.0.0 - use the new TablePrefix property to set a naming prefix for the identity tables that are using in the DynamoDB instance. This enables multi-tenant support per storage account via configuration option for table name prefixing. e.g. Table prefix 'My' uses tables, MyAspNetIndex, MyAspNetRoles, MyAspNetUsers. This is an optional field, can be set to string.empty or left unset.
Example of using the new configuration section:
<configSections>
    <section name="elcaminoIdentityDynamoDBConfiguration" type="ElCamino.AspNet.Identity.Dynamo.Configuration.IdentityConfigurationSection,ElCamino.AspNet.Identity.Dynamo " />
  </configSections>    
<elcaminoIdentityDynamoDBConfiguration
    tablePrefix=""
    serviceURL="http://localhost:8000" />
Note: the following ConnectionStrings configuration option has been deprecated in 1.0.0.0 For example, the default local connection string to the DynamoDB Emulator.
<configuration>
  <connectionStrings>
    <!-- Deprecated ElCamino.AspNet.Identity.Dynamo settings -->
    <!--<add name="DynamoConnectionString" connectionString="http://localhost:8000" />-->
...

Identity Model to DynamoDB Relationships

IdentityModelToTable.png

AspNetUsers

Identity Model UserId (Hash) Id (Range) Cardinality
IdentityUser Guid Guid (same as Hash Key) 1 per user
IdentityUserClaim Guid Escaped(ClaimType, ClaimValue) 0 to Many per user
IdentityUserLogin Guid Escaped(LoginProvider, ProviderKey) 0 to Many per user
IdentityUserRole Guid Escaped(RoleName) 0 to Many per user

UserEmailIndex (Global Secondary Index) on AspNetUsers

Identity Model Email (Hash) Id (Range) Cardinality
IdentityUser Escaped(Email) Guid (same as UserId) 0 or 1 per user
IdentityUserClaim Escaped(Email) Escaped(ClaimType, ClaimValue) 0 to Many per user
IdentityUserLogin Escaped(Email) Escaped(LoginProvider, ProviderKey) 0 to Many per user
IdentityUserRole Escaped(Email) Escaped(RoleName) 0 to Many per user

UserNameIndex (Global Secondary Index) on AspNetUsers

Identity Model UserName (Hash) Id (Range) Cardinality
IdentityUser Escaped(UserName) Guid (same as UserId) 1 per user
IdentityUserClaim Escaped(UserName) Escaped(ClaimType, ClaimValue) 0 to Many per user
IdentityUserLogin Escaped(UserName) Escaped(LoginProvider, ProviderKey) 0 to Many per user
IdentityUserRole Escaped(UserName) Escaped(RoleName) 0 to Many per user

AspNetIndex

Identity Model Type Id (Hash) Cardinality
IdentityUserIndex User Login Index Escaped(LoginProvider, ProviderKey) 0 to Many per user

AspNetRoles

Identity Model Id (Hash)
IdentityRole Escaped(RoleName)


The properties of the respective identity model class are stored as a field in the table unless marked with the ignore attribute. Inheriting and extending these classes one can add fields whenever your extended class is saved. Also, the Escaped() psydo-code is a reference to the respective methods found in the KeyHelper class.

Performance

The AspNetUsers table is designed to keep all of the user's data in a single table and organized by UserId. This results in a single query using the user's id (hash key) to get all of the data in a single query when the user's id is known. The user's id is an arbitrary guid assigned to the user on creation and allows the UserStore.FindByUserByIdAsync() to query on the hashed key which is a very performant.
Addition Global Secondary Indexes UserNameIndex and UserEmailIndex allows to queries UserStore.FindByUserNameAsync() and UserStore.FindByEmailAsync() to use a hashed key for UserName and Email respectively to get the full user information.
The AspNetIndex table is queried by external login information on a hash key of a composite of the login provider and key used by UserStore.FindAsync() to get the user's id and then call UserStore.FindByUserByIdAsync() for the complete user information. The AspNextIndex is always queried by the hash key Id making that query extremely more efficient than scanning the AspNetUsers range key.
AspNetRoles table also uses the RoleName for the hash key Id making it possible query the table by its primary key optimizing performance.

Testing

A full suite of unit tests against this assembly ElCamino.AspNet.Identity.Dynamo.Tests.csproj

Release Management

  • Full suite of unit tests against this assembly at 100% pass rate against the DynamoDB Emulator and against a live AWS DynamoDB account. 100% pass rate is required before release. The tests are at about 99% code coverage currently and will work to keep the up.
  • Releases available on NuGet and are strong name signed. Binaries are available for download from this site.
  • https://www.nuget.org/packages/ElCamino.AspNet.Identity.Dynamo/

Last edited Sep 25, 2014 at 11:16 PM by dotnetdavy, version 7