相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Unconfirmed Email Login: PasswordSignInAsync Returning 'NotAllowed' Result Despite 'options.SignIn.RequireConfirmedEmail = false;'

Ask Question

I've created a Razor Pages Web App targeting .NET 5.0. No authentication was selected on creation, and ASP.NET Identity was added to the project as a scaffolded item immediately after creation, with all Identity files being overridden.

While experimenting with the ASP.NET Identity options, I set 'options.SignIn.RequireConfirmedEmail = false;' in the ConfigureServices method of the Startup.cs class file as shown here .

Despite options.SignIn.RequireConfirmedEmail being set to false, I was still unable to login using an unconfirmed email, with the catch-all error message of "Invalid login attempt." appearing above the form.

Setting a breakpoint, I found that, during login, the result variable receives a "NotAllowed" value from the _signInManager.PasswordSignInAsync() method.

Image of Breakpoint in OnPostAsync Method in Login.cshtml.cs

Image of Local Variables Immediately After Calling _signInManager.PasswordSignInAsync()

Upon setting the email to be confirmed, the login succeeds. Therefore, the only difference between login success and failure is whether or not the email is confirmed, even though options.SignIn.RequireConfirmedEmail has been set to false in the ConfigureServices method of the Startup.cs class file.

The question then is, have I missed something that is required to allow for an unconfirmed email to successfully login? If not, then is this a bug? Also, how could one allow for an unconfirmed email to successfully login, assuming that options.SignIn.RequireConfirmedEmail blocks unconfirmed email login attempts regardless of whether it has been set to true or false?

Thank you very much.

While posting my question to stack overflow, one of the similar questions suggested by stack overflow helped me figure out the answer to my question. The following is my response to my own question for the sake of those who will struggle with the same misunderstanding as I did.

Stack Overflow Question:

Why is the login attempt returning {NotAllowed} in the PasswordSignInAsync method (ASP.NET)

Stack Overflow Answer:

“File that is most likely your issue: ‘TaskManager/TaskManager/Areas/Identity/IdentityHostingStartup.cs’

Location is in requiring the account to be confirmed in this line:

‘services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)’

My guess is that your account is not confirmed so you need to confirm it or remove this constraint.”

It appears that when one creates a Razor Pages Web App without authentication, and then add the ASP.NET Identity files as a scaffolded item (‘override all files’ checked), the Identity folder in the Areas folder contains an IdentityHostingStartup.cs file in addition to the Data folder and Pages folder. Additionally, the application also contains the typical Startup.cs class file in the root folder.

On the other hand, when one creates a Razor Pages Web App with individual accounts authentication using ASP.NET Identity, the Identity folder in the Areas folder only contains a Pages folder, and all configuration settings are located in the typical Startup.cs class file in the root folder.

The line of code that is actually preventing the successful login of an account with an unconfirmed email is the following:

services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)

For an application with scaffolded Identity, the above line of code is located in the IdentityHostingStartup.cs file, while for an application created with Identity authentication, the above line of code is located in the Startup.cs file.

Therefore, the solution for an application with scaffolded Identity is to edit the IdentityHostingStartup.cs file and either 1) set ‘SignIn.RequireConfirmedAccount’ to ‘false’, or 2) completely remove the configuration setting from the ‘services.AddDefaultIdentity<IdentityUser>()’ method and instead place all the configuration settings in the ‘services.Configure<IdentityOptions>()’ method.

The latter approach would probably be the most clear and readable approach, and will allow for the developer to use the 'options.SignIn.RequireConfirmedEmail = false;' setting as originally intended.

Image of the First Approach: Setting SignIn.RequireConfirmedAccount to False

Image of the Second Approach: Removing SignIn.RequireConfirmedAccount from services.AddDefaultIdentity<IdentityUser>() and Setting SignIn.RequireConfirmedEmail to False in services.Configure<IdentityOptions>()

The main point of misunderstanding here and the key takeaway is that the developer of an application with scaffolded Identity should configure the settings of ASP.NET Identity in the IdentityHostingStartup.cs file, and not the Startup.cs file.

The use of IdentityHostingStartup.cs for configuring Identity is in fact explicitly mentioned in the documentation regarding scaffolding Identity into a Razor project without existing authorization.

Scaffold Identity in ASP.NET Core projects: Scaffold Identity into a Razor project without existing authorization https://learn.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-5.0&tabs=visual-studio#scaffold-identity-into-a-razor-project-without-existing-authorization

Please feel free to add any other comments that will help others better understand this topic.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

 
推荐文章