Getting 404 error instead of 401, when token is ex

2019-07-27 03:32发布

问题:

i am working with aspnet core WEB Api application.

While Login i am validating user through SignInManager like this.

 await _signInManager.PasswordSignInAsync

Äfter that i am generating jwt token for that user.

i have added [Authorize] tag in controller method.

when i am sending request with out token or invalid token, i am getting 404 error instead of 401 error.

This is startup.cs file

var tp_options = new TokenProviderOptions
            {
                Audience = xyz,
                Issuer = xyz,
                SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),
            };
            app.UseJwtBearerAuthentication(new JwtBearerOptions
            {
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                TokenValidationParameters = tokenValidationParameters,
                AuthenticationScheme = JwtBearerDefaults.AuthenticationScheme,
            });
            app.UseStaticFiles();
            app.UseFileServer();
            app.UseIdentity(); 

i have added a app.UseIdentity();. This is required for signInManger to validate login.

if i remove app.UseIdentity() i am getting 401 error ,but signInManager is getting exception "No authentication handler is configured to handle the scheme: Identity.Application"

how can i achieve both functionality here. i want to use both JWT Token validation and ASP IDENTITY.

回答1:

I had the same problem and was able to work around it by not using SignInManager for user authentication. It seems that SignInManager uses cookie authentication internally and unauthorized requests are redirected to Login page which I have not implemented, hence 404 response.

If you exclude app.UseIdentity() and also exclude cookie middleware unauthorized request should return 401 response. Here is the user authentication code:

public async Task<ClaimsIdentity> GetIdentity(string username, string password)
{
    // Can't use SignInManager because it uses a cookie so requests for unauthorized actions will not return 401, 
    // it will return 404 (redirect to Login page that is missing)
    // instead we validate the user using PasswordHasher
    var user =  await _userManager.FindByNameAsync(username);
    if (user != null)
    {
        var passwordHasher = new Microsoft.AspNetCore.Identity.PasswordHasher<ApplicationUser>();

        var passverificationResult = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password);
        if (passverificationResult == PasswordVerificationResult.Success)
        {
             var claims = await _userManager.GetClaimsAsync(user);
             return new ClaimsIdentity(new GenericIdentity(username, "Token"), claims);
         }
     }
     return null;
 }