我正在开发一个程序,它允许用户以两种方式进行身份验证:他们可以创建和使用本地(自制)帐户和任何电子邮件;或者他们可以仅为我们的组织使用Azure AD OAuth。无论使用哪种身份验证方法,用户都应被同等对待,并在context.User.Identity.IsAuthenticated
上返回true。
我遇到了只有Azure AD方法有效的问题,为了解决这个问题,我使用了身份验证策略inspired by this article。然而,在遵循它之后,两种身份验证方法似乎都不起作用:(
以下是startup.cs
中的服务代码:
services.AddJwtAuthorization();
services.AddAuthentication(o =>
{
o.DefaultScheme = "MultiAuthSchemes";
o.DefaultChallengeScheme = "MultiAuthSchemes";
})
.AddCookie(o =>
{
o.LoginPath = "/login";
})
.AddJwtBearer("HomebrewScheme", _ => { })
.AddPolicyScheme("MultiAuthSchemes", JwtBearerDefaults.AuthenticationScheme, options =>
{
options.ForwardDefaultSelector = context =>
{
string authorization = context.Request.Headers[HeaderNames.Authorization];
if (!string.IsNullOrEmpty(authorization) && authorization.Contains("Bearer "))
{
var token = authorization["Bearer ".Length..].Trim();
var jwtHandler = new JwtSecurityTokenHandler();
return jwtHandler.CanReadToken(token)
? "HomebrewScheme" : "AdScheme";
}
return CookieAuthenticationDefaults.AuthenticationScheme;
};
})
.AddMicrosoftIdentityWebApi(Config, "AzureAd", "AdScheme");
services.AddAuthorization(o =>
{
var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(
JwtBearerDefaults.AuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme,
"HomebrewScheme", "AdScheme");
defaultAuthorizationPolicyBuilder =
defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
o.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
var onlySecondJwtSchemePolicyBuilder = new AuthorizationPolicyBuilder("HomebrewScheme");
o.AddPolicy("OnlyHomebrewScheme", onlySecondJwtSchemePolicyBuilder
.RequireAuthenticatedUser()
.AddAuthenticationSchemes()
.Build());
var onlyCookieSchemePolicyBuilder = new AuthorizationPolicyBuilder("AdScheme");
o.AddPolicy("OnlyAdScheme", onlyCookieSchemePolicyBuilder
.RequireAuthenticatedUser()
.Build());
});
以下是startup.cs
中的应用代码:
app.UseAuthentication()
app.UseGraphQLPlayground(new PlaygroundOptions
{
GraphQLEndPoint = GraphQLApiEndpoint
});
app.UseWebSockets();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(x => x.MapGraphQL(path: GraphQLApiEndpoint));
下面是我用来测试身份验证的startup.cs
代码:
app.Use((context, next) =>
{
//Grab the first identity because the authentication type does not matter
if (context.User.Identity?.IsAuthenticated == true)
{
PermissionLevel = Permissions.Authorized;
}
});
从我调试的情况来看,系统从来没有检测到我现在获得了身份验证。我知道前端工作正常,因为如果我只使用services.AddMicrosoftIdentityWebApiAuthentication(Config, "AzureAd", "AdScheme");
,不管它是否是默认方案,一切都正常。
谢谢你的帮助,我被困在这件事上了😊
1条答案
按热度按时间pw9qyyiw1#
首先,我跟随this blog在我的代码中添加了Cookie认证。它提供了一个登录页面让我们登录。在AccountController中,它提供了几个模拟用户帐户,以便我们可以使用它们登录进行测试。
然后,我在登录页面中添加了代码,以便它提供使用AAD登录的选项。
更改
Program.cs
文件以添加多重身份验证方案。这是我的代码Program.cs
我的家庭控制器
我的帐户控制器:
我的登录模型和用户模型
查看-〉账户-〉登录。cshtml:
查看-〉首页-〉保密数据. cshtml
View-〉Shared-〉_LoginPartial. cshtml,请不要忘记将此部分视图添加到布局中。
appsetting.json:
这段代码在我这边运行得很好,我可以用cookie auth和aad登录。我注意到用aad登录后,
@User.Identity.Name
不会显示用户名。但实际上登录流程成功了。