Device to Cloud Messaging Azure IOT Hub

I would like to route the IOT hub device to cloud messages to the asp.net core web app hosted as azure AppService. I am not sure whether it is possible. If yes, could you please provide the necessary instructions to achieve the same.

I would like to route the IOT hub device to cloud messages to the asp.net core web app hosted as azure AppService. I am not sure whether it is possible. If yes, could you please provide the necessary instructions to achieve the same.

ASP.NET MVC tutorial for Azure Cosmos DB: How to use Azure Cosmos DB

ASP.NET MVC tutorial for Azure Cosmos DB: How to use Azure Cosmos DB

In this article, you will learn how to use Azure Cosmos DB - a key-value store solution - your ASP.NET app instead of a relational database.

In this article, you will learn how to use Azure Cosmos DB - a key-value store solution - your ASP.NET app instead of a relational database.

Cosmos DB is a planet-scale database capable of holding billions of records (“documents” using Cosmos jargon) without significant detriment to performance.

To demonstrate their differences, check out a simple example query using both a relational database and Cosmos DB. When you query a relational database you get back a set of rows. All rows have the same columns and some may have relationships to other rows. Take a look:

SELECT * FROM Items WHERE Name = 'WebForm' 

Record Found

When you query Azure Cosmos DB, you get back a CLOB - a character large object - in this case, a JSON file. In the example below c refers to the collection, determined by the URL being queried.

SELECT * FROM c WHERE c.Name = '' 

Record Found

{
    "name": "Netflix",
    "amount": 16,
    "frequency": "m",
    "startDate": "2019-06-01T00:00:00",
    ...
}

While Cosmos is powerful, data with complex relationships may be better off in a relational database than in a key-value store like Azure Cosmos DB. Relationships get tricky with Cosmos and often result in multiple transactions to get the data you need.

What you’ll need for this post:

Scaffold Your ASP.NET Web Project

Let’s get started! Open Visual Studio and add a new ASP.NET Web Application (.NET Framework) project. Give your new project a name that is meaningful to you, I’m calling mine ExpenseWebApp. Then select MVC as the ASP.NET 4.6.1 Template.

Define Object Models for Your ASP.NET + Cosmos DB App

Let’s define our model objects. The following objects will be used to send data through the layers of the app.

Right click on Models and add a new class named Expense.cs. Paste the following code into the new file.

using System;
using Newtonsoft.Json;

namespace ExpenseWebApp.Models
{
  public class Expense
  {
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }

    [JsonProperty(PropertyName = "amount")]
    public double Amount { get; set; }

    [JsonProperty(PropertyName = "frequency")]
    public string Frequency { get; set; }

    [JsonProperty(PropertyName = "startDate")]
    public DateTime StartDate { get; set; }

    [JsonProperty(PropertyName = "monthlyCost")]
    public double MonthlyCost { get; set; }
  }
}

Right click on Models and add a new class named Payment.cs. Paste the following code into the new file.

using System;

namespace ExpenseWebApp.Models
{
  public class Payment
  {
    public DateTime DueDate { get; set; }
    public double Amount { get; set; }
  }
}
Create Cosmos DB in Azure

Cosmos DB is where we’ll be storing the data used by your application. The Cosmos portion of this project is divided into two parts - first creating the Cosmos DB, and second programming our ASP.NET App to connect to it.

Login to your Microsoft Azure Portal and go to Azure Cosmos DB under All resources. Click the Add button, then make sure to specify the following settings:

Account Name = expense-cosmos-db API = Core (SQL)

Next click Review + create. Then on the subsequent screen click Create. You will be taken to a screen showing the status of your new Azure Cosmos DB - this may take a few minutes.

When your Cosmos DB is ready to go, click Go to resource which will take you to the Quick start guide. For this tutorial, we’ll use the Items container that Azure creates for you automatically, so go ahead and click Create ‘Items’ container.

