我正在ASP.NET Core 1.0.1应用程序上实现安全性,该应用程序用作Web API。我试图了解是否以及如何实施2种不同的身份验证方案
理想情况下,我希望允许通过Azure Active Directory或通过用户名/密码进行身份验证,以获取与应用程序联系的特定后端服务。
是否可以为这样的设置配置ASP.NET Core,其中端点通过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
}
});
答案 0 :(得分:3)
添加授权策略时以及添加身份验证中间件时使用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
。如果删除该错误行,则代码将automatically use the appropriate default.
The linked sample application from the comments拨打services.AddAuthentication
并将SignInScheme
设置为" Cookie"。这会更改所有身份验证中间件的默认登录方案。结果:对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"
});