调用.Net API时如何解决邮递员中的401未授权错误
Posted
技术标签:
【中文标题】调用.Net API时如何解决邮递员中的401未授权错误【英文标题】:how to solve 401 unauthorized error in postman when calling a .Net API 【发布时间】: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, 【参考方案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 不记名令牌以上是关于调用.Net API时如何解决邮递员中的401未授权错误的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core API 在从 React 客户端调用时返回 401