DotVVM Authorization With IdentityServer4

DotVVM is an open source MVVM framework for ASP.Net Core and OWIN and it is a member of .Net Foundation. DotVVM is  free to use under the Apache License but also has commercial extensions.
 
DotVVM lets you build interactive web UIs with just C# and HTML using MVVM pattern. DotVVM framework is shipped with many built-in controls like GridView, FileUpload, Validators, and more.
 
To learn more about the DotVVM framework visit DotVVM.com.
 
In this article we will see how to secure your DotVVM web application using IdentityServer4.
 

What is IdentityServer4?

 
IdentityServer4 is an OpenID Connect and OAuth2.0 framework for ASP.Net Core. it enables:
  • Authentication as a service
  • Single Sign-n (SSO)
  • Access control for APIsn and more.
It is an open source framework and  you can get its code from GitHub repository and the full documentation.
 
You can check my previous article to know how to install DotVVM extension.
 
First of all we need to prepare our IdentityServer4 as our authentication service. IdentityServer4 has different templates to use, for simplicity we will use out of the box IdentityServer4 UI template which provides a complete UI for defining roles, users, clients, claim types,.etc.
  1. To install IdentityServer templates for dotnet CLI run this command in console window.
    1. dotnet new -i IdentityServer4.Templates  
  2. From cmd or windows PowerShell run following commands
    1. md dotvvm/src //create folder for our solution  
    2. cd dotvvm/src  
    3. dotnet new sln -n dotvvm  
    4. dotnet new is4admin -n dotvvm.auth  
    5. dotnet sln add .\dotvvm.auth\dotvvm.auth.csproj  
  3. Open your solution in vs2019 or vs code, your solution should look like,


  4. Build and run your solution and  it should show a page like this,

      

  5. Open Users page and click on Add User button then fill the New User form where you define your user and his login credentials.



  6. Save user name and password as you will use it when you run your DotVVM application.

Define your application as Client

  1. Open Clients page and click on Add Client button
  2. Select Web App then click Start
  3. Fill your application main details then click Next.

    • Client ID : dotvvm-article-sample.
    • DotVVM Framework
    • https://localhost:5001



  4. Protected Resources: Select all available resources that can be accessible by your DotVVM application then click Next.
  5. Review your choices and click Save
  6. Open your client details and go to Advanced -> Token tab and check Always Include UserClaims In Id Token

The differences between different options we have selected is beyond the scope of this post.
 

DotVVM Application

 
We will create a new empty DotVVM application, just include Bootstrap and Authentication sample code.
 
You can check this [post](https://dev.to/dotvvm/dotvvm-crud-application-with-entity-framework-and-cosmos-db-4oah) for full steps of DotVVM application creation.
 
 
It is recommended to change the target framework of your DotVVM application to .Net Core 3.1 and also re-install Microsoft.AspNetCore.Authentication.Cookies package.
  1. Open Program.cs file and add the following line to BuildWebHost method. We specify the URL of the DotVVM application to match what we have used while configuring the IdentityServer client.
    1. .UseUrls("https://localhost:5001")  
  2. Install Microsoft.AspNetCore.Authentication.OpenIdConnect package.
    1. install-package Microsoft.AspNetCore.Authentication.OpenIdConnect  
  3. Replace ConfigureServices method with the following code
    1. public void ConfigureServices(IServiceCollection services)  
    2. {  
    3.    services.AddDataProtection();  
    4.    services.AddAuthorization();  
    5.    services.AddWebEncoders();  
    6.    JwtSecurityTokenHandler.DefaultMapInboundClaims = false;  
    7.    services.AddAuthentication(options =>{  
    8.       options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;  
    9.       options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;  
    10.    })  
    11.    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)  
    12.    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>{  
    13.       options.Authority = "http://localhost:5000";  
    14.       options.RequireHttpsMetadata = false;  
    15.       options.SaveTokens = true;  
    16.       options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;  
    17.       options.ClientId = "dotvvm-article-sample";  
    18.       options.ClientSecret = "dotvvm-secret";  
    19.       options.ResponseType = "id_token token";  
    20.       options.Scope.Add("openid");  
    21.       options.Scope.Add("profile");  
    22.       options.CallbackPath = "/signin-oidc";  
    23.    });  
    24.    services.AddRazorPages();  
    25.    services.AddDotVVM<DotvvmStartup>();  
    26. }  
  4. Replace Configure method with the following code
    1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
    2. {  
    3.    app.UseAuthentication();  
    4.    app.UseRouting();  
    5.    app.UseAuthorization();  
    6.    // use DotVVM  
    7.    var dotvvmConfiguration = app.UseDotVVM<DotvvmStartup>(env.ContentRootPath);  
    8.    dotvvmConfiguration.AssertConfigurationIsValid();  
    9.    // use static files  
    10.    app.UseStaticFiles(new StaticFileOptions  
    11.    {  
    12.       FileProvider = new PhysicalFileProvider(env.WebRootPath)  
    13.    });  
    14.    app.UseEndpoints(endpoints =>  
    15.    {  
    16.       endpoints.MapRazorPages();  
    17.    });  
    18. }  
  5. Open ViewModels/MasterPageViewModel.cs file and decorate MaterPageViewModel class with Authorize attribute.
    1. [Authorize]  
    2. public class MasterPageViewModel : DotvvmViewModelBase  
  6. Add the following line to MasterPageVeiwModel class to read the name of the logged in user from IdentityServer claims.
    1. public string Username => Context.HttpContext.User.FindFirst("name")?.Value;  
  7. Open Views/Default.dothtml file and add this div to content control
    1. <div class="alert alert-info">Welcome to DotVVM, {{value: Username}}</div>  
  8. First you must run dotvvm.auth project and once you run your dotvvm.web project it will be redirected to the login page of IdentityServer.

 

Summary

 
In this article we showed how to use IdentityServer4 to Authenticate your DotVVM application.
 
You can find the complete code sample in GitHub.