Bre*_*gby 6 c# authentication jwt openid-connect .net-core
简短版本:我在我的 .NET Core MVC 网站中合并正确的身份验证配置以允许我的用户针对 Azure Active Directory 进行身份验证时遇到问题,但也允许守护程序连接(来自控制台应用程序)。
长版: 我有一个 .NET Core MVC 网站,当在 Startup.cs 的 ConfigureServices 方法中使用以下内容时,它可以完美地对 Azure Active Directory 进行身份验证:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddSignIn("AzureAd", Configuration, options => Configuration.Bind("AzureAd", options));
Run Code Online (Sandbox Code Playgroud)
我还试图让我的 .NET Core 控制台应用程序将 API(作为守护程序连接)调用到上述 MVC 网站(所有这些都在我的 Microsoft Azure 帐户的应用程序注册部分中配置)。我可以将控制台应用程序连接到 MVC 网站,它会在控制器中成功命中一个操作结果,但前提是我在网站的 Startup.cs 的 ConfigureServices 方法中使用以下内容:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddProtectedWebApi("AzureAd", Configuration, options => Configuration.Bind("AzureAD", options));
Run Code Online (Sandbox Code Playgroud)
基本上,如果我只使用 OpenIdConnect 选项,我的网络用户可以访问该网站,但我的控制台应用程序被拒绝。如果我只使用 JwtBearer 选项,那么我的控制台应用程序可以连接,但我的网络用户被拒绝。
我一整天都在使用 Google-Bing,我正在努力让这两种配置的混搭能够正常工作,而不会将另一种淘汰。
我曾尝试使用 .AddJwtBearer() 方法,但我完全被它弄糊涂了:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddSignIn("AzureAd", Configuration, options => Configuration.Bind("AzureAd", options))
.AddJwtBearer(options => Configuration.Bind("AzureAD", options));
Run Code Online (Sandbox Code Playgroud)
这些是如何协同工作的,这样两者都可以就位,我的 Web 应用程序可以通过浏览器运行,并且控制台应用程序(守护程序)也可以运行?我可以将两者都绑定到我的 appsettings.json 文件吗??
顺便说一下,appsettings.json 文件如下所示:
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "zzzzzzzzzzzzzz.onmicrosoft.com",
"TenantId": "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy",
"ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath ": "/signout-callback-oidc",
"ClientSecret": "myAzureClientSecret"
}
}
Run Code Online (Sandbox Code Playgroud)
2020 年 6 月 15 日更新:为 AGES 开启/关闭此功能后,我找到了一个合适的解决方案,因此我将赏金点数授予 @michael-shterenberg。另外,我现在知道我可以从@gary-archer 和他令人印象深刻的博客网站学到很多东西。我碰巧从迈克尔的意见中获得了成功。
这是上图中 ASP.NET Core MVC Web 应用程序中 Startup.cs 文件的 mods:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddSignIn("AzureAd", Configuration, options =>
Configuration.Bind("AzureAd", options))
.AddJwtBearer(o =>
{
o.Authority = "https://login.microsoftonline.com/common";
o.TokenValidationParameters.ValidateAudience = false;
o.TokenValidationParameters.ValidateIssuer = false;
});
services.AddAuthorization(options =>
{
options.AddPolicy("UserAndApp", builder =>
{
builder.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
builder.AuthenticationSchemes.Add(OpenIdConnectDefaults.AuthenticationScheme);
builder.RequireAuthenticatedUser();
});
});
Run Code Online (Sandbox Code Playgroud)
...再加上我试图从守护程序应用程序调用的控制器上的以下属性的使用。
[Authorize("UserAndApp")]
Run Code Online (Sandbox Code Playgroud)
我的用户仍然可以使用 Azure Active Directory 进程登录网站,现在我的自动化进程也可以登录。
如果有人在努力理解所有这些的 Azure 应用注册方面是如何工作的,请尝试这篇真正解释性的博客文章:
(当我试图了解 Azure 应用程序注册过程的工作原理时,我希望我早点看到它!)
这是对我有用的解决方案(在 ASP .NET Core 2.1 和 3.1 上测试)
AddAuthentication
应该不带参数:services.AddAuthentication()
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddJwtBearer(o=> {
o.Authority = "https://login.microsoftonline.com/common";
o.TokenValidationParameters.ValidateAudience = false;
o.TokenValidationParameters.ValidateIssuer = false;
});
Run Code Online (Sandbox Code Playgroud)
我使用过AddAzureAd
但没有AddSignIn
(这是您正在使用的自定义外部库吗?)
services.AddAuthorization(options =>
{
options.AddPolicy("UserAndApp", builer =>
{
builer.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
builer.AuthenticationSchemes.Add(AzureADDefaults.AuthenticationScheme);
builer.RequireAuthenticatedUser();
});
});
Run Code Online (Sandbox Code Playgroud)
[Authorize("UserAndApp")]
public class HomeController : Controller
Run Code Online (Sandbox Code Playgroud)
关于机制的一些解释:
您不想设置自动身份验证方案,因为这将是授权中间件中运行的默认架构,而您有两种不同的类型
该策略将尝试运行两个身份验证处理程序,如果其中一个成功,则身份验证成功
注意:如果您发送带有无效承载令牌的请求,则两个身份验证处理程序都将失败,在这种情况下,它们AzureADDefaults
将“获胜”,因为它实际上实现了质询方法并将重定向您(状态代码 302),因此请确保处理此问题在你的应用程序中
Gar*_*her -1
感觉架构不太正确,您需要将 Web 后端执行的 2 个角色分开:
当前的纯网络架构
多客户端架构
您需要更新 Web 后端以包含由 OAuth 2.0 访问令牌(而不是 cookie)保护的 API 入口点。然后,控制台应用程序将能够调用您的网络后端。
.NET 核心子路径
在您的 Web 后端引入额外的 /api 子路径。UseWhen功能将允许您在不影响其他 Web 后端行为的情况下执行此操作:
/*
* Apply API behaviour to only subpaths, without impacting the rest of the app
*/
app.UseWhen(
ctx => ctx.Request.Path.StartsWithSegments(new PathString("/api")),
api => {
api.useAuthentication();
api.useJwtBearer();
});
Run Code Online (Sandbox Code Playgroud)
.NET Core API 示例
有关使用子路径的示例,请参阅我的示例 .Net Core API。启动类是 ASP.Net 中间件与不同子路径的不同身份验证处理连接的地方。
未来的可能性
一旦您进行了上述逻辑分离,您将来就有可能进一步发展它,例如完全无 cookie 的模型:
我的博客https://authguidance.com遵循这种方法,并且我的示例 API 都支持任何类型的客户端。
归档时间: |
|
查看次数: |
2984 次 |
最近记录: |