Finally, select a resource group. If you don’t already have a resource group you want to put Cosmos DB into, feel free to create a new one.

Before navigating away from Azure, you’ll want to copy some values to your web.config under AppSettings.

Go to to Keys under your new expense–cosmos-db and copy the value from URI to Cosmos.EndPointUrl in your web.config. Then copy the value from PRIMARY KEY to Cosmos.AuthorizationKey in your web.config.





Side note: Data Explorer is where you would go if you want to browse the data in your containers. Although not utilized in this article, you will probably end up using it frequently to examine your data in the future!

Connect Your ASP.NET App to Azure Cosmos DB

Add the following Nuget Package to your project:

Microsoft.Azure.DocumentDB v2.4.0

Right click on Models and add a new class named CosmosConfig.cs. This class will be used to store the Cosmos DB configuration settings. Paste the following code into the new file.

using System;

namespace ExpenseWebApp.Models
{
  public class CosmosConfig
  {
    public string EndPointUrl { get; set; }
    public string AuthorizationKey { get; set; }

    public string DatabaseId { get; set; }
    public string ExpenseCollectionId { get; set; }
  }
}

Right click on Global.asax and select View Code. Overwrite the code that’s currently in the file with the following.

using System.Configuration;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Helpers;

using ExpenseWebApp.Models;

namespace ExpenseWebApp
{
  public class MvcApplication : HttpApplication
  {
    protected void Application_Start()
    {
      AreaRegistration.RegisterAllAreas();
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
      RouteConfig.RegisterRoutes(RouteTable.Routes);
      BundleConfig.RegisterBundles(BundleTable.Bundles);

      MvcApplication.InitCosmosConfig();
    }

    public static CosmosConfig CosmosConfig { get; set; }

    private static void InitCosmosConfig()
    {
      AntiForgeryConfig.UniqueClaimTypeIdentifier = "name";
      MvcApplication.CosmosConfig = new CosmosConfig()
      {
        DatabaseId = ConfigurationManager.AppSettings["Cosmos.DatabaseId"],
        EndPointUrl = ConfigurationManager.AppSettings["Cosmos.EndPointUrl"],
        AuthorizationKey = ConfigurationManager.AppSettings["Cosmos.AuthorizationKey"],
        ExpenseCollectionId = ConfigurationManager.AppSettings["Cosmos.ExpenseCollectionId"]
      };
    }
  }
}

This new code creates the static CosmosConfig property of MvcApplication to store your Cosmos configuration settings. It also defines InitCosmosConfig() and calls it when the application starts.

The HomeController will do the bulk of the work. Right click on HomeController.cs and select View Code. Overwrite the code in the file with the following.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Mvc;

using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;

using ExpenseWebApp.Models;

namespace ExpenseWebApp.Controllers
{
  public class HomeController : Controller
  {
    public async Task Index()
    {
      ViewBag.Title = "Expenses";

      //get expenses from Cosmos DB
      var expenses = await this.GetExpenses();

      var monthStart = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);

      //calculate payments that will take place over 2 months from the start of this month
      var payments = this.GetPayments(expenses, monthStart, monthStart.AddMonths(2));

      //calculate how much is owed over specific time periods
      ViewBag.AlreadyPaid = this.OwedDuring(payments, monthStart, DateTime.Today - new TimeSpan(1, 0, 0, 0));
      ViewBag.DueToday = this.OwedDuring(payments, DateTime.Today, DateTime.Today);
      ViewBag.StillComing = this.OwedDuring(payments, DateTime.Today.AddDays(1), monthStart.AddMonths(1) - new TimeSpan(1, 0, 0, 0));

      ViewBag.Next1Week = this.OwedDuring(payments, DateTime.Today, DateTime.Today.AddDays(7));
      ViewBag.Next2Weeks = this.OwedDuring(payments, DateTime.Today, DateTime.Today.AddDays(14));
      ViewBag.Next1Month = this.OwedDuring(payments, DateTime.Today, DateTime.Today.AddMonths(1));
      ViewBag.Next2Months = this.OwedDuring(payments, DateTime.Today, DateTime.Today.AddMonths(2));

