配置不同的授权/认证方案
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 酷。我鼓励您发布自己的答案,以表明我的答案帮助您找到的解决方案。这可能会在将来对其他人有所帮助,我会觉得这很有趣。以上是关于配置不同的授权/认证方案的主要内容,如果未能解决你的问题,请参考以下文章
Shiro学习——认证与授权(ini文件配置与数据库配置方式)
SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权