Harvey Harvey - 9 days ago 6
ASP.NET (C#) Question

ASP.NET Web API 2 Forcing the requirement to confirm email

This might sound like quite a basic question but the documentation for ASP.NET in general is terrible and I cannot find how to enforce the email confirmation.

I have been able to set up generating and sending confirmation emails no problem and they work well.

Its just I only want users to access the 'Auth' endpoints that are confirmed. How can I enforce this.

The closes information I could find seems to only apply for ASP.NET MVC which requires adding

config.SignIn.RequireEmailConfirmation
to Startup.cs however The Startup.cs in the Web API is completely different.

As a last resort I could add:

if (User.EmailConfirmed)
to every endpoint, however I feel this is a bit dramatic.

I also tried to add this 'rule' as a custom Authentication Attribute however I'm not sure how to access the current user and therefore cant check if the email is confirmed.

How can I ensure the email confirmation is enforced?

Answer

Options:

  1. When you are sending invitation link to user with password to register make sure you are creating the user without password, plus send the user a link with a code from AppUserManager.GeneratePasswordResetTokenAsync(user.id) where users can set a password, and you can set EmailConfirmed to true at this action.

  2. Forced check user to have email confirmed when token is generated:

in Startup at ConfigureAuth

 OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider("self"),
                //...
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = false
            };

Go and check your provider (ApplicationOAuthProvider):

 public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);


            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
            //Insecure message returned, you show to outside world the email exist, 
            //any how here is where you  stop the token generation if email of the useris not confirmed, 
            //going forward if you have speciffic role where this validation is not required 
            //check if user is in that role before checking if user has email confirmed 
            if (!user.EmailConfirmed)
            {
                context.SetError("invalid_grant", "Email is not confirmed");
                return;
            }
            //... rest of code
}
Comments