      return View(expenses);
    }

    [HttpPost]
    [ActionName("Create")]
    [ValidateAntiForgeryToken]
    public async Task CreateAsync([Bind(Include = "Name,Amount,Frequency,StartDate")] Expense input)
    {
      if (ModelState.IsValid)
        using (var client = new DocumentClient(new Uri(MvcApplication.CosmosConfig.EndPointUrl), MvcApplication.CosmosConfig.AuthorizationKey))
        {
          await client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(MvcApplication.CosmosConfig.DatabaseId, MvcApplication.CosmosConfig.ExpenseCollectionId), input);
          return RedirectToAction("Index");
        }

      return View(input);
    }


    private List GetPayments(List expenses, DateTime start, DateTime finish)
    {
      var ret = new List();

      //get all payments between specified start and finish dates
      foreach (var e in expenses)
        for (var x = e.StartDate; x <= finish;)
        {
          if (x >= start)
            ret.Add(new Payment() { Amount = e.Amount, DueDate = x });
          x = this.GetNextDueDate(x, e.Frequency);
        }

      return ret;
    }
    private DateTime GetNextDueDate(DateTime lastDueDate, string frequency)
    {
      if (frequency == "w")
        return lastDueDate.AddDays(7);
      else if (frequency == "m")
        return lastDueDate.AddMonths(1);
      else if (frequency == "q")
        return lastDueDate.AddMonths(3);
      else if (frequency == "y")
        return lastDueDate.AddYears(1);

      throw new Exception("Invalid expense frequency - unable to get the next due date");
    }
    private double OwedDuring(List payments, DateTime start, DateTime finish)
    {
      double ret = 0;

      for (var i = 0; i < payments.Count; i++)
        if (payments[i].DueDate >= start && payments[i].DueDate <= finish)
          ret += payments[i].Amount;

      return ret;
    }

    private async Task> GetExpenses()
    {
      var ret = new List();

      using (var client = new DocumentClient(new Uri(MvcApplication.CosmosConfig.EndPointUrl), MvcApplication.CosmosConfig.AuthorizationKey))
      {
        IDocumentQuery query = client.CreateDocumentQuery(
          UriFactory.CreateDocumentCollectionUri(MvcApplication.CosmosConfig.DatabaseId, MvcApplication.CosmosConfig.ExpenseCollectionId),
          new FeedOptions { MaxItemCount = -1 })
          .AsDocumentQuery();

        while (query.HasMoreResults)
          ret.AddRange(await query.ExecuteNextAsync());

        for (var i = 0; i < ret.Count; i++)
          ret[i].MonthlyCost = CalculateMonthlyCost(ret[i]);
      }

      return ret;
    }
    private double CalculateMonthlyCost(Expense input)
    {
      if (input.Frequency == "w")
        return input.Amount * 52 / 12;

      else if (input.Frequency == "m")
        return input.Amount;

      else if (input.Frequency == "q")
        return input.Amount / 3;

      else if (input.Frequency == "y")
        return input.Amount / 12;

      throw new Exception("Invalid expense frequency - unable to calculate the monthly cost");
    }
  }
}

The Index() action will now pass a list of expenses as the model. It also calculates several values passed via the ViewBag such as Next1Week and Next2Weeks which reflect the amount that will be owed over the next week, and next 2 weeks respectively.

Refer to GetExpenses() to see how data is pulled from Azure Cosmos DB.

Refer to GetPayments() to see the algorithm for calculating how many payments will occur over a specified period of time, based on the expenses and how often they recur (IE: weekly, monthly, quarterly, or yearly).

Get Your Cosmos DB Data to the ASP.NET App UI

