locked
Problem validating user login RRS feed

  • Question

  • User662762443 posted

    Guys, I have a doubt when validating my login. In my application we can use the username and the number of the cnpj accompanied by the password, however when I enter the login cnpj, it does not find in the database, and it exists, because currently the login is made only by the username, as I do for also validate by the cnpj number?

    This my code:

    switch (request.Request.GrantTypes)
                {
                    case "password":
    
                        // Checks the existence of the user in the ASP.NET Core Identity tables
                        var userIdentity = await _userManager.FindByNameAsync(request.Request.UserName); // Here is the problem.
    
    
    
                        if (userIdentity == null || userIdentity.Deletado)
                            {
                                loginResponse.Message = "Login ou senha inválidos.";
                                result.WithError("Login or password invalid.");
                                result.Value = loginResponse;
                                return result;
                            }
    }

    Wednesday, May 26, 2021 12:27 PM

Answers

  • User475983607 posted

    There is an error when implementing linq: It is not possible to implicitly convert type "Core.Entities.Security.ApplicationUser" to string.

    The code tries to assign an ApplicationUser type to a string.   Change string to ApplicationUser as shown in my previous post.

    ApplicationUser user = _userManager.Users.FirstOrDefault(u => u.CNPJ == request.Request.UserName);

    Or if you want the only the username, then the syntax is...

    string username = _userManager.Users.FirstOrDefault(u => u.CNPJ == request.Request.UserName)?.UserName;

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, May 28, 2021 3:20 PM

