Tag Archives: Portal

Production Tips for ASP .NET Core 3.1 Web Apps

By Shahed C on April 20, 2020

This is the sixteenth of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

In this Article:

P is for Production Tips

After getting through more than halfway in this A-Z series, this blog post takes a step back from application code to focus on productions tips. Once you’re ready to deploy (and maintain) your web app in production, there are many tips and tricks you should be aware of. In fact, feel free to discuss with your team members and the dev community to learn about other ways developers are deploying in production.

Server Environments from Dev to Prod via Staging
Server Environments from Dev to Prod via Staging

While this article focuses on deployments to Azure App Service, you can use some of the lessons learned for your own environments. That being said, I would highly recommend taking a look at Azure for all your staging and production deployment needs.

Deployment Slots

Azure makes it very easy to deploy your ASP .NET Core web application with the use of Deployment Slots. Instead of publish a web app directly to production or worrying about downtime, you can publish to a Staging Slot and the perform a “swap” operation to essentially promote your Staging environment into Production.

NOTE: To enable multiple deployment slots in Azure, you must be using an App Service in a Standard, Premium, or Isolated tier.

If you need help creating a Web App in App Service, you may refer to my blog post on the topic:

To make use of deployment slots for your Web App:

  1. Log in to the Azure Portal.
  2. Create a new Web App if you haven’t done so already.
  3. Locate the App Service blade for your Web App
  4. Enter the Deployment Slots item under Deployment
  5. Click + Add Slot to add a new slot
  6. Enter a Name, chose a source to clone settings (or not)
  7. Click the Add button to create a new slot
Deployment Slots in Azure App Service
Deployment Slots in Azure App Service

Once you set up multiple slots for staging and production, you may use the Swap feature to swap your deployed application when the staged deployment is ready to be deployed into production. Note that all slots are immediately live at the specified endpoints, e.g. hostname.azurewebsite.net.

You may also adjust website traffic by setting the Traffic % manually. From the above screenshot, you can see that the Traffic % is initially set to 0 for the newly-created slot. This forces all customer traffic to go to the Production slot by default.

When deploying your application through various means (Visual Studio Publish, Azure CLI, CI/CD from your Source Control System, etc), you may choose the exact slot when there is more than one. You may also set up “Auto-Swap” to swap a slot (e.g. staging) automatically into production, upon pushing code into that slot.

To learn more about all of the above, check out the official docs at:

Environment Configuration

To maintain unique configuration settings for each environment (e.g. staging database vs production database connection strings), you should have unique configuration settings for each environment. This is easily accomplished using the Configuration section in the Settings category of each slot’s unique blade.

Configuration screen in Azure App Service
Configuration screen in Azure App Service

NOTE: If you need help with User Secrets for your development environment or Key Vault secrets for your server environment, consider the following posts from my 2018 series and earlier in this 2020 series:

EF Core Migrations

You may be wondering how you can deploy structural changes from your database into production. Perhaps, you write manual SQL scripts to run in production, maybe you use a tool to generate such SQL scripts or a combination of both. Many developers aren’t aware but you can actually make use of Entity Framework Core (EF Core) Migrations to update your database structure.

To get a quick refresher on EF Core Migrations and Relationships, check out the following post:

You wouldn’t typically run your “Update Database” command in production. Instead, you could generate a SQL Script from your EF Core Migrations. This will allow you to inspect the SQL Scripts (revise them if necessary), hand them over to a DBA if appropriate and finally run the SQL Scripts in production when required.

The following PowerShell command can be run in Visual Studio’s Package Manager Console panel:

Script-Migration

The following CLI Command can be run on a Command Prompt, PowerShell prompt or VS Code Terminal window:

dotnet ef migrations script

You may set specific migrations to start from and/or end on:

Script-Migration -To <starting-migration>
Script-Migration -From <ending-migration>

You may also dump out the SQL scripts into a file for further inspection:

Script-Migration -Output "myMigrations.sql"

Scalability

