Skip to content
This repository has been archived by the owner on May 11, 2023. It is now read-only.

Commit

Permalink
Chapter updates
Browse files Browse the repository at this point in the history
  • Loading branch information
gildedgardenia committed Nov 15, 2022
1 parent 9bee9f7 commit 5011d9e
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 125 deletions.
47 changes: 23 additions & 24 deletions src/chapters/auth/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,39 @@ The first place to start with configuring Identity to fit the needs of the proje
``ConfigureServices()``
^^^^^^^^^^^^^^^^^^^^^^^

The first place that we may want to customize our settings is at the bottom of ``ConfigureServices()``.
When you were testing out your application, you may have accidentally entered an invalid password.
The validation conditions for a user's password is an example of one of the settings that can be configured here by using a method called ``services.Configure<IdentityOptions>()``.
If we wanted to make the minimum number of characters for our password 10 as opposed to 6, we would do the following.
Now that we are getting to configure our user, let's check out the code in ``ConfigureServices()``.
Earlier you may have added the following:

.. sourcecode:: csharp
:linenos:

services.Configure<IdentityOptions>( options =>
options.Password.RequiredLength = 10
);
services.AddDefaultIdentity<IdentityUser>
(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Password.RequireDigit = false;
options.Password.RequiredLength = 10;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = false;
}).AddEntityFrameworkStores<JobDbContext>();

For a full list of the default settings for users' passwords and how we can change those settings, check out the `documentation <https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.passwordoptions?view=aspnetcore-3.1>`__.

In ``ConfigureServices()``, we can also configure cookie settings, password hashers, user validation requirements, sign in settings and more.

``Configure()``
^^^^^^^^^^^^^^^
This code is dictating the settings for account creation. Right now, for a user to create an account, they have to have the following:

Below ``ConfigureServices()``, you will find ``Configure()``. Inside ``Configure()``, we must make sure we have the following:
#. They have to click a link to confirm their account.
#. Their password has to be more than 10 characters long.
#. Their password has to include an uppercase letter(s).

.. sourcecode:: csharp
:linenos:
The following is not true for a user to create an account.

app.UseRouting();
#. Their password does not have to include a number.
#. Their password does not have to include a special character such as a question mark.
#. Their password does not have to include lowercase letters.

app.UseAuthentication();
app.UseAuthorization();
These are just some basic requirements that can be changed to suit the needs of your application.
For a full list of the default settings for users' passwords and how we can change those settings, check out the `documentation <https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.passwordoptions?view=aspnetcore-3.1>`__.

While we did properly scaffold Identity onto our code base, we need to add the calls to ``UseAuthentication()`` and ``UseAuthorization()``.
Our application uses middleware to relay requests between our application and our database.
By adding the calls to ``UseAuthentication()`` and ``UseAuthorization()``, we are specifying that we now need authentication middleware to handle these requests.
Authentication is not just about ensuring users are signed in. It is about protecting data at every point it passes through to make the application work.
In ``ConfigureServices()``, we can also configure cookie settings, password hashers, user validation requirements, sign in settings and more.

Additional Customizations
-------------------------
Expand All @@ -66,7 +66,6 @@ Here are some examples of what you can do with it.
.. admonition:: Note

If you want to customize user data, it is best to do so when initially scaffolding the app.
Identity has a default user class called ``IdentityUser``.
`IdentityUser <https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.identity.entityframeworkcore.identityuser?view=aspnetcore-1.1>`__ has a number of properties that are important and relevant to storing user data.
However, when you read through the requirements you may notice that you need additional properties, such as the user's first and last name.
If you want to add custom properties, check out this `article <https://docs.microsoft.com/en-us/aspnet/core/security/authentication/add-user-data?view=aspnetcore-5.0&tabs=visual-studio>`__ from Microsoft.
12 changes: 0 additions & 12 deletions src/chapters/auth/identity-management.rst

This file was deleted.

1 change: 0 additions & 1 deletion src/chapters/auth/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ Authentication
users
configuration
authorization
identity-management
studio