All replies

  • User475983607 posted

    Keep in mind, the community has no idea how your application works.  

    What kind of application is this?  What is cnpj?  Is there an error message?  How is it possible to know the Username before logging in?  What is request.Request.UserName and how is it populated?

    Wednesday, May 26, 2021 12:47 PM
  • User662762443 posted

    It is a login screen, cnpj is an identifier number of a company, for example 49125207000181. And I have my user who is rtavix, however in the implementation the request.Request.UserName does not recognize that the cnpj is a type of user tbm, the the idea is to log in both by username and by this cnpj (however it is returning null).

    Wednesday, May 26, 2021 1:39 PM
  • User475983607 posted

    It is a login screen, cnpj is an identifier number of a company, for example 49125207000181. And I have my user who is rtavix, however in the implementation the request.Request.UserName does not recognize that the cnpj is a type of user tbm, the the idea is to log in both by username and by this cnpj (however it is returning null).

    While you understand what you're trying to do, the community has no idea and we cannot read your mind or see the code.  Plus, there's no mention of cnpj or tbm in the code sample you provided.  

    Perhaps there is a senior developer on your team you can ask?  

    Wednesday, May 26, 2021 1:50 PM
  • User662762443 posted

    mgebhard, I'm just having trouble using await _userManager.FindByNameAsync (request.Request.UserName); It's not about reading my mind, my only question is how can I use the username and CNPJ number (which can be any number) to be my login user. If I put the login user c1526 it works, it returns with the data in this beautiful one, however when I try to login with the cnpj that is also related to the user c1526, it brings null. I believe the problem is in FindByNameAsync that he only brings by the userName field.

    Wednesday, May 26, 2021 2:40 PM
  • User475983607 posted

    rtaVix

    mgebhard, I'm just having trouble using await _userManager.FindByNameAsync (request.Request.UserName); It's not about reading my mind, my only question is how can I use the username and CNPJ number (which can be any number) to be my login user. If I put the login user c1526 it works, it returns with the data in this beautiful one, however when I try to login with the cnpj that is also related to the user c1526, it brings null. 

    You're asking questions as if the community knows how your application works.  You have no even told us what type of application this is. 

    Can you explain the following code?

    request.Request.UserName

    The code must be a custom feature.  What is the value of request.Request.UserName?  How is the UserName property set? 

    The standard method to get a username in an ASP.NET application is...

    HttpContext.Current.User.Identity.Name

    What is cnpj?  And how is it related to the user?  

    rtaVix

    I believe the problem is in FindByNameAsync that he only brings by the userName field.

    Yes.  FindByNameAsync() looks up the username and returns a user object as explained in the UserManager reference documentation.  What are you expecting to return?

    Wednesday, May 26, 2021 3:26 PM
  • User662762443 posted

    Come on. This app is a login screen only. In the database I have a table of users, who have the fields of userName and CNPJ (Registration number of a company). Request.Request.UserName, on the other hand, returns the value entered (when I type the user in the user field).

    The cnpj he is part of the field of the user table. The idea is that I use the same to login. I could log in both by username and also by this CNPJ.

    However, FindByNameAsync will only recognize the userNAme that was entered c1526. this user c1526 he has the CNPJ, which he would like to use also to login.

    Well, I tried to be as explanatory as possible. I hope someone can understand.

    private UserManager<ApplicationUser> _userManager;
    
    public CreateLoginCommandHandler(IUsuarioRepository usuarioRepository, UserManager<ApplicationUser> userManager)
    {
    _userManager = userManager;
    
    }
    public async Task<Result<LoginResponse>> Handle(CreateLoginCommand request, CancellationToken cancellationToken)
            {
                var result = new Result<LoginResponse>();
    
                // Initializes with failure.
                var loginResponse = new LoginResponse();
    
                if (string.IsNullOrEmpty(request.Request.CaptchaId))
                    _tokenTimeApp = true;
                
                switch (request.Request.GrantTypes)
                {
                    case "password":
                        
                        // Checks the existence of the user in the ASP.NET Core Identity tables
                        var userIdentity = await _userManager.FindByNameAsync(request.Request.UserName);
                        //var test = new ApplicationUser() { Id = request.Request.UserName};
                        
    
    
                        if (userIdentity == null || userIdentity.Deletado)
                            {
                                loginResponse.Message = "Login or password invalid.";
                                result.WithError("Login or password invalid.");
                                result.Value = loginResponse;
                                return result;
                            }
                     }
             }

    Wednesday, May 26, 2021 6:12 PM
  • User475983607 posted

    However, FindByNameAsync will only recognize the userNAme that was entered c1526. this user c1526 he has the CNPJ, which he would like to use also to login.

    Correct.

    UserManager<TUser>.FindByNameAsync() finds the user by username as openly and clearly stated in the reference documentation.  I had no idea you thought FindByNameAsync() looks in another column.   

    Write a LINQ query that looks up the CNDJ value if FindByNameAsync() returns null.

    Wednesday, May 26, 2021 6:38 PM
  • User662762443 posted
    Would you have an example of how I could do it? It would help me already.
    Thursday, May 27, 2021 12:38 PM
  • User475983607 posted

    Would you have an example of how I could do it? It would help me already.

    You keep asking questions as if the community understands what you are thinking and how the code base is designed.  I have no idea how to answer this question other than explain how to write an if...else statement which you already have.  If the userIdentity is null then write a LINQ query to get the username.  

    var userIdentity = await _userManager.FindByNameAsync(request.Request.UserName); 
    
    if (userIdentity == null || userIdentity.Deletado)
    {
        string username = //Your LINQ query to get the username form the cnpj 
        if(username == null) { 
            loginResponse.Message = "Login ou senha inválidos.";
            result.WithError("Login or password invalid.");
            result.Value = loginResponse;
            return result;
        }
        else {
            userIdentity = await _userManager.FindByNameAsync(username); 
        }
    }

    Thursday, May 27, 2021 12:54 PM
  • User662762443 posted

    When trying to create linq, it returns null, what do you suggest?

    List<ApplicationUser> Users = new List<ApplicationUser>();

    var user = from tb1 in Users where tb1.CNPJ == request.Request.UserName select tb1.CNPJ;

    Friday, May 28, 2021 1:27 PM
  • User475983607 posted

    When trying to create linq, it returns null, what do you suggest?

    List<ApplicationUser> Users = new List<ApplicationUser>();

    var user = from tb1 in Users where tb1.CNPJ == request.Request.UserName select tb1.CNPJ;

    Your code example queries a new (empty) ApplicationUser object.  You need to query the DbContext.  

    ApplicationUser user = _context.Users.FirstOrDefault(u => u.CNPJ == "TheCNOJValue");

    Friday, May 28, 2021 1:47 PM
  • User662762443 posted

    There is an error when implementing linq: It is not possible to implicitly convert type "Core.Entities.Security.ApplicationUser" to string.

    request.Request.UserName // receives the value of the object that was entered by the user.

    my code:

    public class CreateLoginCommandHandler : IRequestHandler<CreateLoginCommand, Result<LoginResponse>>
        {
            private readonly IUserRepository _userRepository;
            private readonly IPermissionRepository _permissionRepository;
            private readonly ICaptchaRepository _captchaRepository;
            private UserManager<ApplicationUser> _userManager;
            private AccessManager _accessManager;
            private AppSettings _appSettings;
            private EnvironmentVariables _environmentVariables;
            private bool _tokenTimeApp = false;
    
            public CreateLoginCommandHandler(IUserRepository userRepository,
                AccessManager accessManager,
                IPermissionRepository permissionRepository,
                ICaptchaRepository captchaRepository,
                UserManager<ApplicationUser> userManager,
                IOptions<AppSettings> appSettings,
                EnvironmentVariables environmentVariables)
            {
                _usuarioRepository = usuarioRepository;
                _accessManager = accessManager;
                _permissionRepository = permissionRepository;
                _appSettings = appSettings.Value;
                _environmentVariables = environmentVariables;
                _captchaRepository = captchaRepository;
                _userManager = userManager;
            }
     
             public async Task<Result<LoginResponse>> Handle(CreateLoginCommand request, CancellationToken cancellationToken)
            {
                var result = new Result<LoginResponse>();
    
                // Initializes with failure.
                var loginResponse = new LoginResponse();
    
                if (string.IsNullOrEmpty(request.Request.CaptchaId))
                    _tokenTimeApp = true;
    
                switch (request.Request.GrantTypes)
                {
                    case "password":
    
                        // Checks the existence of the user in the ASP.NET Core Identity tables
                        var userIdentity = await _userManager.FindByNameAsync(request.Request.UserName);
    
                        if (userIdentity == null || userIdentity.Deletado)
                        {
                            string username = _userManager.Users.FirstOrDefault(u => u.CNPJ == request.Request.UserName);
                            if (username == null)
                            {
                                loginResponse.Message = "Login or password invalid.";
                                result.WithError("Login or password invalid.");
                                result.Value = loginResponse;
                                return result;
                            }
                            else
                            {
                                userIdentity = await _userManager.FindByNameAsync(username);
                            }
                        }
                    }
            }
    }

    to complement the information, I also have my ApplicationDbContext class

    using System;
    using Microsoft.AspNetCore.Identity;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore;
    using Core.Entities.Security;
    
    namespace Infra.Data
    {
        public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
        {
            public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
                : base(options)
            {

     protected override void OnModelCreating(ModelBuilder builder)
            {
                base.OnModelCreating(builder);
                
                builder.HasDefaultSchema("Client");

                foreach(var entity in builder.Model.GetEntityTypes())
                {
                    // Replace table names
                    entity.Relational().TableName = entity.Relational().TableName.ToUpper();

                    // Replace column names            
                    foreach(var property in entity.GetProperties())
                    {
                        property.Relational().ColumnName = property.Relational().ColumnName.ToUpper();
                    }

                    foreach(var key in entity.GetKeys())
                    {
                        key.Relational().Name = key.Relational().Name.ToUpper();
                    }

                    foreach(var key in entity.GetForeignKeys())
                    {
                        key.Relational().Name = key.Relational().Name.ToUpper();
                    }

                    foreach(var index in entity.GetIndexes())
                    {
                        index.Relational().Name = index.Relational().Name.ToUpper();
                    }
                }
            }

            }
        }
    }

    Friday, May 28, 2021 2:47 PM
  • User475983607 posted

    There is an error when implementing linq: It is not possible to implicitly convert type "Core.Entities.Security.ApplicationUser" to string.

    The code tries to assign an ApplicationUser type to a string.   Change string to ApplicationUser as shown in my previous post.

    ApplicationUser user = _userManager.Users.FirstOrDefault(u => u.CNPJ == request.Request.UserName);

    Or if you want the only the username, then the syntax is...

    string username = _userManager.Users.FirstOrDefault(u => u.CNPJ == request.Request.UserName)?.UserName;

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, May 28, 2021 3:20 PM