我正在ASP上实现安全性。NET Core 1.0.1应用程序,它被用作Web API。我试图了解是否以及如何实现2种不同的身份验证方案。
理想情况下,我希望允许通过Azure Active Directory或通过用户名/密码对与应用程序联系的特定后端服务进行身份验证。是否可以配置ASP ?对于这样的设置,端点通过Azure AD或JWT令牌进行身份验证?
我尝试过这样做,但是在调用生成令牌端点时,我得到了一个完全没有信息的500。删除Azure AD配置可以使端点正常工作:
services.AddAuthorization(configuration =>
{
configuration.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = Configuration["Authentication:AzureAD:ClientId"],
Authority
= Configuration["Authentication:AzureAd:AADInstance"]
+ Configuration["Authentication:AzureAd:TenantId"],
ResponseType = OpenIdConnectResponseType.IdToken,
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
});
app.UseJwtBearerAuthentication(new JwtBearerOptions
{
TokenValidationParameters = new TokenValidationParameters
{
ClockSkew = TimeSpan.FromMinutes(1),
IssuerSigningKey = TokenAuthenticationOptions.Credentials.Key,
ValidateAudience = true,
ValidateIssuer = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidAudience = TokenAuthenticationOptions.Audience,
ValidIssuer = TokenAuthenticationOptions.Issuer
}
});
在添加授权策略和添加认证中间件时使用OpenIdConnectDefaults.AuthenticationScheme
常数
这里您使用的是OpenIdConnectDefaults
。好。保持那条线。
services.AddAuthorization(configuration =>
{
...
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme) // keep
.RequireAuthenticatedUser().Build());
});
这里您使用的是CookieAuthenticationDefaults
。删除那一行
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
...
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme // delete
});
为什么?
当您的OpenIdConnect授权策略运行时,它将查找名为OpenIdConnectDefaults.AuthenticationScheme
的身份验证方案。它不会找到一个,因为注册的OpenIdConnect中间件命名为CookieAuthenticationDefaults.AuthenticationScheme
。如果您删除了错误的行,那么代码将自动使用适当的默认值。
编辑:对示例的注释
第二个合理的解决方案
注释中链接的示例应用程序调用services.AddAuthentication
并将SignInScheme
设置为"Cookies"。这将更改所有身份验证中间件的默认登录方案。结果:对app.UseOpenIdConnectAuthentication
的调用现在相当于:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
}
这正是卡米洛一开始所拥有的。那么为什么我的答案有效呢?
我的回答起作用了,因为不管我们选择什么SignInScheme
的名字;重要的是这些名字是一致的。如果我们将OpenIdConnect身份验证登录方案设置为"Cookies",那么在添加授权策略时,我们需要像这样通过名称请求该方案:
services.AddAuthorization(configuration =>
{
...
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme) <----
.RequireAuthenticatedUser().Build());
});
第三种合理的解决方案
为了强调一致性的重要性,这里是第三个合理的解决方案,在方案名称中使用任意符号。
services.AddAuthorization(configuration =>
{
configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes("Foobar")
.RequireAuthenticatedUser().Build());
});
这里你正在使用CookieAuthenticationDefaults
。删除那一行
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
SignInScheme = "Foobar"
});