对于Asp.Net Core WebApi,身份验证失败并显示“取消保护票证失败”

时间:2019-02-11 15:12:45

标签: c# authentication oauth-2.0 asp.net-core-identity asp.net-core-2.2

当我将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]

3 个答案:

答案 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();

之前