If you’re deploying your web apps to Azure App Service, it’s a no-brainer to take advantage of scalability features. You could ask Azure to scale your app in various ways:

  • Scale Up: Upgrade to a more powerful (and higher priced) tier to add more CPU, memory and disk space. As you’ve seen with the appearance of staging slots, upgrading to a higher tier also provides additional features. Other features include custom domains (as opposed to just subdomains under azurewebsites.net) and custom certificates.
  • Scale Out: Upgrade the number of VM instances that power your web app. Depending on your pricing tier, you can “scale out” your web app to dozens of instances.
  • Autoscaling: When scaling out, you can choose when to scale out automatically:
    • Based on a Metric: CPU %, Memory %, Disk Queue Length, Http Queue Length, Data In and Data Out.
    • Up to a specific Instance Count: set a numeric value for the number of instances, set minmium and maximum.

An example of autoscaling on a metric could be: “When the CPU% is >50%, increase instance count by 1“. When you had new scaling conditions, you may also set a schedule to start/end on specific dates and also repeated on specific days of the week.

Adding a Scale Rule to Scale Out in Azure App Service
Adding a Scale Rule to Scale Out in Azure App Service

NOTE: In order to make use of Auto-Scaling, you’ll have to upgrade to the appropriate tier to do so. You can still use Manual Scaling at a lower tier. Scalability features are not available on the F1 Free Tier.

CI/CD

There are countless possibilities to make use of CI/CD (Continuous Integration and Continuous Deployment) to make sure that your code has been merged properly, with unit tests passing and deployed into the appropriate server environments. Some of your options may include one of the following: Azure Pipelines, GitHub Actions, or some other 3rd party solution.

  • Azure Pipelines: an offering of Azure DevOps services, you can quickly set up CI/CD for your web app, both public and private.
  • GitHub Actions: available via GitHub, the relatively-new Actions feature allows you to automate your workflow

The Deployment Center feature in Azure’s App Service makes it very easy to select Azure Pipelines (under Azure Repos) for your web app. This is all part of Azure DevOps Services, formerly known as VSTS (Visual Studio Team Services)

Deployment Center in Azure App Service
Deployment Center in Azure App Service

To get started with the above options, check out the official docs at:

TeamCity and Octopus Deploy are also popular products in various developer communities. Whatever you end up using, make sure you and your team select the option that works best for you, to ensure that you have your CI/CD pipeline set up as early as possible.

Troubleshooting

Once your application has been deployed, you may need to troubleshoot issues that occur in Production. You can use a combination of techniques, including (but not limited to) Logging, Error Handling and Application Insights.

  • Logging: From ASP .NET Core’s built-in logging provider to customizable structured logging solutions (such as Serilog), logging helps you track down bugs in any environment.
  • Error Handling: Anticipating errors before they occur, and then logging errors in production help you
  • Application Insights: Enabled by default in Azure’s App Service, Application Insights literally give you insight into your web application running in a cloud environment.

For more information on Logging and Error Handling, check out the earlier posts in this series:

For more information on Application Insights, check out the official documentation at:

References

Organizational Accounts for ASP .NET Core 3.1

By Shahed C on April 13, 2020

This is the fifteenth of a new series of posts on ASP .NET Core 3.1 for 2020. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2020, titled ASP .NET Core A-Z! To differentiate from the 2019 series, the 2020 series will mostly focus on a growing single codebase (NetLearner!) instead of new unrelated code snippets week.

Previous post:

NetLearner on GitHub:

NOTE: The NetLearner suite of apps won’t be updated to use organizational authentication in the main branch, so you can check out the new sample code in the experimental subfolder, merged from a branch:

In this Article:

O is for Organizational Accounts

If you’ve created new ASP .NET Core projects, you’ve probably seen an option to add authentication upon creation. In Visual Studio, the IDE provides radio buttons to select a specific type of Authentication. Using CLI commands (e.g. in the VS Code terminal) you can use the ‐‐auth flag to choose the type of authentication you’d like to add.

