我正在使用.NET Core,通过我的免费Azure帐户进行Azure Active Directory身份验证。目标是让用户登录,我的Web应用程序轮询数据库并找出他们拥有的访问权限,并将该访问权限添加到声明中。然后,当重新加载页面时,我可以使用.NET Core的新策略或命令验证用户。
这似乎对我的Microsoft帐户非常有效,但是,当我尝试使用我在Azure Active Directory中创建的帐户时,一旦用户尝试更改页面,索赔就会丢失。我已经通过调试验证了声明是在登录后添加的,并且是在初始首页加载时,但是一旦用户更改页面或刷新就会丢失。
所以,在我ConfigureServices
的{{1}}方法中,我有:
Startup.cs
而且,在services.AddAuthorization(options =>
{
foreach(var accessPolicy in AccessPolicy.GetAllPolicies())
{
options.AddPolicy(accessPolicy, policy => policy.Requirements.Add(new CanAccessRequirement(accessPolicy)));
}
});
services.AddSingleton<IAuthorizationHandler, CanAccessHandler>();
方法中我有:
Configure
最后,在我的控制器中,我的类上面有这样的行,其中app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
ClientId = ApiLogin.ClientId,
ClientSecret = ApiLogin.ClientSecret,
Authority = ApiLogin.Authority,
PostLogoutRedirectUri = Configuration["AzureAd:PostLogoutRedirectUri"],
ResponseType = OpenIdConnectResponseType.CodeIdToken,
CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
GetClaimsFromUserInfoEndpoint = false,
Events = new OpenIdConnectEvents()
{
OnRemoteFailure = OnAuthenticationFailed,
OnAuthorizationCodeReceived = OnAuthorizationCodeReceived
}
});
private Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
if (!Session.Keys.Contains(Constants.AUTH_TOKEN))
{
var email = user.FindFirst(ClaimTypes.Email)?.Value ?? user.Identity.Name;
if (email == null || !email.Contains('@')) return;
// This is the security token needed to talk to the API.
// Putting it as a magic value, since it doesn't have anything
// to do with the current problem
string token = "123";
Session.Set(Constants.AUTH_TOKEN, Encoding.ASCII.GetBytes(token));
// Add the claims
var claims = ApiLogin.LoginUser(token, email) ?? new List<string> { };
(user.Identity as ClaimsIdentity).AddClaims(claims.Select(p => new Claim(p.ToString(), "True")));
}
return Task.FromResult(0);
}
只保存常量字符串。
AccessPolicy
我无法弄清楚为什么这对我[Authorize(Policy = AccessPolicy.EditInvoicePrivilege)]
帐户有效,但在我尝试使用我的@hotmail
帐户时却无效。
我是否对索赔做错了什么?如果是这样,为什么它适用于一个帐户,而不适用于另一个帐户?
如果您需要更多信息,请与我们联系。不幸的是,有很多代码,所以用少量代码重新创建代码仍然很多。