配置不同的授权/认证方案 [英] Configuring different authorization/authentication schemes

查看:142
本文介绍了配置不同的授权/认证方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ASP.NET Core 1.0.1应用程序上实现安全性,该应用程序用作Web API.我正在尝试了解是否以及如何实施2种不同的身份验证方案.
理想情况下,我希望允许通过Azure Active Directory或通过用户名/密码对与该应用程序联系的特定后端服务进行身份验证.
是否可以针对终端通过Azure AD或JWT令牌进行身份验证的设置配置ASP.NET Core?

I am implementing security on an ASP.NET Core 1.0.1 application, which is used as a Web API. I am trying to understand if and how to implement 2 different authentication schemes.
Ideally, I would like to allow authentication via Azure Active Directory or via username/password for specific back-end services that contact the application.
Is it possible to configure ASP.NET Core for such a setup where an endpoint either authenticates through Azure AD or JWT token?

我尝试了类似的方法,但是在调用了generate token端点时,我得到了500,但绝对没有任何信息.删除Azure AD配置可使终结点正常运行:

I tried with something like this, but upon calling the generate token endpoint, I get a 500 with absolutely no information. Removing the Azure AD configuration makes the endpoint work perfectly:

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常量.

Use the OpenIdConnectDefaults.AuthenticationScheme constant when you add the authorization policy and when you add the authentication middleware.

在这里您正在使用OpenIdConnectDefaults.好的.保持那条线.

Here you are using OpenIdConnectDefaults. Good. Keep that line.

services.AddAuthorization(configuration =>
{
    ...

    configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes(OpenIdConnectDefaults.AuthenticationScheme) // keep
        .RequireAuthenticatedUser().Build());
 });

在这里您正在使用CookieAuthenticationDefaults.删除该行.

Here you are using CookieAuthenticationDefaults. Delete that line.

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    ...

    SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme // delete
});

为什么?

运行OpenIdConnect授权策略时,它将查找名为OpenIdConnectDefaults.AuthenticationScheme的身份验证方案.找不到一个,因为注册的OpenIdConnect中间件名为CookieAuthenticationDefaults.AuthenticationScheme.如果删除该错误行,则代码将自动使用适当的默认值.

When your OpenIdConnect authorization policy runs, it will look for an authentication scheme named OpenIdConnectDefaults.AuthenticationScheme. It will not find one, because the registered OpenIdConnect middleware is named CookieAuthenticationDefaults.AuthenticationScheme. If you delete that errant line, then the code will automatically use the appropriate default.

来自注释的链接的示例应用程序调用services.AddAuthentication并将SignInScheme设置为"Cookies".这将更改所有身份验证中间件的默认登录方案.结果:对app.UseOpenIdConnectAuthentication的调用现在等效于此:

The linked sample application from the comments calls services.AddAuthentication and sets SignInScheme to "Cookies". That changes the default sign in scheme for all of the authentication middleware. Result: the call to app.UseOpenIdConnectAuthentication is now equivalent to this:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions 
{
    SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme
}

这恰恰是Camilo所拥有的.那我的答案为什么起作用?

That is exactly what Camilo had in the first place. So why did my answer work?

我的回答之所以有用,是因为我们选择的SignInScheme名称无关紧要;重要的是这些名称是一致的.如果我们将OpenIdConnect身份验证登录方案设置为"Cookies",则在添加授权策略时,我们需要按如下名称要求该方案:

My answer worked because it does not matter what SignInScheme name we choose; what matters is that those names are consistent. If we set our OpenIdConnect authentication sign in scheme to "Cookies", then when adding an authorization policy, we need to ask for that scheme by name like this:

services.AddAuthorization(configuration =>
{
    ...

    configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme) <----
        .RequireAuthenticatedUser().Build());
});

第三个合理的解决方案

为强调一致性的重要性,这是使用方案名称中的任意符号的第三个合理解决方案.

A third reasonable solution

To emphasize the importance of consistency, here is a third reasonable solution that uses an arbitrary sign in scheme name.

services.AddAuthorization(configuration =>
{
    configuration.AddPolicy("OpenIdConnect", new AuthorizationPolicyBuilder()
        .AddAuthenticationSchemes("Foobar")
        .RequireAuthenticatedUser().Build());
});

在这里您正在使用CookieAuthenticationDefaults.删除该行.

Here you are using CookieAuthenticationDefaults. Delete that line.

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    SignInScheme = "Foobar"
});

这篇关于配置不同的授权/认证方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