C# 如何在ASP.net核心应用程序中同时使用承载身份验证和Cookie身份验证?

C# 如何在ASP.net核心应用程序中同时使用承载身份验证和Cookie身份验证?,c#,asp.net,authentication,cookies,bearer-token,C#,Asp.net,Authentication,Cookies,Bearer Token,我正在开发一个ASP.net Core 2.0应用程序,它使用IdentityServer4令牌服务器进行身份验证。我的应用程序有Razor页面,我想使用Cookie身份验证,还有一个API,我想使用承载令牌 这是我在Startup.cs中的设置: public void ConfigureServices(IServiceCollection services) { //... services.AddAuthentication(options => { opt

我正在开发一个ASP.net Core 2.0应用程序,它使用IdentityServer4令牌服务器进行身份验证。我的应用程序有Razor页面,我想使用Cookie身份验证,还有一个API,我想使用承载令牌

这是我在
Startup.cs中的设置:

    public void ConfigureServices(IServiceCollection services) {
//...
        services.AddAuthentication(options => { options.DefaultChallengeScheme = "oidc"; })
            .AddIdentityServerAuthentication(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                options.Authority = Configuration["OpenIDConnect:Authority"];
                options.ApiName = Configuration["OpenIDConnect:ApiName"];
                options.JwtBearerEvents.OnChallenge += async context =>
                {
                    context.Response.StatusCode = StatusCodes.Status403Forbidden;
                    context.HandleResponse();
                };
            })
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddOpenIdConnect("oidc", options =>
            {
                options.SignInScheme = "Cookies";
                options.Authority = Configuration["OpenIdConnect:Authority"];
                options.RequireHttpsMetadata = false;
                options.ClientId = Configuration["OpenIdConnect:ClientId"];
                options.SaveTokens = true;
                options.Scope.Add("role");
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role"
                };
            });

        services.AddAuthorization(options =>
        {
            options.AddPolicy(Constants.Policies.ApiUserWithBearerToken,
                policy =>
                {
                    policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
                    policy.AuthenticationSchemes.Remove(CookieAuthenticationDefaults.AuthenticationScheme);
                    policy.AuthenticationSchemes.Remove("oidc");
                    policy.RequireClaim("MobileClient", "true");
                    policy.RequireClaim("ApiUser", "true");
                });
        });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    //…
    //…
    app.UseAuthentication();
}
这是一个API端点,我正试图用承载令牌保护它:

[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = "Bearer"), MobileAppController]
public class CatalogController : Controller
{
    // …
    [HttpGet("current")]
    public async Task<IActionResult> Current()
    {
        // …
    }        
}
如果我删除了默认的质询方案,那么ASP.net只会抛出一个异常,表示它是必需的


我在这里遗漏了什么?

我也遇到了同样的问题,既然我解决了它,我很高兴提供我的解决方案。 通过调用
服务添加Identity Server时,默认情况下会添加AddIdentity Server()
cookie身份验证,如您在此处所见

您也不需要
.AddOpenIdConnect()
方法

现在,请记住,当您完成此操作时,您已经声明了两种身份验证方法来为您的身份验证请求提供服务。第一个是cookie(由is添加),另一个是通过调用
.AddIdentityServerAuthentication()
添加的JWT承载。 由于cookie是首先添加的,因此当任何请求需要进行身份验证时,也会首先调用cookie,因此您需要指定在授权时要使用的方法,您通过使用以下方法正确地使用了这些方法:

[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = "Bearer"), MobileAppController]
我个人使用默认值,但结果相同:

[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme), MobileAppController]

有了这个,你应该有一个可以同时满足API请求和Razor页面的工作应用程序。

你解决了这个问题吗?
services.AddAuthentication()
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = Configuration["Settings:Authentication:Authority"];
        options.RequireHttpsMetadata = !CurrentEnvironment.IsDevelopment();

        options.ApiName = Configuration["Settings:Authentication:ApiName"];
        options.ApiSecret = Configuration["Settings:Authentication:ApiSecret"];
     });
[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = "Bearer"), MobileAppController]
[Route("api/[controller]"), Authorize(Policy = "ApiUserWithBearerToken", AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme), MobileAppController]