ASP.NET JSON Web 令牌“401 未经授权”
Posted
技术标签:
【中文标题】ASP.NET JSON Web 令牌“401 未经授权”【英文标题】:ASP.NET JSON Web Token "401 Unauthorized" 【发布时间】:2016-05-17 12:29:34 【问题描述】:我正在使用分离的资源和身份验证服务器。 当我成功获得 JSON Web 令牌时,我使用 jwt.io 检查它,令牌格式一切正常,而且它是秘密的。
请求带有授权标头:
Authorization: Bearer TOKEN_HERE
响应总是“401 Unauthorized”:
"message": "Authorization has been denied for this request."
这是来自资源服务器的 Startup.cs
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Jwt;
using Newtonsoft.Json.Serialization;
using Owin;
using System.Web.Http;
using Test.Database;
using Test.Infrastructure;
using Microsoft.WindowsAzure.ServiceRuntime;
[assembly: OwinStartup(typeof(Test.API.Startup))]
namespace Custodesk.API
public class Startup
public void Configuration(IAppBuilder app)
app.CreatePerOwinContext(() =>
ApplicationDbContext.Create(RoleEnvironment.GetConfigurationSettingValue("SqlConnectionString")));
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
GlobalConfiguration.Configuration.SuppressDefaultHostAuthentication();
ConfigureOAuthTokenConsumption(app);
GlobalConfiguration.Configure(config =>
//global filters
config.Filters.Add(new AuthorizeAttribute());
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "controller/action/id",
defaults: new id = RouteParameter.Optional
);
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(GlobalConfiguration.Configuration);
private void ConfigureOAuthTokenConsumption(IAppBuilder app)
var issuer = "http://localhost";
var audience = "Universal_application";
var secret = Helper.GetHash("helper_class_to_get_the_same_hash_as_authentication_server");
// Api controllers with an [Authorize] attribute will be validated with JWT
app.UseJwtBearerAuthentication(
new JwtBearerAuthenticationOptions
AuthenticationMode = AuthenticationMode.Active,
AllowedAudiences = new[] audience ,
IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
new SymmetricKeyIssuerSecurityTokenProvider(issuer, secret)
);
以下是令牌解密的示例:
"typ": "JWT",
"alg": "HS256"
"nameid": "b22a825e-60ce-45ed-b2cb-b2ee46a47936",
"unique_name": "begunini",
"role": [
"Owner",
"Admin",
"ManagerViewer"
],
"iss": "http://localhost",
"aud": "Universal_application",
"exp": 1454876502,
"nbf": 1454876202
我检查了 Secret 并且双方(身份验证和资源服务器)都相同。 观众匹配,发行人也。 已经尝试将 System.IdentityModel.Tokens.Jwt 降级到 3.0.2 版但没有成功
我猜配置顺序有问题,但没有任何帮助。
有什么想法吗?
【问题讨论】:
【参考方案1】:TL;DR:你试过删除GlobalConfiguration.Configuration.SuppressDefaultHostAuthentication()
吗?
使用此方法时,Web API 会删除由主机或在 Web API 之前注册的中间件(在您的情况下,由 JWT 承载中间件)创建并添加到 OWIN 上下文的用户主体。
此方法旨在与HostAuthenticationFilter
或HostAuthenticationAttribute
一起使用,直接调用与指定身份验证类型对应的身份验证中间件,并将生成的用户主体持久保存在 OWIN 上下文中。
由于您使用SuppressDefaultHostAuthentication
而不使用HostAuthenticationAttribute
,Web API 总是会看到未经身份验证的请求,这就是它们被AuthorizeAttribute
拒绝的原因。
【讨论】:
这很有帮助,非常感谢!我认为 SuppressDefaultHostAuthentication() 允许另一个身份验证处理程序优先。同意,缺少适当的 HostAuthenticationFilter 当你使用 OWIN 时,你根本不应该使用 GlobalConfiguration。以上是关于ASP.NET JSON Web 令牌“401 未经授权”的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core 和 JSON Web 令牌 - 自定义声明映射
如何在 Asp.NET Core WEB API 中使用 .Net (C#) 在 Payload 中创建具有自定义 JSON 声明的 JWT 令牌