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

Posted

技术标签:

【中文标题】配置不同的授权/认证方案【英文标题】:Configuring different authorization/authentication schemes 【发布时间】:2017-03-11 18:49:33 【问题描述】:

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

我尝试过这样的事情,但是在调用生成令牌端点时,我得到一个 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
     
);

【问题讨论】:

OpenIdConnect 身份验证需要 Cookie 身份验证。像这样github.com/aspnet/Security/blob/dev/samples/OpenIdConnectSample/… 不清楚您要做什么。您写道,“端点通过 Azure AD 或 JWT 令牌进行身份验证......” 对于 JWT 令牌部分,用户从哪里获得 JWT 令牌?对于通过 Azure AD 部分,您的意思是在用户缺少令牌时将用户重定向到 Azure AD 吗? @ShaunLuttin AAD 令牌必须来自 AAD,是的,应用程序应该重定向它们。 JWT 令牌在我创建的端点(控制器操作)处生成 【参考方案1】:

在添加授权策略和添加身份验证中间件时使用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 设置为“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"
);

【讨论】:

如果这就是问题所在,那为什么我发现的每一篇 Microsoft 文章和 GitHub 存储库都是这样设置的? @CamiloTerevinto 您能否链接示例 MSFT 文章或 GitHub 存储库设置。这样我就可以回复你的评论了。 当然,见github.com/Azure-Samples/… 问题实际上隐藏在中间件中,您的第一个解决方案(我之前尝试过)让我意识到这一点。谢谢 @CamiloTerevinto 酷。我鼓励您发布自己的答案,以表明我的答案帮助您找到的解决方案。这可能会在将来对其他人有所帮助,我会觉得这很有趣。

以上是关于配置不同的授权/认证方案的主要内容,如果未能解决你的问题,请参考以下文章

Hive 配置——认证和授权

OAuth 2.0实现分布式认证授权-认证服务器配置

Shiro学习——认证与授权(ini文件配置与数据库配置方式)

SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权

动手实验01-----vCenter 微软AD认证配置与用户授权

Shiro学习——认证与授权(ini文件配置与mysql方式)