C# 可以为一个Api设置两个身份验证吗?身份服务器4

C# 可以为一个Api设置两个身份验证吗?身份服务器4,c#,asp.net-core,identityserver4,C#,Asp.net Core,Identityserver4,我构建了一个身份服务器,并使用一个客户机实现了两种授权类型。混合和密码 现在,他们每个人都可以独立地获取访问令牌。 如果在同一时间添加主题。混合动力车就行了。 密码模式可以获取访问令牌,但当使用承载令牌访问api时。我被重定向到混合登录页面 //添加密码身份验证 服务。添加身份验证(“承载人”) .AddJwtBearer(“Bearer”,选项=> { 选项。权限=”http://localhost"; options.RequireHttpsMetadata=false; options.a

我构建了一个身份服务器,并使用一个客户机实现了两种授权类型。混合和密码

现在,他们每个人都可以独立地获取访问令牌。 如果在同一时间添加主题。混合动力车就行了。 密码模式可以获取访问令牌,但当使用承载令牌访问api时。我被重定向到混合登录页面

//添加密码身份验证
服务。添加身份验证(“承载人”)
.AddJwtBearer(“Bearer”,选项=>
{
选项。权限=”http://localhost";
options.RequireHttpsMetadata=false;
options.audition=“SlideCloudStorage”;
});
//添加混合身份验证
//todo将此信息添加到配置中。
services.AddAuthentication(
选项=>
{
options.DefaultScheme=“Cookies”;
options.DefaultChallengeScheme=“oidc”;
})
.AddCookie(“Cookies”)
.AddOpenIdConnect(
“oidc”,
选项=>
{
options.signnscheme=“Cookies”;
选项。权限=”http://localhost";
options.RequireHttpsMetadata=false;
options.ClientId=“幻灯片云存储”;
options.ClientSecret=“secret”;
options.ResponseType=“代码id\U令牌”;
options.SaveTokens=true;
options.GetClaimsFromUserInfoEndpoint=true;
options.Scope.Add(“脱机访问”);
选项.索赔.MapJsonKey(“网站”、“网站”);
});
希望这不是XY的问题。 为什么我要添加两个身份验证

密码模式适用于我的桌面客户端。 Hybrid适用于我的web/移动客户端

services.AddAuthentication("Bearer")
这将默认身份验证方案设置为
承载

services.AddAuthentication(
    options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
这将默认身份验证方案设置为
Cookies
(默认质询方案设置为
oidc
)。因此,在此之后,默认情况下不再调用承载身份验证

配置多个身份验证方案是非常好的,在许多情况下,这也是必需的。但是您必须了解,只有一个默认值(对于每个身份验证操作)将由框架自动调用。我已经解释过了,但其基本思想是,当您不做任何特殊的事情时,当请求传入时,将使用默认的身份验证方案对用户进行身份验证

因此,在您的情况下,
Cookies
是默认方案,用户将尝试通过Cookies登录。对于以用户为中心的应用程序来说,这通常是一个很好的默认设置,因为大多数用户将使用cookie来验证自己。另一方面,对这些应用程序的API访问更为特殊,通常仅限于几个控制器或路由;因此,将承载身份验证作为默认设置通常没有多大用处

那么当
Cookies
是默认值,并且只有一个默认值会自动调用时,那么使用其他方案的方法是什么呢?答案是授权策略

授权策略通常允许您根据某些规则限制访问。策略基本上就是这些规则的集合。出于授权目的,您通常会检查索赔值,以控制某人是否有权做某事。然而,授权策略还有一个方面,那就是它们允许您将身份验证方案指定为规则

使用创建授权策略时,可以指定它所需的身份验证方案。当授权策略用于授权请求时,如果这些方案尚未通过身份验证,它将自动对其进行身份验证

因此,您可以使用此机制触发API控制器的承载身份验证,而不会影响默认的cookie身份验证,只要您不指定任何其他内容,就会使用默认的cookie身份验证

[Authorize("ApiPolicy")]
public class MyApiController : ControllerBase
{
    // …
}
Startup.ConfigureServices
中:

services.AddAuthorization(options =>
{
    var apiPolicy = new AuthorizationPolicyBuilder("Bearer")
        .RequireAuthenticatedUser()
        .Build();
    options.AddPolicy("ApiPolicy", apiPolicy);
});
这样,您就配置了一个自定义策略,您可以随时扩展该策略以添加额外的需求(例如特殊声明),并使用它来授权客户端访问您的API

如果仅在少数操作或控制器中需要此项,还可以直接在
[Authorize]
属性中指定身份验证方案。这使您无需创建自定义授权策略,但另一方面,如果您希望使用其他要求(或更改的身份验证方案)扩展策略,则当然需要更多的复制和维护:

请注意,最后,这还将导致临时创建一个策略来授权用户。因此,效果和潜在机制实际上是相同的

[Authorize(AuthenticationSchemes = "Bearer")] 
public class MyApiController : ControllerBase
{
    // …
}