ASP.NET JSON Web令牌“;401“未经授权”;
我正在使用解耦的资源和身份验证服务器。 当我成功获得JSON Web令牌时,我用jwt.io检查它,令牌格式和它的秘密一切正常 请求包含授权标头:ASP.NET JSON Web令牌“;401“未经授权”;,asp.net,authorization,owin,jwt,bearer-token,Asp.net,Authorization,Owin,Jwt,Bearer Token,我正在使用解耦的资源和身份验证服务器。 当我成功获得JSON Web令牌时,我用jwt.io检查它,令牌格式和它的秘密一切正常 请求包含授权标头: Authorization: Bearer TOKEN_HERE 响应始终为“401未经授权”: 这是我在资源服务器上的Startup.cs using Microsoft.Owin; using Microsoft.Owin.Cors; using Microsoft.Owin.Security; using Microsoft.Owin.Sec
Authorization: Bearer TOKEN_HERE
响应始终为“401未经授权”:
这是我在资源服务器上的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)
}
});
}
}
}
我已经检查了这个秘密,它在双方(身份验证服务器和资源服务器)都是一样的。
观众比赛,还有。
已尝试将System.IdentityModel.Tokens.Jwt降级至3.0.2版,但没有成功
我猜在配置顺序上有一些问题,但没有任何帮助
有什么想法吗?TL;DR:您是否尝试删除
全局配置.Configuration.SuppressDefaultHostAuthentication()
使用此方法时,Web API将删除主机或在Web API之前注册的中间件(在您的情况下,是JWT承载中间件)创建并添加到OWIN上下文中的用户主体
此方法旨在与HostAuthenticationFilter
或HostAuthenticationAttribute
一起使用,该方法直接调用与指定身份验证类型对应的身份验证中间件,并在OWIN上下文中持久化生成的用户主体
由于您使用的是
SuppressDefaultHostAuthentication
而没有HostAuthenticationAttribute
,因此Web API总是看到未经身份验证的请求,这就是为什么AuthorizeAttribute
会拒绝这些请求的原因。这很有帮助,非常感谢!我认为SuppressDefaultHostAuthentication()允许另一个身份验证处理程序优先。同意,缺少相应的HostAuthenticationFilter当您使用OWIN时,根本不应使用全局配置。
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
}