c# - 可以为一个 Api 设置两个身份验证吗?身份服务器4
问题描述
我建立了一个身份服务器,并与一个客户端两个grant_types。混合和密码。
现在,他们每个人都可以独立获取访问令牌。如果同时添加它们。只是混合工作。密码模式可以获得访问令牌,但是当访问带有不记名令牌的 api 时。我被重定向到混合登录页面。
// add password authentication
services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options =>
{
options.Authority = "http://localhost";
options.RequireHttpsMetadata = false;
options.Audience = "SlideCloudStorage";
});
// add hybrid authentication
// todo add this information to configuration.
services.AddAuthentication(
options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect(
"oidc",
options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost";
options.RequireHttpsMetadata = false;
options.ClientId = "slide-cloud-storage";
options.ClientSecret = "secret";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.Scope.Add("offline_access");
options.ClaimActions.MapJsonKey("website", "website");
});
希望这不是 XY 问题。为什么我要添加两个身份验证?
密码模式适用于我的桌面客户端。Hybrid 适用于我的网络/移动客户端。
解决方案
services.AddAuthentication("Bearer")
这会将默认身份验证方案设置为Bearer
。
services.AddAuthentication(
options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
这会将默认身份验证方案设置为Cookies
(并将默认质询方案设置为oidc
)。所以在此之后,默认情况下不再调用承载认证。
配置多个身份验证方案非常好,在许多情况下也有些需要。但是您必须了解,框架会自动调用一个默认值(对于每个身份验证操作)。我已经对这个问题进行了更详细的解释,但这个想法基本上是当你不做任何特别的事情时,当请求进来时,默认的身份验证方案将用于对用户进行身份验证。
因此,在您的情况下,Cookies
作为默认方案,用户将尝试通过他们的 cookie 登录。对于以用户为中心的应用程序来说,这通常是一个很好的默认设置,因为大多数用户都会使用 cookie 来验证自己的身份。另一方面,对这些应用程序的 API 访问更为特殊,通常仅限于几个控制器或路由;因此,将不记名身份验证作为默认设置通常没那么有用。
那么什么时候Cookies
是默认的,并且只能有一个默认会自动调用,那么使用其他方案的方法是什么?答案是授权策略。
授权策略通常允许您根据某些规则限制访问。策略基本上是这些规则的集合。出于授权目的,您通常会检查声明值以控制某人是否被授权做某事。然而,授权策略还有另一个方面,那就是它们允许您将身份验证方案指定为规则。
当您使用 来创建授权策略时AuthorizationPolicyBuilder
,您可以指定它所需的身份验证方案。当授权策略随后用于授权请求时,如果这些方案尚未经过身份验证,它将自动对其进行身份验证。
因此,您可以使用此机制为您的 API 控制器触发不记名身份验证,而不会影响默认 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
{
// …
}
请注意,最后,这也会导致临时创建一个策略来授权用户。所以效果和底层机制其实是一样的。
推荐阅读
- excel - 如果今天修改了txt文件,Excel VBA退出子
- ruby-on-rails - Rails 中惯用的 CSV 导出
- trace32 - Conditional breakpoint with trace32
- kubernetes - 带有警报的 K8S 监控堆栈配置
- c# - send multiple parameters to asp.net core 3 mvc action using post method
- flutter - Flutter - 如何在滚动到屏幕上时创建小部件
- postgresql - Can we load CSV data from S3 to Redshift and RDS using same COPY command?
- elasticsearch - How does Elasticsearch incremental snapshots deal with the deleted docs?
- python - Finding items inside a list
- scala - Spark Noob 对 DataFrame count() 和 show() 之间的不一致感到困惑