当我将Bearer令牌与受[Authorize]
保护的AspNetCore控制器一起使用时,会收到日志消息:
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[7]
Identity.Application was not authenticated. Failure message: Unprotect ticket failed
我正试图了解这意味着什么以及可能导致这种情况的原因。
Api的Startup
类具有以下设置。 Api使用AspNet Identity Core。
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<UserAccountDbContext>(options => options.UseSqlServer(connectionString,
sql => sql.MigrationsAssembly(MigrationsAssembly)));
services.AddIdentity<UserAccount, IdentityRole>()
.AddEntityFrameworkStores<UserAccountDbContext>();
services.AddTransient<UserManager<UserAccount>>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthorization();
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = _configuration.OAuth2.ServerUri;
options.RequireHttpsMetadata = false;
options.Audience = "api";
});
}
并且:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
对呼叫者的响应未经授权(401),没有任何解释。
编辑:
我认为这与Cookie有关,如评论所建议。我看到一个Cookie Identity.Application
。我清除了此内容并尝试了但没有帮助。我认为这可能与设置令牌服务器和Api服务器(两者都使用AspNet Identity)有关。
我有一个Mvc项目作为localhost:5000上的Idp运行。然后,具有受保护控制器的我的用户管理器Api托管在localhost:5001上。当我尝试访问受保护的控制器时,我被重定向到IdP项目中的登录页面(我认为这是设置cookie的原因)。然后,我尝试在控制器中使用令牌,但出现上述错误。
如果删除在获取令牌和进行Api调用之间的cookie,则会收到以下日志:
2019-02-11 23:35:15.3711 [INFO] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes ().
2019-02-11 23:35:15.3711 [INFO] Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
AuthenticationScheme: Identity.Application was challenged.
2019-02-11 23:35:15.3711 [INFO] AuthenticationScheme: Identity.Application was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
答案 0 :(得分:2)
我不记得要怎么解决这个问题。我已经很久没有解释答案了。基本上,我浏览了很多IdentityServer4示例和Microsoft文档,并将下面的内容合并在一起。看看是否有效。
services.AddAuthentication(options => options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.Audience = "api";
});
代替:
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = _configuration.OAuth2.ServerUri;
options.RequireHttpsMetadata = false;
options.Audience = "api";
});
答案 1 :(得分:2)
当我在端口5000上启动开发服务器时,我还收到“取消保护票证失败”错误消息。在Chrome浏览器中,我在另一个运行于5000个项目中的项目中放置了许多cookie。删除了所有cookie,并消失了错误消息。
答案 2 :(得分:0)
问题是当您的应用程序在反向代理或类似http的东西后面运行时,回调URL作为https传递,就像克里斯提到的那样。这就是swdon描述的方法有帮助的原因。
如果您在反向代理后面运行(例如,在azure linux webapp或docker容器中),这将帮助您根据应用运行的位置自动解决该问题(链接到相应问题,如代码):
// https://github.com/IdentityServer/IdentityServer4/issues/1331
var forwardOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, RequireHeaderSymmetry = false
};
forwardOptions.KnownNetworks.Clear();
forwardOptions.KnownProxies.Clear();
// ref: https://github.com/aspnet/Docs/issues/2384
app.UseForwardedHeaders(forwardOptions);
此内容必须放在app.UseAuthentication();