配置不同的授权/认证方案



我正在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"
});

最新更新