153 changes: 66 additions & 87 deletions src/chapters/auth/scaffolding.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,45 +38,43 @@ When you run this command, the output may look something like the following:
.. sourcecode:: guess
:linenos:

.NET Core SDK (reflecting any global.json):
Version: 3.1.101
Commit: b377529961
.NET SDK (reflecting any global.json):
Version: 6.0.403
Commit: 2bc18bf292

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.15
OS Platform: Darwin
RID: osx.10.15-x64
Base Path: /usr/local/share/dotnet/sdk/3.1.101/
OS Name: Mac OS X
OS Version: 12.4
OS Platform: Darwin
RID: osx.12-x64
Base Path: /usr/local/share/dotnet/sdk/6.0.403/

Host (useful for support):
Version: 5.0.5
Commit: 2f740adc14
global.json file:
Not found

.NET SDKs installed:
3.1.101 [/usr/local/share/dotnet/sdk]
5.0.202 [/usr/local/share/dotnet/sdk]
Host:
Version: 6.0.11
Architecture: x64
Commit: 943474ca16

.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 5.0.5 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 2.1.15 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.23 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 5.0.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
If the .NET Core SDK listed on line 2 does not match the SDK specified in your ``csproj`` file, you may need to open up your ``global.json`` and edit it so that the SDK used by the project matches.

To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download
.. admonition:: Note

If you are do not have a ``global.json`` file, but the .NET Core SDK is still not matching your ``csproj`` file, you can create a new ``global.json`` file with the following command:

::

If the .NET Core SDK listed on line 2 does not match the SDK specified in your ``csproj`` file, you need to open up your ``global.json`` and edit it so that the SDK used by the project matches.
dotnet new globaljson --sdk-version 6.0.403

You need to install five NuGet packages before getting started with this process:
You need to install six NuGet packages before getting started with this process:

#. ``Microsoft.AspNetCore.Identity``
#. ``Microsoft.EntityFrameworkCore.Design``
#. ``Microsoft.AspNetCore.Identity.UI``
#. ``Microsoft.AspNetCore.Identity.EntityFrameworkCore``
#. ``Microsoft.EntityFrameworkCore.SqlServer``
#. ``Microsoft.VisualStudio.Web.CodeGeneration.Design``
#. ``Microsoft.EntityFrameworkCore.Tools``

When installing these packages, make sure that the versions are the same as the .NET Core version your project is using. You can confirm this is the case by reviewing the code in your ``csproj`` file.

Expand Down Expand Up @@ -106,9 +104,9 @@ All of these commmands should be run in the project directory *inside* of the so

.. sourcecode:: guess

dotnet tool install -g dotnet-aspnet-codegenerator
dotnet tool install --global dotnet-aspnet-codegenerator --version <YOUR .NET VERSION>

If the tool is installed, you are ready to proceed.
If the tool is installed, check the version before proceeding to make sure it works with your .NET version.
#. Use the following command to add the full package necessary to generate the actual Identity code.

.. sourcecode:: guess
Expand Down Expand Up @@ -176,42 +174,58 @@ All of these commmands should be run in the project directory *inside* of the so
^^^^^^^^^^^^^

If you tried to run the application right now, you would encounter some build errors.
While we specified in our scaffolding commands that we wanted to use ``EventDbContext``, we need to open up two files to make sure that Identity is properly using ``EventDbContext``: ``Startup.cs`` and ``IdentityHostingStartup.cs``.
While we specified in our scaffolding commands that we wanted to use ``EventDbContext``, we need to open up ``EventDbContext`` and make some changes.

``IdentityHostingStartup.cs`` can be found in the ``Areas/Identity`` directory.
You should update this file to make sure that it uses MySQL and the ``"DefaultConnection"`` string:
In order to use Identity, we need to change what ``EventDbContext`` extends. Currently, it extends ``DbContext``. Let's change that to ``IdentityDbContext`` like so:

.. sourcecode:: csharp
:lineno-start: 14

public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<EventDbContext>(options =>
options.UseMySql(
context.Configuration.GetConnectionString("DefaultConnection")));
public class JobDbContext: IdentityDbContext<IdentityUser, IdentityRole, string>