First things first on the UI, you need to throw together some markup! Open up Views\Home\Index.cshtml and overwrite the code that’s currently in the file with the following.



  # @ViewBag.Title

  
    ### This month...

    Already paid
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.AlreadyPaid)" />
    Due today
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.DueToday)" />
    Still coming
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.StillComing)" />
  
  
    ### Next...

    1 week
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.Next1Week)" />
    2 weeks
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.Next2Weeks)" />
    1 month
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.Next1Month)" />
    2 months
    <input type="text" readonly="readonly" class="highlight"
    value="@string.Format("{0:C}", ViewBag.Next2Months)" />
  



  
  ## List of Expenses

  
    
      @*
      
      *@
      Name
      Monthly Cost
    
    @if (Model != null) { var total = 0; foreach (var e in Model) { total +=
    e.MonthlyCost;
    
      @e.Name
      @string.Format("{0:C}", e.MonthlyCost)
    
    }
    
      Total
      @string.Format("{0:C}", total)
    
    }
  

  
  @using (Html.BeginForm("Create", "Home")) { @Html.AntiForgeryToken()

  ### Add Expense


  Name
  

  Amount
  

  Frequency
  
    Weekly
    Monthly
    Quarterly
    Yearly
  

  Start Date
  

  
  }

This code adds:

  • A summary of upcoming expenses at the top of the page
  • A list of expenses and their monthly costs
  • A form to add new expenses

At this point, you’ll be able to run your app with all the functionality in place, but no styling other than what comes out of the box.

Of course we want more styling, so open up Site.css - located in the Content folder. Overwrite everything from line 19 down, with the following, then re-run your app to see the changes.

/* Set width on the form input elements since they're 100% wide by default */
input,
label,
select,
textarea {
  display: block;
  margin: 0px 0px 0px 0px;
}
label {
  margin-top: 5px;
}

input[type='submit'] {
  margin-top: 20px;
  display: block;
  margin: auto;
}

/* Custom styling */
div.left {
  float: left;
  width: 45%;
  overflow: hidden;
}
div.right {
  overflow: hidden;
}

div.jumbotron input[readonly='readonly'] {
  margin: 0px 0px 0px 0px;
  padding: 0px 0px 0px 0px;
  background-color: transparent;
  border-style: none;
}
input.highlight {
  font-weight: bold;
  color: darkgreen;
}

tr.header td {
  border-style: solid;
  border-width: 1px;
  border-color: #000000;
  padding: 4px 15px 4px 15px;
  text-align: center;
}
tr.header td.empty {
  border-style: none;
}

tr td {
  padding: 4px 4px 4px 4px;
}
tr td.money {
  text-align: right;
  color: darkgreen;
}
tr td.total {
  text-align: right;
  font-weight: bold;
  font-style: italic;
}
Implement Authentication in ASP.NET with Okta

Okta is a developer API service with SDKs and tooling that make it easy to store user accounts and add registration, login, multi-factor auth and more to your app. If you don’t already have one, you’ll need to create a free Okta developer account.

After creating an account, Okta will provide a URL for your organization called an “Okta domain”. Be sure to check your email for instructions to complete your registration.

Once you have logged in, on your administrator dashboard, click Applications in the main menu and on the Application screen, click Add Application.

Select Web then click Next.

On the Create New Application screen, set the values I have shown below, but make sure the port is set correctly. Visual Studio will assign a random port to new applications to make it easy for you to have multiple running at the same time. To see what port your app is using, click Run in visual studio, and replace 59601 in the URLs below, with the port your app is running on.

  • Base URIs: [http://localhost:59601/](http://localhost:59601/)
  • Login redirect URIs: [http://localhost:59601/authorization-code/callback](http://localhost:59601/authorization-code/callback)
  • Initiate login URI: [http://localhost:59601/authorization-code/callback](http://localhost:59601/authorization-code/callback)
  • Allow grant types:
  • Authorization Code
  • Implicit (Hybrid)

After you save your settings, click Edit by General Settings, then check the following two checkboxes as shown in the screenshot below:

  • Allow ID Token with implicit grant type
  • Allow Access Token with implicit grant type

Next, scroll to the bottom and copy your Client ID and Client secret. Paste Client ID into the okta:ClientId appSetting in your web.config. Paste Client secret into the okta.ClientSecret appSetting in your web.config. Also make sure the ports are set correctly for the okta:RedirectUri and okta:PostLogoutRedirectUri appSetting records.






Your Okta account is now setup and ready to go. Now we just have to code it into our app to make it secure.

Secure Your ASP.NET App

To secure your web app with Okta you’ll need to install the following Nuget Packages:

  • Microsoft.Owin.Host.SystemWeb v4.0.1
  • Microsoft.Owin.Security.Cookies v4.0.1
  • Okta.AspNet v1.1.5

Right click on your project and add a new class called Startup.cs. In that file paste the following code:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Okta.AspNet;
using System.Collections.Generic;
using System.Configuration;

[assembly: OwinStartup(typeof(ExpenseWebApp.Startup))]

namespace ExpenseWebApp
{
  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

      app.UseCookieAuthentication(new CookieAuthenticationOptions());

      app.UseOktaMvc(new OktaMvcOptions()
      {
        OktaDomain = ConfigurationManager.AppSettings["okta:OktaDomain"],
        ClientId = ConfigurationManager.AppSettings["okta:ClientId"],
        ClientSecret = ConfigurationManager.AppSettings["okta:ClientSecret"],
        RedirectUri = ConfigurationManager.AppSettings["okta:RedirectUri"],
        PostLogoutRedirectUri = ConfigurationManager.AppSettings["okta:PostLogoutRedirectUri"],
        GetClaimsFromUserInfoEndpoint = true,
        Scope = new List { "openid", "profile", "email" },
      });
    }
  }
}

Next we’ll need to create the Account controller to handle login and logout events. Add a new file to Controllers called AccountController.cs. In that file paste the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Microsoft.Owin.Security.Cookies;
using Okta.AspNet;

namespace ExpenseWebApp.Controllers
{
  public class AccountController : Controller
  {
    public ActionResult Login()
    {
      if (!HttpContext.User.Identity.IsAuthenticated)
      {
        HttpContext.GetOwinContext().Authentication.Challenge(
          OktaDefaults.MvcAuthenticationType);
        return new HttpUnauthorizedResult();
      }

      return RedirectToAction("Index", "Expense");
    }

    [HttpPost]
    public ActionResult Logout()
    {
      if (HttpContext.User.Identity.IsAuthenticated)
      {
        HttpContext.GetOwinContext().Authentication.SignOut(
          CookieAuthenticationDefaults.AuthenticationType,
          OktaDefaults.MvcAuthenticationType);
      }

      return RedirectToAction("Index", "Home");
    }

    public ActionResult PostLogout()
    {
      return RedirectToAction("Index", "Home");
    }
  }
}

Once complete, your security settings are in place and we just need to tell our App which pages to apply the security to. We’ll do this by placing the [Authorize] attribute on the controller we want to be secured. Open up HomeController.cs and paste the following [Authorize] attribute just above the class declaration on line 13, as shown below:

  [Authorize]
  public class HomeController : Controller
  {
    ...
Update Template with User Authentication Status

Open up Views\Shared\_Layout.cshtml and overwrite the contents of lines 22 through 26 with the following:

@if (Context.User.Identity.IsAuthenticated) {
*Hello, **@Context.User.Identity.Name**
* Log out


} else {
* @Html.ActionLink("Log in", "Login", "Account")

}
Run Your ASP.NET MVC App

To run your App, simply click Run in Visual Studio. You will be taken to the Okta login page and then to the Expenses screen after successfully logging in. Your new app is very simple and provides plenty of room for you to continue building out the feature set.

DevOps For ASP.NET Developers

DevOps is the union of people, process, and products to enable continuous delivery of value to our end users. Azure DevOps is everything you need to turn an idea into a working piece of software.


Abel and Jeremy introduce us the benefits of DevOps. They give us a high level overview of how to implement some DevOps best practices using Azure DevOps.

Abel and Jeremy explain the difference between these two options and show how we can get started with Azure Repos. They will walk us through creating branches, adding policies, and also integrating with GitHub.

Thanks for reading ❤

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Learn More

The Complete ASP.NET MVC 5 Course

Build a Real-world App with ASP.NET Core and Angular 2 (4+)

Build an app with ASPNET Core and Angular from scratch

Introduction to ASP.NET Core 2.2

Build a REST API with ASP.NET Core 2.2

Build amazing web apps with ASP.NET Core 3.0

Angular and .NET Core

Building Web App using ASP.NET Web API Angular 7 and SQL Server

Create Login and Registration in Your ASP.NET Core MVC App

Create Login and Registration in Your ASP.NET Core MVC App

This tutorial walks you through setting up login and registration with ASP.NET Core MVC. In this tutorial, you learned how to add authentication to your ASP.NET Core MVC app and allow users to register for a new account.

This tutorial walks you through setting up login and registration with ASP.NET Core MVC. In this tutorial, you learned how to add authentication to your ASP.NET Core MVC app and allow users to register for a new account.

User authentication and authorization are common features in web applications, but building these mechanics has the potential to take a lot of time. Doing so requires setting up persistent storage for user information (in some type of database) and paying keen attention to potential security issues around sensitive operations like hashing passwords, password reset workflows, etc. - weeks of development time begin to add up before we ever get to the functionality that delivers value to your users.

In this post, we’ll walk through how Okta simplifies this process for us and set up a simple integration for an ASP.NET Core MVC app using the Okta NuGet package. We’ll build functionality for users to register for new accounts and login with their Okta credentials.

Scaffold Your ASP.NET Project

To follow along with this tutorial start by creating a new app in the console:

mkdir MyOktaProject
cd MyOktaProject
dotnet new mvc


Configure User Registration

If you don’t already have one, you’ll need to create an Okta developer account. Doing so will give you a URL for your organization called an “Okta domain”. It will also allow you to create your login credentials for accessing the Okta dashboard.

Upon submission of this form, you will receive an email Okta with instructions to obtain your credentials and complete your registration.

Execute the following steps to configure Okta so that users can register themselves for an account.

  1. From the Administrative Dashboard, hover over Users and click Registration
  2. Click Enable Registration
  3. Save the changes

Configure Basic User Authentication

Once you have access to your account you can proceed to the Dashboard using a link like the one below:

<span

class="okta-preview-domain">https://{yourOktaDomain}/admin/dashboard

On the Dashboard, click Applications in the main menu and on the Application screen, click Add Application.

Select Web then click Next.

On the Create New Application screen, set the following values:

Click Done, then click Edit next to General Settings on your newly created Okta app. Edit the following values:

Logout redirect URIs: https://localhost:5001/signout-callback-oidc

Initiate login URI: https://localhost:5001/authorization-code/callback

Add .NET Authentication Dependencies

Once your account is set up you need to add the Okta.Sdk library to your project. This post will take the approach of using the NuGet package, but the Github repository for Okta.AspNetCore can be found here.

To proceed simply search for the latest version of the Okta.Sdk NuGet package in your IDE of choice (version 1.2.0 at the time of this publication) and install it. If you’re using Visual Studio you can do this by right-clicking on the project in the solution explorer and selecting Manage NuGet Packages. For those of you not using Visual Studio, add the package via console window using the following command:

dotnet add package Okta.Sdk --version 1.2.0


Configure Your ASP.NET App for Login

Authentication works by redirecting users to the Okta website, where they will log in with their credentials, and then be returned to your site via the URL you configured above.

Add the following code to your appsettings.json file:

  "Okta": {
    "Issuer": "https://{yourOktaDomain}/oauth2/default",
    "ClientId": "{yourClientId}",
    "ClientSecret": "{yourClientSecret}"
  }


You can find each of the actual values needed to replace the settings in the config above in the following places:

ClientId refers to the client ID of the Okta application ClientSecret refers to the client secret of the Okta application Issuer will need the text {yourOktaDomain} replaced with your Okta domain, found at the top-right of the Dashboard page

Add some using statements to your Startup.cs file:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.IdentityModel.Tokens;


Add the following code to the top of the ConfigureServices method in your Startup.cs file:

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
    .AddCookie()
    .AddOpenIdConnect(options =>
    {
        options.ClientId = Configuration["okta:ClientId"];
        options.ClientSecret = Configuration["okta:ClientSecret"];
        options.Authority = Configuration["okta:Issuer"];
        options.CallbackPath = "/authorization-code/callback";
        options.ResponseType = "code";
        options.SaveTokens = true;
        options.UseTokenLifetime = false;
        options.GetClaimsFromUserInfoEndpoint = true;
        options.Scope.Add("openid");
        options.Scope.Add("profile");
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name"
        };
    });


In the Configure() method of your Startup.cs file add this line just before the app.UseMvc() method:

app.UseAuthentication();


Add the following MeViewModel to the Models directory:

using System.Collections.Generic;

namespace OktaAspNetCoreMvc.Models
{
    public class MeViewModel
    {
        public string Username { get; set; }

        public bool SdkAvailable { get; set; }

        public dynamic UserInfo { get; set; }

        public IEnumerable<string> Groups { get; set; }
    }
}


Add Login to Your ASP.NET App

Now that all the configuration and plumbing is done, you’re ready to add the code that will actually log users into your application.

Add the following AccountController to the Controller directory.

The controller exposes the Login() action. If the user has already been authenticated, the Login() action will redirect them to the home page. Otherwise, it will redirect them to the Okta login screen.

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Mvc;
using Okta.Sdk;

namespace OktaAspNetCoreMvc.Controllers
{
    public class AccountController : Controller
    {
        private readonly IOktaClient _oktaClient;

        public AccountController(IOktaClient oktaClient = null)
        {
            _oktaClient = oktaClient;
        }

        public IActionResult Login()
        {
            if (!HttpContext.User.Identity.IsAuthenticated)
            {
                return Challenge(OpenIdConnectDefaults.AuthenticationScheme);
            }

            return RedirectToAction("Index", "Home");
        }
    }
}


Add the following code to your _Layout.cshtml file, just below the main menu to add the login button, or a welcome message, based on the current user’s status.:

   @if (User.Identity.IsAuthenticated)
    {
        <ul class="nav navbar-nav navbar-right">
            <li><p class="navbar-text">Hello, @User.Identity.Name</p></li>
        </ul>
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li><a asp-controller="Account" asp-action="Login">Log in</a></li>
        </ul>
    }


For information on user authorization using Okta groups check out Lee Brandt’s article on user authorization in ASP.NET Core with Okta.

Register Users

If you following the instructions above to enable self-service registration the “Don’t have an account? Sign Up” message will appear at the bottom of the login form. In the next step, you’ll run the application.

Log In Using ASP.NET

That’s it! To run your solution open up a terminal and enter the following command:

dotnet run


Then navigate to http://localhost:5001 in your browser and enjoy!

The source code for this tutorial is available on GitHub.

Now you have a website with a working login and user registration form. Your website also allows users to recover lost passwords. By repeating these steps you can create a network of tools that your users can access all with the same login.

Learn More

The Complete ASP.NET MVC 5 Course

Build a Real-world App with ASP.NET Core and Angular 2 (4+)

ASP NET Core (ASP.NET 5),MVC 6,C#,Angular2 & EF Crash Course

Rest Api’s in Asp.Net and C#

Hands on ASP .Net Core 2