Extend application user (Angular)

Radzen provides security support out of the box, more info can be found in our Security article. This guide demonstrates how to extend application user.

Source Code

Often there would be a need to extend the user entity by adding additional properties.

Add ApplicationUser partial class

  1. Go to the server\Authentication directory.
  2. Add a new file called ApplicationUser.Properties.cs. It will extend the ApplicationUser partial class.
  3. Add a new property e.g. Country
         using System;
         using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    
         // Replace [ApplicationName] with the namespace of your Radzen application.
         namespace [ApplicationName].Models
         {
             public partial class ApplicationUser
             {
                 public string Country { get; set; }
             }
         }
    
         Imports System
         Imports Microsoft.AspNetCore.Identity.EntityFrameworkCore
    
         Namespace [ApplicationName].Models
             Public Partial Class ApplicationUser
                   Public Property Country As String
             End Class
         End Namespace
    
  4. Open the server directory in a terminal.
  5. Run dotnet ef migrations add Country -c ApplicationIdentityDbContext. This will create an Entity Framework Core migration which at runtime will add a Country column to the AspNetUsers table. It will store the Country property values.

Extend the Register User page

In order to capture the values of the custom properties created in the previous step you have to update the Register Application User page.

  1. Open Register Application User in design time.
  2. Select the Form component in the design surface.
  3. Add a new string form field. Set its Type to string and Property to Country.

Make the custom properties available at the client-side

Often you would need to use some of the custom properties at the client-side - in the Angular application. You need to expose them in the client-side profile object first.

  1. Go to the server\Authentication directory.
  2. Add a new file called ApplicationPrincipalFactory.Properties.cs. It will specify which properties to be available at the client-side.
  3. Define OnCreatePrincipal partial method with the following body:
         using System.Security.Claims;
         using [ApplicationName].Models;
    
         namespace [ApplicationName].Authentication
         {
             public partial class ApplicationPrincipalFactory
             {
                 partial void OnCreatePrincipal(ClaimsPrincipal principal, ApplicationUser user)
                 {
                     var identity = principal.Identity as ClaimsIdentity;
    
                     if (!string.IsNullOrEmpty(user.Country))
                     {
    
                         // the property will be available at the client-side.
                         identity.AddClaim(new Claim("country", user.Country));
                     }
                 }
             }
         }
    
       Imports System.Security.Claims
       Imports [ApplicationName]
    
       Namespace [ApplicationName].Authentication
             Public Partial Class ApplicationPrincipalFactory
                   Private Partial Sub OnCreatePrincipal(ByVal principal As ClaimsPrincipal, ByVal user As ApplicationUser)
                         Dim identity = TryCast(principal.Identity, ClaimsIdentity)
    
                         If Not String.IsNullOrEmpty(user.Country) Then
                               identity.AddClaim(New Claim("country", user.Country))
                         End If
                   End Sub
             End Class
       End Namespace
    

    If the property type is not string you need to add the new Claim with proper type:

     public partial class ApplicationUser
     {
         public Boolean Active { get; set; }
     }
     ...
     identity.AddClaim(new Claim("active", user.Active.ToString(), System.Security.Claims.ClaimValueTypes.Boolean));
    
     Public Partial Class ApplicationUser
         Public Property Active As Boolean
     End Class
     ...
     dentity.AddClaim(New Claim("active", user.Active.ToString(), System.Security.Claims.ClaimValueTypes.Boolean))
    
  4. At the client-side you can now use the Country property:

    <div *ngIf="security.isAuthenticated()">{{ security.profile.country }}</div>