services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<EventDbContext>();
});
}
}
You may note that we didn't add any ``DbSet`` for ``IdentityUser`` like we did for other models in the application.
This is not an oversight! With ``EventDbContext`` properly set up, we can run a migration and the database will add the appropriate tables for our authentication data.

Now go to ``Startup.cs`` and comment out the following lines in ``ConfigureServices()``:
Add a line to ``ConfigureServices()`` in ``Startup.cs`` for the use of the Razor pages in Identity:

.. sourcecode:: csharp
:lineno-start: 29

services.AddDbContext<EventDbContext>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllersWithViews();
services.AddRazorPages();

.. admonition:: Note

While you are editing ``ConfigureServices()``, you may need to also add a default identity user.
We will learn more about how to configure this user in a later section.
For now, you can add code to ``ConfigureServices()`` to address this:

.. sourcecode:: csharp
:linenos:

services.AddControllersWithViews();
services.AddRazorPages();

var serverVersion = new MySqlServerVersion(new Version(8, 0, 29));
var defaultConnection = Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<JobDbContext>(options =>
options.UseMySql(defaultConnection, serverVersion));

services.AddDefaultIdentity<IdentityUser>
(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Password.RequireDigit = false;
options.Password.RequiredLength = 10;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = false;
}).AddEntityFrameworkStores<JobDbContext>();

Add one line to ``ConfigureServices()`` in ``Startup.cs`` for the use of the Razor pages in Identity:
Review ``Configure()`` in ``Startup.cs``. Above ``app.UseAuthorization()``, add one line of code like so:

.. sourcecode:: csharp

services.AddRazorPages();
app.UseAuthentication();
app.UseAuthorization();

Add an additional line to ``app.UseEndpoints()`` inside of ``Configure()`` in ``Startup.cs``:

Expand All @@ -224,49 +238,14 @@ Add an additional line to ``app.UseEndpoints()`` inside of ``Configure()`` in ``
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllers();
endpoints.MapRazorPages();
});

``endpoints.MapRazorPages()`` specifies to the app that the Identity pages should follow the routing laid out in ``_LoginPartial.cshtml``.

These initial steps were to make sure that the application is still using ``EventDbContext`` for its connection to the database now that we have added Identity.
However, if you take a look inside the ``Areas/Identity/Data`` directory, you will find a file also called ``EventDbContext``. Delete that generated file and continue to use the one we initially created for ``CodingEvents``.
Now we just need to dive into our copy of ``EventDbContext`` and do the following:

#. ``EventDbContext`` should now extend ``IdentityDbContext<IdentityUser>``.
#. We need to add an additional line to ``OnModelCreating()``:

.. sourcecode:: csharp

base.OnModelCreating(modelBuilder);

With these changes made, ``EventDbContext`` will look like the following:

.. sourcecode:: csharp
:lineno-start: 13

public class EventDbContext : IdentityDbContext<IdentityUser>
{
public DbSet<Event> Events { get; set; }
public DbSet<EventCategory> Categories { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<EventTag> EventTags { get; set; }

public EventDbContext(DbContextOptions<EventDbContext> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<EventTag>().HasKey(et => new { et.EventId, et.TagId });

base.OnModelCreating(modelBuilder);
}
}

You may note that we didn't add any ``DbSet`` for ``IdentityUser`` like we did for other models in the application.
This is not an oversight! With ``EventDbContext`` properly set up, we can run a migration and the database will add the appropriate tables for our authentication data.

Views
^^^^^
Expand Down
2 changes: 1 addition & 1 deletion src/chapters/auth/studio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Scaffolding

#. Use the same files as the chapter content and ``JobDbContext``.

#. Update ``IdentityHostingStartup.cs``, ``Startup.cs``, and ``JobDbContext`` as necessary.
#. Update ``Startup.cs`` and ``JobDbContext`` as necessary.
#. Add the ``LoginPartial`` partial view to the navbar.
#. Run a new migration and test the application.

Expand Down

0 comments on commit 5011d9e

Please sign in to comment.