The possible values are:

  • None – No authentication (Default).
  • Individual – Individual authentication (accounts stored in-app).
  • IndividualB2C – Individual authentication with Azure AD B2C.
  • SingleOrg – Organizational authentication for a single tenant.
  • MultiOrg – Organizational authentication for multiple tenants.
  • Windows – Windows authentication..

In this article, we will focus on the option for Work or School Accounts. This option can be used to authenticate users with AD (Active Directory, Azure AD or Office 365. This authentication process is illustrated in the diagram shown below:

ASP .NET Core web authentication via AzureAD
ASP .NET Core web authentication via AzureAD

Adding Authentication

To add authentication to a new project quickly, here are the instructions for Visual Studio 2019.

If you choose to use the new splash screen:

  1. Click “Create a new project”
  2. Select “ASP .NET Core Web Application” or “Blazor” (server-side)
  3. Click Next
  4. Enter Project Name, Location, Solution Name
  5. Optional: check the checkbox to place in the same directory
  6. Click Create
  7. Select .NET Core and then ASP .NET Core 3.1 from dropdowns
  8. Select a project type, e.g. Empty, Web Application (Razor Pages or MVC), Blazor App.
  9. Click the “Change” action link in the Authentication section
Creating a new web app project with authentication
Creating a new web app project with authentication

This should allow you to change the authentication type to “Work or School Accounts” so that you may your organizational domain info. As always, you may select the little info buttons (lowercase i) to learn more about each field. Talk to your system administrator if you need more help on what domains to use.

Work/School account selected for authentication method

NOTE: If you need help creating new .NET Core 3.1 project types in Visual Studio, take a look at this previous blog post in this series on .NET Core 3.0 to get some help on how to enable it.

If you wish to skip the Splash Screen instead upon launching VS2019:

  1. Click “Continue without code” in the lower right area of the splash screen.
  2. In the top menu, click File | New | Project (or Ctrl-Shift-N)
  3. Follow the remaining steps outlined earlier in this section

To use CLI Commands in a Terminal window, use the dotnet new command followed by the ‐‐auth flag. The authentication type can be any of the aforementioned authentication types, e.g. Individual.

dotnet new mvc --auth Individual -o myproj

Configuring App Registration

If you’ve used “Individual User Accounts” before, you’ve probably used a database to store user data, either on-premises or in the cloud. If you’ve used “Work or School Accounts” (i.e. organizational accounts), you may have the old App portal at the following URL:

Old App Registration Portal
Old App Registration Portal

On the old site, you may see a message suggesting that you should go to the Azure Portal to use the newer (current) App Registrations feature. This feature was previously in preview, and you can currently use it directly in the Azure Portal. If you click the link from the old site, it should take you directly to the App Registrations page, and may prompt you to log in first.

TODO: screenshot of new (preview?) portal, overview section
App Registration screen showing overview

If you’re not clear about how you got to this screen or how to come back to it later, here’s a set of steps that may help.

  1. Log in to the Azure Portal
  2. Search for App Registrations
  3. Arrive at the App Registrations page
  4. When a newer preview version becomes available, you may have to click the banner that takes you to a preview experience.
New App Registration in Azure Portal
New App Registration in Azure Portal

In the form that follows, fill out the values for:

  • Name (which you can change later)
  • Account Type (your org, any org, any org + personal MSA)
  • Redirect URI (where users will return after authentication)
authentication
Register an application for authentication

Now you should have options to configure your app and also download a pre-written application to get started. In the QuickStart section for your newly registered application (after selecting  the guide for “ASP .NET Core”, you should see a button to make the changes for you and also download a configured Visual Studio application.

Quickstart screen for app registration
Quickstart screen for app registration

In the steps that follow:

  1. Click the “Make the changes for me” button to make the necessary configuration changes.
  2. Optional: Click the “Download” link to download the pre-configured Visual Studio solution, if you don’t already have a project.

At the time of this writing, the downloadable sample project is a VS2019 application for ASP .NET Core 2.2. You can download it to inspect it, but I would recommend creating a new project manually in VS2019. There may be some subtle differences between projects created by VS2019 with authentication turned on, versus what you get with the downloaded project.

For further customization using the Manifest file available to you, check out the official documentation on the Azure AD app manifest:

Using Authentication in Your Code

When creating a new project in VS2019, you get the following lines of code in your ConfigureServices() method, including calls to .AddAuthentication(). For different project types (MVC, Razor Pages, Blazor), you should also see some additional code setting up the authorization policy.

// contents of ConfigureServices() when created in VS2019

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

The string value “AzureAd” is referenced in your appsettings file, e.g. appsettings.json in MVC, Razor Pages, or Blazor projects. The properties for this entry include the following:

  • Instance: URL for login page, e.g. https://login.microsoftonline.com
  • Domain: your AD tenant’s domain, e.g. microsoft.onmicrosoft.com
  • TenantId: your Tenant Id value, usually a GUID
  • ClientId: Your app’s Client Id, obtained from app registration
  • Callback Path: partial path for sign-in, e.g. /signin-oidc
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<REPLACE_DOMAIN_NAME>",
    "TenantId": "<REPLACE_TENANT_ID>",
    "ClientId": "<REPLACE_CLIENT_ID>",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

You can see more information on appsettings.json values in the official docs. You can also open the apssettings.json from the portal-downloaded project to get your own app’s Id values. The following documentation is specifically written for v2, but offers explains for important fields such as ClientId and TenantId.

To get a refresher on Authentication and Authorization in ASP .NET Core 3.1, check out the following post on from earlier in this blog series.

For more on assigning users to specific roles, check out the official documentation at the following URL:

Finally, take a look at the Login.partial.cshtml partial view to observe the way a user’s identity is detected and shown in an MVC or Razor Pages web app. Here is a snippet from the samples:

@if (User.Identity.IsAuthenticated)
{
 <li class="nav-item">
 <span class="nav-text text-dark">Hello @User.Identity.Name!</span>
 </li>
...
}

NOTE: The Blazor web app wraps the authorized content in an <Authorized> tag within an <AuthorizedView. For more on the Blazor project, take a look at the Blazor post:

Depending on what you have access to, the User.Identity object may not contain everything you expect it to. Here are some things to take note of:

  • User.Identity should be null when not logged in
  • User.Identity should be non-null when logged in…
  • … however, User.Identity.Name may be null even when logged in
  • If User.Identity.Name is null, also check User.Identity.Claims
  • User.Identity.Claims should have more than 0 values when logged in

The following screenshot shows an example of the user information in my debugging environment when logged in:

 User.Identity.Name with Claims in debugger
User.Identity.Name with Claims in debugger

Running the Samples

Running the sample web projects should redirect you to the Azure AD login page for your tenant. The login page should look identical for all 3 project types: MVC, Razor Pages or Blazor. If you’ve already logged in to one or more accounts in your browser, you should have one or more identities to select from.

Once you’ve selected an account, you should see a confirmation screen (at least the first time) to Accept the authentication and login. This screen will look similar for all your projects, and the project name should be displayed in the middle.

 MVC app authentication confirmation
MVC app authentication confirmation
Razor Pages app authentication confirmation
Blazor app authentication confirmation
Blazor app authentication confirmation

Finally, you should see each web application with some indication that you are currently logged in. In the template-generated sample apps, this is demonstrated by the “Hello” message in the header area.

MVC web app, logged in
MVC web app, logged in
Razor Pages web app, logged in
Razor Pages web app, logged in
 Blazor web app, logged in
Blazor web app, logged in

References

Production Tips for ASP .NET Core Web Apps

By Shahed C on April 22, 2019

This is the sixteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

P is for Production Tips

After getting through more than halfway in this A-Z series, this blog post takes a step back from application code to focus on productions tips. Once you’re ready to deploy (and maintain) your web app in production, there are many tips and tricks you should be aware of. In fact, feel free to discuss with your team members and the dev community to learn about other ways developers are deploying in production.

From development to server environments

From development to server environments

While this article focuses on deployments to Azure App Service, you can use some of the lessons learned for your own environments. That being said, I would highly recommend taking a look at Azure for all your staging and production deployment needs.

Deployment Slots

Azure makes it very easy to deploy your ASP .NET Core web application with the use of Deployment Slots. Instead of publish a web app directly to production or worrying about downtime, you can publish to a Staging Slot and the perform a “swap” operation to essentially promote your Staging environment into Production.

NOTE: To enable multiple deployment slots in Azure, you must be using an App Service in a Standard, Premium, or Isolated tier.

If you need help creating a Web App in App Service, you may refer to my blog post on the topic:

To make use of deployment slots for your Web App:

  1. Log in to the Azure Portal.
  2. Create a new Web App if you haven’t done so already.
  3. Locate the App Service blade for your Web App
  4. Enter the Deployment Slots item under Deployment
  5. Click + Add Slot to add a new slot
  6. Enter a Name, chose a source to clone settings (or not)
  7. Click the Add button to create a new slot

AspNetCore-Prod-Slots

You may now use the Swap feature to swap your deployed application between staging and production when the staged deployment is ready to be deployed into production. Note that all slots are immediately live at the specified endpoints, e.g. hostname.azurewebsite.net.

You may also adjust website traffic by setting the Traffic % manually. From the above screenshot, you can see that the Traffic % is initially set to 0 for the newly-created slot. This forces all customer traffic to go to the Production slot by default.

When deploying your application through various means (Visual Studio Publish, Azure CLI, CI/CD from your Source Control System, etc), you may choose the exact slot when there is more than one. You may also set up “Auto-Swap” to swap a slot (e.g. staging) automatically into production, upon pushing code into that slot.

To learn more about all of the above, check out the official docs at:

Environment Configuration

To maintain unique configuration settings for each environment (e.g. staging database vs production database connection strings), you should have unique configuration settings for each environment. This is easily accomplished using the Configuration section in the Settings category of each slot’s unique blade.

AspNetCore-Prod-Slots-Staging-Config

NOTE: If you need help with User Secrets for your development environment or Key Vault secrets for your server environment, consider the following posts from my 2018 series and earlier in this 2019 series:

EF Core Migrations

You may be wondering how you can deploy structural changes from your database into production. Perhaps, you write manual SQL scripts to run in production, maybe you use a tool to generate such SQL scripts or a combination of both. Many developers aren’t aware but you can actually make use of Entity Framework Core (EF Core) Migrations to update your database structure.

To get a quick refresher on EF Core Migrations and Relationships, check out the following post:

You wouldn’t typically run your “Update Database” command in production. Instead, you could generate a SQL Script from your EF Core Migrations. This will allow you to inspect the SQL Scripts (revise them if necessary), hand them over to a DBA if appropriate and finally run the SQL Scripts in production when required.

The following PowerShell command can be run in Visual Studio’s Package Manager Console panel:

Script-Migration

The following CLI Command can be run on a Command Prompt, PowerShell prompt or VS Code Terminal window:

dotnet ef migrations script

You may set specific migrations to start from and/or end on:

Script-Migration -To <starting-migration>
Script-Migration -From <ending-migration>

You may also dump out the SQL scripts into a file for further inspection:

Script-Migration -Output "myMigrations.sql"

Scalability

If you’re deploying your web apps to Azure App Service, it’s a no-brainer to take advantage of scalability features. You could ask Azure to scale your app in various ways:

  • Scale Up: Upgrade to a more powerful (and higher priced) tier to add more CPU, memory and disk space. As you’ve seen with the appearance of staging slots, upgrading to a higher tier also provides additional features. Other features include custom domains (as opposed to just subdomains under azurewebsites.net) and custom certificates.
  • Scale Out: Upgrade the number of VM instances that power your web app. Depending on your pricing tier, you can “scale out” your web app to dozens of instances.
  • Autoscaling: When scaling out, you can choose when to scale out automatically:
    • Based on a Metric: CPU %, Memory %, Disk Queue Length, Http Queue Length, Data In and Data Out.
    • Up to a specific Instance Count: set a numeric value for the number of instances, set minmium and maximum.

An example of autoscaling on a metric could be: “When the CPU% is >50%, increase instance count by 1“. When you had new scaling conditions, you may also set a schedule to start/end on specific dates and also repeated on specific days of the week.

AspNetCore-Prod-Scale-Out

NOTE: In order to make use of Auto-Scaling, you’ll have to upgrade to the appropriate tier to do so. You can still use Manual Scaling at a lower tier. Scalability features are not available on the F1 Free Tier.

CI/CD

There are countless possibilities to make use of CI/CD (Continuous Integration and Continuous Deployment) to make sure that your code has been merged properly, with unit tests passing and deployed into the appropriate server environments. Some of your options may include one of the following: Azure Pipelines, GitHub Actions, or some other 3rd party solution.

  • Azure Pipelines: an offering of Azure DevOps services, you can quickly set up CI/CD for your web app, both public and private.
  • GitHub Actions: available via GitHub, the new Actions feature allows you to automate your workflow

The Deployment Center feature in Azure’s App Service makes it very easy to select Azure Pipelines (under Azure Repos) for your web app. This is all part of Azure DevOps Services, formerly known as VSTS (Visual Studio Team Services)

AspNetCore-Prod-Deploy

To get started with the above options, check out the official docs at:

TeamCity and Octopus Deploy are also popular products in various developer communities. Whatever you end up using, make sure you and your team select the option that works best for you, to ensure that you have your CI/CD pipeline set up as early as possible.

Troubleshooting

Once your application has been deployed, you may need to troubleshoot issues that occur in Production. You can use a combination of techniques, including (but not limited to) Logging, Error Handling and Application Insights.

  • Logging: From ASP .NET Core’s built-in logging provider to customizable structured logging solutions (such as Serilog), logging helps you track down bugs in any environment.
  • Error Handling: Anticipating errors before they occur, and then logging errors in production help you
  • Application Insights: Enabled by default in Azure’s App Service, Application Insights literally give you insight into your web application running in a cloud environment.

For more information on Logging and Error Handling, check out the earlier posts in this series:

For more information on Application Insights, stay tuned for an upcoming post in my next series that will focus on various Azure-related topics for ASP .NET Core developers.

References

 

Organizational Accounts for ASP .NET Core

By Shahed C on April 15, 2019

This is the fifteenth of a series of posts on ASP .NET Core in 2019. In this series, we’ll cover 26 topics over a span of 26 weeks from January through June 2019, titled A-Z of ASP .NET Core!

ASPNETCoreLogo-300x267 A – Z of ASP .NET Core!

In this Article:

O is for Organizational Accounts

If you’ve created new ASP .NET Core projects, you’ve probably seen an option to add authentication upon creation. In Visual Studio, the IDE provides radio buttons to select a specific type of Authentication. Using CLI commands (e.g. in the VS Code terminal) you can use the ‐‐auth flag to choose the type of authentication you’d like to add.

The possible values are:

  • None – No authentication (Default).
  • Individual – Individual authentication.
  • IndividualB2C – Individual authentication with Azure AD B2C.
  • SingleOrg – Organizational authentication for a single tenant.
  • MultiOrg – Organizational authentication for multiple tenants.
  • Windows – Windows authentication..

In this article, we will focus on the option for Work or School Accounts. This option can be used to authenticate users with AD (Active Directory, Azure AD or Office 365. In VS2019, a screenshot of the dialog is shown below:

AspNetCore-Auth-Azure

To follow along, take a look at the sample project on Github:

Web Org Authentication Sample: https://github.com/shahedc/AspNetCore2019Org

Adding Authentication

To add authentication to a new project quickly, here are the instructions for Visual Studio 2019.

If you choose to use the new splash screen:

  1. Click “Create a new project”
  2. Select “ASP .NET Core Web Application”
  3. Click Next
  4. Enter Project Name, Location, Solution Name
  5. Optional: check the checkbox to place in the same directory
  6. Click Create
  7. Select .NET Core 3.0 and then ASP .NET Core 3.0 from dropdowns
  8. Select a project type, e.g. Empty, Web Application (Razor Pages or MVC), etc
  9. Click the “Change” action link in the Authentication section

vs2019-project-new

This should allow you to change the authentication type to “Work or School Accounts” so that you may your organizational domain info. As always, you may select the little info buttons (lowercase i) to learn more about each field. Talk to your system administrator if you need more help on what domains to use.

vs2019-auth-options

NOTE: If you’re having trouble locating .NET Core 3.0 project types in Visual Studio, take a look at the previous blog post in this series on .NET Core 3.0 to get some help on how to enable it.

If you wish to skip the Splash Screen instead upon launching VS2019:

  1. Click “Continue without code” in the lower right area of the splash screen.
  2. In the top menu, click File | New | Project (or Ctrl-Shift-N)
  3. Follow the remaining steps outlined earlier in this section

To use CLI Commands in a Terminal window, use the dotnet new command followed by the ‐‐auth flag. The authentication type can be any of the aforementioned authentication types, e.g. Individual.

dotnet new mvc --auth Individual -o myproj

Configuring App Registration

If you’ve used “Individual User Accounts” before, you’ve probably used a database to store user data, either on-premises or in the cloud. If you’ve used “Work or School Accounts” (i.e. organizational accounts), you may have the old App portal at the following URL:

appdevreg-old

You may see a message suggesting that you should go to the Azure Portal to use the new App Registrations feature. Although this feature is currently in preview, you can start using it right now. If you click the link, it should take you directly to the App Registrations page, and may prompt you to log in first.

webreg-azure

If you’re not clear about how you got to this screen or how to come back to it later, here’s a set of steps that may help.

  1. Log in to the Azure Portal
  2. Search for App Registrations
  3. Arrive at the App Registrations page
  4. If necessary, click the banner that takes you to the preview experience.

webreg-portal-to-preview

The preview experience includes both your old and new app registrations. Click “New registration” to add a new app for authentication.

webreg-preview-add

In the form that follows, fill out the values for:

  • Name (which you can change later)
  • Account Type (your org, any org, any org + personal MSA)
  • Redirect URI (where users will return after authentication)

webreg-add-new

Now you should have options to configure your app and also download a pre-written application to get started. In the QuickStart section for your newly registered application (after selecting  the guide for “ASP .NET Core”, you should see a button to make the changes for you and also download a configured Visual Studio application.

webreg-azure-quickstart-aspnetcore

In the steps that follow:

  1. Click the “Make the changes for me” button to make the necessary configuration changes.
  2. Click the “Download” link to download the pre-configured Visual Studio solution.

webreg-azure-quickstart-aspnetcore-zoomed

At the time of this writing, the project type is a VS2017 application. You can download it to inspect it, but I would recommend creating a new project manually in VS2019. There are some subtle diferences between projects created by VS2019 with authentication turned on, versus what you get with the downloaded project.

For further customization using the Manifest file available to you, check out the official documentation on the Azure AD app manifest:

Using Authentication in Your Code

When creating a new project in VS2019, you get the following lines of code in your ConfigureServices() method, including calls to .AddAuthentication() and .addMvc().

// contents of ConfigureServices() when created in VS2019

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
      options.Filters.Add(new AuthorizeFilter(policy));
})
.AddNewtonsoftJson();

If you download the pre-configured project from the Azure portal, you may notice an additional block of code in between .AddAuthentication() and .addMVC().

// contents of ConfigureServices() when downloaded from Portal

services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
   options.Authority = options.Authority + "/v2.0/";
   options.TokenValidationParameters.ValidateIssuer = false;
});

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
   options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

