【问题标题】:how to solve 401 unauthorized error in postman when calling a .Net API调用.Net API时如何解决邮递员中的401未授权错误
【发布时间】:2022-01-07 15:39:29
【问题描述】:

我有一个 .net 核心 webapi 工作正常并用 swagger 进行了测试,该方法也设置为允许匿名访问,因此不需要身份验证。但是在使用 Postman 测试 POST 方法时,我总是收到 401 错误。感谢任何帮助!

【问题讨论】:

  • 您的 POST 方法 API 是如何设置为允许匿名访问的?能否提供您的具体配置和 API 代码?
  • 将示例 JWT 访问令牌的副本发布到问题中也会有所帮助。 ASP.NET Core 也确实提供了很好的 looing,可以让您很好地了解它失败的原因。
  • @Chaodeng 方法有 [allowanonymous] 保护,在启动文件中,在 launchSettings.json 中,"anonymousAuthentication": true,

标签: authentication postman asp.net-core-webapi


【解决方案1】:

由于我不清楚你的具体代码实现,所以在这里写了一个demo,是一个从用户登录生成token到访问权限API的例子。可以参考一下,或许对你有一点帮助:

首先,打开 appsettings.json 文件并更改名为 Jwt 的部分:

"Jwt": {
    "Issuer": "testUser",
    "Audience": "user",
    "Key": "this is my custom Secret key for authnetication"
  }

配置启动时启用JWT认证方案和swagger授权配置,整个代码如下:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using WebApplication129.Controllers.conf;

namespace WebApplication129
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.AddSingleton<IConfiguration>(Configuration);
            services.AddAuthentication(opt => {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
     .AddJwtBearer(options =>
     {
         options.TokenValidationParameters = new TokenValidationParameters
         {
             ValidateIssuer = true,
             ValidateAudience = true,
             ValidateLifetime = true,
             ValidateIssuerSigningKey = true,
             ValidIssuer = Configuration["Jwt:Issuer"],
             ValidAudience = Configuration["Jwt:Audience"],
             IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
         };
     });
            services.AddControllers(options =>
            {
                options.Conventions.Add(new GroupingByNamespaceConvention());
            });

            services.AddSwaggerGen(config =>
            {   
                config.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description =
        "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer",
                    BearerFormat="JWT"
                });

                config.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
            },
            Scheme = "oauth2",
            Name = "Bearer",
            In = ParameterLocation.Header,

        },
        new List<string>()
    }
});


                var titleBase = "Test API";
                var description = "This is a Web API for Test operations";
                var TermsOfService = new Uri("https://xxxxxx");
                var License = new OpenApiLicense()
                {
                    Name = "MIT"
                };
                var Contact = new OpenApiContact()
                {
                    Name = "Test",
                    Email = "Test@hotmail.com",
                    Url = new Uri("https://xxxxxx")
                };

                config.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = titleBase + " v1",
                    Description = description,
                    TermsOfService = TermsOfService,
                    License = License,
                    Contact = Contact
                });

                config.SwaggerDoc("v2", new OpenApiInfo
                {
                    Version = "v2",
                    Title = titleBase + " v2",
                    Description = description,
                    TermsOfService = TermsOfService,
                    License = License,
                    Contact = Contact
                });

                var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                config.IncludeXmlComments(xmlPath);
            });
        }

       
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseSwagger();
            app.UseSwaggerUI(config =>
            {
                config.SwaggerEndpoint("/swagger/v1/swagger.json", "Test v1");
                //config.SwaggerEndpoint("/swagger/v2/swagger.json", "Test v2");
            });
            app.UseHttpsRedirection();

            app.UseAuthentication();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

如下登录并生成jwt部分。由于我没有将它与数据库一起使用,因此我自定义了一个用户:

型号:

public class Usuario
    {
        public string NomeUsuario { get; set; }
        public string Senha { get; set; }
    }

控制器:

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebApplication129.Model;

namespace WebApplication129.Controllers.V1
{
    [Route("api/[controller]")]
    [ApiController]
    public class SegurancaController : Controller
    {
        private IConfiguration _config;
        public SegurancaController(IConfiguration Configuration)
        {
            _config = Configuration;
        }
        [HttpPost]
        [Route("login")]
        public IActionResult Login([FromBody] Usuario loginDetalhes)
        {
            bool resultado = ValidarUsuario(loginDetalhes);
            if (resultado)
            {
                var tokenString = GerarTokenJWT();
                return Ok(new { token = tokenString });
            }
            else
            {
                return Unauthorized();
            }
        }
        private string GerarTokenJWT()
        {
            var issuer = _config["Jwt:Issuer"];
            var audience = _config["Jwt:Audience"];
            var expiry = DateTime.Now.AddMinutes(120);
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
            var token = new JwtSecurityToken(issuer: issuer, audience: audience,
expires: expiry, signingCredentials: credentials);
            var tokenHandler = new JwtSecurityTokenHandler();
            var stringToken = tokenHandler.WriteToken(token);
            return stringToken;
        }
        private bool ValidarUsuario(Usuario loginDetalhes)
        {
            if (loginDetalhes.NomeUsuario == "TestName" && loginDetalhes.Senha == "TestPwd")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

测试和验证 API:

 [ApiController]
[Route("api/v1/[controller]")]
public class HomeController : ControllerBase
{
    /// <summary>
    /// Add the description information you need    
    /// </summary>
    /// 
    /// 
    [Route("test")]
   [HttpGet]
    
    public string Test( int userID)
    {
        return "v1 test";
    }

    [Route("list_data")]
    [HttpGet]
    [Authorize]
    public Object  Data()
    {
        User user = new User();
        user.id = 1;
        user.userName = "Test";
        user.email = "test@xxx.com";
        user.address = "testAddress";

        return user;
    }

}

上面展示了两个API,一个需要授权,一个不需要授权才能访问。

结果:

【讨论】:

  • 感谢您提供详细示例。感谢这一点,尽管我的错误是在使用 Postman 时没有包含正确的 JWT 不记名令牌
猜你喜欢
  • 2020-09-17
  • 2018-07-01
  • 1970-01-01
  • 2020-01-24
  • 2021-01-24
  • 2021-03-19
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多