api - 当 token 过期或 token 未通过 Asp.net core 2 时,获取 404 错误而不是 401

标签 api asp.net-core asp.net-core-2.0 bearer-token

我创建了 Asp.net-core 2 项目并添加了

  1. 由 Bearer token 授权的 api Controller 。
  2. 授权的mvc Controller CookieAuthenticationDefaults.AuthenticationScheme。
  3. 没有 app.UseIdentity();在配置功能中

当我尝试调用 iis express 中发布的 api 时。它会返回 401 unauthorized 。

当我尝试调用 iis 中发布的 api 时,它会返回 404 not found。

当 token 过期或未传递 token 时,我收到 404 错误而不是 401

和我的创业公司

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApiContext>();
        //options =>
        //    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddTransient<ApiContextSeed>();
        //a confirmed email.
        services.AddIdentity<ApplicationUser, IdentityRole>(config =>
        {
            config.SignIn.RequireConfirmedEmail = true;
            config.Password.RequireDigit = false;
            config.Password.RequireLowercase = false;
            config.Password.RequireNonAlphanumeric = false;
            config.Password.RequireUppercase = false;
            config.Password.RequiredUniqueChars =0;
            config.Password.RequiredLength = 6;
            config.User.AllowedUserNameCharacters = null;

        })
            .AddEntityFrameworkStores<ApiContext>()
            .AddDefaultTokenProviders();

        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();
        services.AddMvc().AddSessionStateTempDataProvider();
        services.AddResponseCaching();
        services.AddAutoMapper();
        services.AddSingleton<IEmailSender, EmailSender>();
        services.AddSingleton<IWizIQSender, WizIQSender>();
        services.AddSingleton<IWizIQClass, WizIQClass>();
        services.AddSingleton<ITimeZone, TimeZone>();
        services.AddSingleton<IPinCodeGenerator, PinCodeGenerator>();
        services.AddScoped<IUnitOfWorkAsync, UnitOfWorkAsync>();
        services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
        services.AddBootstrapPagerGenerator(options =>
        {
            // Use default pager options.
            options.ConfigureDefault();
        });         
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)

              .AddCookie("UserAuth", options =>
        {

            options.LoginPath = string.Empty;



        });      
        services.AddDistributedMemoryCache();         
        #region FlashMessage

        services.AddSession();
        // Needed so we can access the user's session.
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddScoped(x => x.GetRequiredService<IHttpContextAccessor>().HttpContext.Session);

        services.AddScoped<IMessageProvider, SessionMessageProvider>();

        // Customize the message types (i.e. we are using Bootstrap v3 and need to provide a custom-value for the error message-type).
        services.AddScoped<IMessageTypes>(x =>
        {
            return new MessageTypes(error: "danger");
        });

        services.AddScoped<IMessengerOptions, MessengerOptions>();

        // We are using a stack to hold messages (i.e. LIFO).
        services.AddScoped<IMessenger, StackMessenger>();

        #endregion
        services.AddCors(cfg =>
        {
            cfg.AddPolicy("UserPanel", bldr =>
            {
                bldr.AllowAnyHeader()
                    .AllowAnyMethod()
                .AllowAnyOrigin();
            });
        });
        //using JWT
        services.AddAuthentication()
              .AddJwtBearer(cfg =>
              {
                  cfg.RequireHttpsMetadata = false;
                  cfg.SaveToken = true;
                  cfg.TokenValidationParameters = new TokenValidationParameters()
                  {
                      ValidIssuer = Configuration["Tokens:Issuer"],
                      ValidAudience = Configuration["Tokens:Issuer"],  
                      IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
                  };

              });


        services.AddMvc();
        services.AddSingleton<IEmailSender, EmailSender>();
        //services.AddUrlHelper();
        services.AddTransient<IEmailSender, EmailSender>();

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "Drossey API", Version = "v1" });
        });


    } 

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApiContextSeed seeding)
   {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
            app.UseDatabaseErrorPage();
        }
        else
        {
             app.UseExceptionHandler("/error");
            app.UseStatusCodePagesWithReExecute("/error");

        }
        app.UseStaticFiles();       
        app.UseSession();
        app.UseAuthentication();
        app.UseCors("UserPanel");
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "Drossey Api");
        });
        app.UseMvc(routes =>
        {            
            routes.MapRoute(
            name: "areaRoute",
            template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");

            routes.MapRoute(
              name: "default",
              template: "{controller=Home}/{action=Index}/{id?}");
        });           
        seeding.EnsureSeeding().Wait();
    }

这是我的 api Controller

public class CodeController : BaseController
{
    private readonly IPinCodeGenerator _pinCodeGenerator;

    public CodeController(IUnitOfWorkAsync unitOfWork,
        UserManager<ApplicationUser> userMgr, IPasswordHasher<ApplicationUser> hasher, 
        ILogger<AuthController> logger, IConfiguration config, IMapper mapper, IPinCodeGenerator pinCodeGenerator) :
        base(unitOfWork, userMgr, hasher, logger, config, mapper)
    {
        _pinCodeGenerator = pinCodeGenerator;
    }

    [HttpPost]
    public async Task<IActionResult> Add([FromBody]CodeAddViewModel model)
    {

        try
        {
            if (ModelState.IsValid)
            {
                var userId = await GetUserId();
                var user = await _userMgr.FindByIdAsync(userId);

                var random = Convert.ToDouble(model.Code.Substring(0, 10));
                var code = model.Code.Substring(10, 5);
                var pinCode = _unitOfWork.PinCodeRepository.Filter(u => u.Code == random).FirstOrDefault();
                if (pinCode == null || pinCode.Status != CodeStatus.IsActive)
                {
                    return StatusCode(400, "InValidCode");
                }
                else
                {
                    string codeStr = _pinCodeGenerator.GetCode(pinCode.Amount, pinCode.Code,
                        pinCode.Vector, pinCode.Key);
                    if (codeStr != model.Code)
                    {
                        return StatusCode(400, "InValidCode");
                    }
                    else
                    {
                        user.Balance += pinCode.Amount;
                        await _userMgr.UpdateAsync(user);
                        pinCode.Status = CodeStatus.Shipped;
                        await _unitOfWork.CommitAsync();
                        return Ok();

                    }
                }

            }
            return StatusCode(400, ModelState);
        }
        catch (Exception e)
        {

            return StatusCode(500, e.Message);
        }



    }
}

和基本 Controller 包含

 public class BaseController : Controller
{
    public readonly ILogger<AuthController> _logger;
    public readonly SignInManager<ApplicationUser> _signInMgr;
    public readonly UserManager<ApplicationUser> _userMgr;
    public readonly IPasswordHasher<ApplicationUser> _hasher;
    public readonly IConfiguration _config;
    public IUnitOfWorkAsync _unitOfWork;
    protected readonly IMapper _mapper;

    public BaseController(IUnitOfWorkAsync unitOfWork,

        UserManager<ApplicationUser> userMgr,
        IPasswordHasher<ApplicationUser> hasher,
        ILogger<AuthController> logger,
        IConfiguration config,
        IMapper mapper
        )
    {
        _unitOfWork = unitOfWork;
        //_signInMgr = signInMgr;
        _logger = logger;
        _userMgr = userMgr;
        _hasher = hasher;
        _config = config;
        _mapper = mapper;


    }

    protected async Task<string> GetUserId()
    {
        try
        {
            var userName = this.User.FindFirst(ClaimTypes.NameIdentifier).Value;
            if (!string.IsNullOrEmpty(userName))
            {
                var user = await _userMgr.FindByNameAsync(userName);
                if (user != null)
                    return user.Id;
                else
                    return null;
            }
        }
        catch (Exception)
        {

            return null;
        }

        return null;
    }

}

最佳答案

startup.cs 中的 app.UseStatusCodePagesWithReExecute("/error") 隐藏 401 未授权错误。

关于api - 当 token 过期或 token 未通过 Asp.net core 2 时,获取 404 错误而不是 401,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49753174/

相关文章:

php - 在 Laravel 中将 API key 文件放在哪里

api - 使用 Webmethods 作为客户端将附件添加到 JIRA REST API

c# - Visual Studio 2017 控制台未显示但正在运行

entity-framework - 使用通用 dbContext 获取通用存储库(多个 dbContext)

PHP:Trivago、Hotelscombined 如何更快地获取数据

Android camera2 API 在自动对焦模式下获取焦距

asp.net-core - 如何排除文件在ASP.NET Core中发布?

asp.net - Angular + ASP.Net 核心 : Plugin Architecture

asp.net-identity - 如何在不访问 MVC 应用程序中的安全页面的情况下触发 IdentityServer4 登录?

c# - 如何使用 ef 为迁移构建强制执行 Restrict DeleteBehavior?