This additional block calls services.Configure<OpenIdConnectOptions>() method to set up authentication for an Azure AD v2.0 endpoint. According to the documentation displayed in the Portal itself: “All users with a work or school, or personal Microsoft account can use your application or API. This includes Office 365 subscribers. To change the supported accounts for an existing registration, use the manifest editor. Take care, as certain properties may cause errors for personal accounts.

You can copy the this block of code manually into your VS2019 project, and refer to the sample project’s Startup.cs file.

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
   options.Authority = options.Authority + "/v2.0/";
   options.TokenValidationParameters.ValidateIssuer = false;
});

There is also a difference in the Compatibility Version setting in the code. The downloaded project for VS2017 currently sets compatibility for v2.1 but you can manually set this to 3.0 when you create a project manually in VS2019, as seen in this snippet from the sample Startup.cs file.

services.AddMvc(options =>
{
   var policy = new AuthorizationPolicyBuilder()
      .RequireAuthenticatedUser()
      .Build();
   options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

Endpoint Routing in MVC

In the Configure() method of Startup.cs, the downloaded project contains familiar method calls to various Middleware components.

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();

app.UseAuthentication();

app.UseMvc(routes =>
{
   routes.MapRoute(
   name: "default",
   template: "{controller=Home}/{action=Index}/{id?}");
});

When you create an ASP .NET Core 3.0 project in VS2019, you may see the new Endpoint Routing feature, which makes it look like this:

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting(routes =>
{
   routes.MapControllerRoute(
   name: "default",
   template: "{controller=Home}/{action=Index}/{id?}");
});

app.UseCookiePolicy();

app.UseAuthentication();
app.UseAuthorization();

You may notice the addition of app.UseRouting() appearing in between app.UseStaticFiles() and app.UseCookiePolicy, and there is no explicit call to app.UseMvc(). This doesn’t mean that the application is calling MVC ahead of time. Rather, the release notes explains it  well:

So think of UseRouting(…) as making a deferred routing decision – where middleware that appear after it run in the middle. Any middleware that run after routing can see the results and read or modify the route data and chosen endpoint. When processing reaches the end of the pipeline, then the endpoint is invoked.

You can read more about this in the writeup for v3.0 Preview 2:

App Settings and Identity

In your appsettings.json file, you can set values for your App Settings. This includes the following AzureAd settings:

  • Instance
  • Domain
  • ClientId
  • TenantId
  • CallbackPath
{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "<YOUR_SUB_DOMAIN>.onmicrosoft.com",
    "ClientId": "<YOUR_CLIENT_ID>",
    "TenantId": "<YOUR_TENANT_ID>",
    "CallbackPath": "/signin-oidc"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

You can see more information on appsettings.json values in the official docs. You can also open the apssettings.json from the portal-downloaded project to get your own app’s Id values. The following documentation is specifically written for v2, but offers explains for important fields such as ClientId and TenantId.

To ensure that your authentication is working correctly, you can test it out by applying the [Authorize] attribute on a controller, e.g. the HomeController.cs class.

[Authorize]
public class HomeController : Controller
{
   //
}

To get a refresher on how to use the [Authorize] attribute, check out the post on Authorization from earlier in this blog series. For more on assigning users to specific roles, check out the official documentation at the following URL:

Finally, take a look at the Login.partial.cshtml partial view to observe the way a user’s identity is detected and shown. Here is a snippet from the sample:

@if (User.Identity.IsAuthenticated)
{
 <li class="nav-item">
 <span class="nav-text text-dark">Hello @User.Identity.Name!</span>
 </li>
}

Depending on what you have access to, the User.Identity object may not contain everything you expect it to. Here are some things to take note of:

  • User.Identity should be null when not logged in
  • User.Identity should be non-null when logged in…
  • … however, User.Identity.Name may be null even when logged in
  • If User.Identity.Name is null, also check User.Identity.Claims
  • User.Identity.Claims should have more than 0 values when logged in

The following screenshot shows an example of the user information in my debugging environment when logged in:

vs2019-login-identity-claims


References: