It’s important that UseAuthentication appear before UseMvc in the Configure method. When configuring Identity in ConfigureServices, you’ll notice a call to AddDefaultTokenProviders. This has nothing to do with tokens that may be used to secure web communications, but instead refers to providers that create prompts that can be sent to users via SMS or email for them to confirm their identity.
You can learn more about configuring two-factor authentication and enabling external login providers from the official ASP.NET Core docs.
The simplest form of authorization involves restricting access to anonymous users. When using Razor Pages, controlling access to individual pages or folders is done when configuring MVC in Startup:
When using controllers, and views, apply the [Authorize] attribute to certain controllers or actions. If roles are being used, the attribute can be further extended to restrict access to users who belong to certain roles, as shown:
In this case, users belonging to either the HRManager or Finance roles (or both) would have access to the SalaryController. To require that a user belong to multiple roles (not just one of several), you can apply the attribute multiple times, specifying a required role each time.
Specifying certain sets of roles as strings in many different controllers and actions can lead to undesirable repetition. You can configure authorization policies, which encapsulate authorization rules, and then specify the policy instead of individual roles when applying the [Authorize] attribute:
Using policies in this way, you can separate the kinds of actions being restricted from the specific roles or rules that apply to it. Later, if you create a new role that needs to have access to certain resources, you can just update a policy, rather than updating every list of roles on every [Authorize] attribute.
Claims are name value pairs that represent properties of an authenticated user. For example, you might store users’ employee number as a claim. Claims can then be used as part of authorization policies. You could create a policy called “EmployeeOnly” that requires the existence of a claim called “EmployeeNumber”, as shown in this example:
This policy could then be used with the [Authorize] attribute to protect any controller and/or action, as described above.
Most web APIs should implement a token-based authentication system. Token authentication is stateless and designed to be scalable. In a token-based authentication system, the client must first authenticate with the authentication provider. If successful, the client is issued a token, which is simply a cryptographically meaningful string of characters. When the client then needs to issue a request to an API, it adds this token as a header on the request. The server then validates the token found in the request header before completing the request. Figure 7-5 demonstrates this process.

Figure 7-5. Token-based authentication for Web APIs.
You can create your own authentication service, integrate with Azure AD and OAuth, or implement a service using an open source tool like IdentityServer.
Be especially careful about “rolling your own” implementation of cryptography, user membership, or token generation system. There are many commercial and open source alternatives available which will almost certainly have better security than a custom implementation.
In addition to serving pages and responding to requests for data via web APIs, ASP.NET Core apps can communicate directly with connected clients. This outbound communication can use a variety of transport technologies, the most common being WebSockets. ASP.NET Core SignalR is a library that makes it simple to add real-time server-to-client communication functionality to your applications. SignalR supports a variety of transport technologies, including WebSockets, and abstracts away many of the implementation details from the developer.
ASP.NET Core SignalR has been available with ASP.NET Core since version 2.1.
Real-time client communication, whether using WebSockets directly or other techniques, are useful in a variety of application scenarios. Some examples include:
When building client communication into your applications, there are typically two components:
Clients are not limited to browsers – mobile apps, console apps, and other native apps can also communicate using SignalR/WebSockets. The following simple program echoes all content sent to a chat application to the console, as part of a WebSocketManager sample application:
Consider ways in which your applications communicate directly with client applications, and consider whether real-time communication would improve your app’s user experience.
Domain-Driven Design (DDD) is an agile approach to building software that emphasizes focusing on the business domain. It places a heavy emphasis on communication and interaction with business domain expert(s) who can relate to the developers how the real-world system works. For example, if you’re building a system that handles stock trades, your domain expert might be an experienced stock broker. DDD is designed to address large, complex business problems, and is often not appropriate for smaller, simpler applications, as the investment in understanding and modeling the domain is not worth it.
When building software following a DDD approach, your team (including non-technical stakeholders and contributors) should develop a ubiquitous language for the problem space. That is, the same terminology should be used for the real-world concept being modeled, the software equivalent, and any structures that might exist to persist the concept (for example, database tables). Thus, the concepts described in the ubiquitous language should form the basis for your domain model.
Your domain model is comprised of objects that interact with one another to represent the behavior of the system. These objects may fall into the following categories:
Note that a DDD domain model should encapsulate complex behavior within the model. Entities, in particular, should not merely be collections of properties. When the domain model lacks behavior and merely represents the state of the system, it is said to be an anemic model, which is undesirable in DDD.
In addition to these model types, DDD typically employs a variety of patterns:
DDD also recommends the use of the Clean Architecture discussed previously, allowing for loose coupling, encapsulation, and code that can easily be verified using unit tests.
DDD is well-suited to large applications with significant business (not just technical) complexity. The application should require the knowledge of domain experts. There should be significant behavior in the domain model itself, representing business rules and interactions beyond simply storing and retrieving the current state of various records from data stores.
DDD involves investments in modeling, architecture, and communication that may not be warranted for smaller applications or applications that are essentially just CRUD (create/read/update/delete). If you choose to approach your application following DDD, but find that your domain has an anemic model with no behavior, you may need to rethink your approach. Either your application may not need DDD, or you may need assistance refactoring your application to encapsulate business logic in the domain model, rather than in your database or user interface.
A hybrid approach would be to only use DDD for the transactional or more complex areas of the application, but not for simpler CRUD or read-only portions of the application. For instance, you needn’t have the constraints of an Aggregate if you’re querying data to display a report or to visualize data for a dashboard. It’s perfectly acceptable to have a separate, simpler read model for such requirements.
There are a few steps involved in the process of deploying your ASP.NET Core application, regardless of where it will be hosted. The first step is to publish the application, which can be done using the dotnet publish CLI command. This will compile the application and place all of the files needed to run the application into a designated folder. When you deploy from Visual Studio, this step is performed for you automatically. The publish folder contains .exe and .dll files for the application and its dependencies. A self-contained application will also include a version of the .NET runtime. ASP.NET Core applications will also include configuration files, static client assets, and MVC views.
ASP.NET Core applications are console applications that must be started when the server boots and restarted if the application (or server) crashes. A process manager can be used to automate this process. The most common process managers for ASP.NET Core are Nginx and Apache on Linux and IIS or Windows Service on Windows.
In addition to a process manager, ASP.NET Core applications hosted in the Kestrel web server can benefit from the use of a reverse proxy server (this was a requirement for ASP.NET Core 1.x). A reverse proxy server receives HTTP requests from the internet and forwards them to Kestrel after some preliminary handling. Reverse proxy servers provide a layer of security for the application, and are used for edge deployments (exposed to traffic from the Internet). As of ASP.NET Core 2.0, Kestrel now supports edge deployments directly. However, Kestrel also doesn’t support hosting multiple applications on the same port, so techniques like host headers cannot be used with it to enable hosting multiple applications on the same port and IP address (a scenario IIS supports).

Figure 7-6. ASP.NET Core hosted in Kestrel behind a reverse proxy server
Another scenario in which a reverse proxy can be helpful is to secure multiple applications using SSL/HTTPS. In this case, only the reverse proxy would need to have SSL configured. Communication between the reverse proxy server and Kestrel could take place over HTTP, as shown in Figure 7-7.

Figure 7-7. ASP.NET Core hosted behind an HTTPS-secured reverse proxy server
An increasingly popular approach is to host your ASP.NET Core application in a Docker container, which then can be hosted locally or deployed to Azure for cloud-based hosting. The Docker container could contain your application code, running on Kestrel, and would be deployed behind a reverse proxy server, as shown above.
If you’re hosting your application on Azure, you can use Microsoft Azure Application Gateway as a dedicated virtual appliance to provide several services. In addition to acting as a reverse proxy for individual applications, Application Gateway can also offer the following features:
Learn more about Azure deployment options in Chapter 10.