Tho*_*urg 17 azure jwt azure-ad-b2c
在Azure B2C中,我曾经通过使用JWT 检索Azure AD组信息,在我的JWT令牌中获得"组"声明:
"groupMembershipClaims":"SecurityGroup",
这在过去一直运作良好(大约一个月前,我相信......)但它已不复存在了.详见下文......
按照上面已知的好食谱.
不幸的是,这不再起作用 - 当此客户端尝试使用B2C验证我时出现以下错误:
AADB2C90068:提供的ID为"032fe196-e17d-4287-9cfd-25386d49c0d5"的应用程序对此服务无效.请使用通过B2C门户创建的应用程序,然后重试"
好吧,公平 - 他们正在把我们带到新门户网站.
使用新的Portal,按照好的旧配方.
但这也不起作用 - 当我到达"下载清单"部分时,我找不到任何方法来访问清单(并且谷歌搜索告诉我它可能已经好了......).
有点绝望,我尝试混合计划A和B:使用新的Portal注册应用程序,然后使用旧的Azure Manager更改清单.
但没有运气 - 当我尝试上传清单时,它会失败并显示消息
ParameterValidationException =提供的参数无效; BadRequestException =此版本不允许对聚合应用程序进行更新.
只需放弃"组"声明 - 相反,每当我需要组信息时,只需使用Graph API查询B2C服务器.
我真的,真的不想这样做 - 它会破坏访问令牌的自包含性,并使系统非常"健谈".
但是我把它作为Z计划包括在内,只是说:是的,我知道选项存在,不,我没有尝试过 - 而且我不愿意.
如何在我的JWT令牌中获得"团体"声明这些天?
计划Z我害怕.我不知道为什么他们不退货,但它目前在他们的反馈门户上标记为计划(这是评价最高的项目).
这就是我的做法.在用户通过身份验证时查询组,您也可以按照自己的方式进行查询 - 只需在需要时进行查询.取决于您的用例.
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseKentorOwinCookieSaver();
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
LoginPath = new PathString("/account/unauthorised"),
CookieSecure = CookieSecureOption.Always,
ExpireTimeSpan = TimeSpan.FromMinutes(20),
SlidingExpiration = true,
CookieHttpOnly = true
});
// Configure OpenID Connect middleware for each policy
app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(Globals.SignInPolicyId));
}
private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy)
{
return new OpenIdConnectAuthenticationOptions
{
// For each policy, give OWIN the policy-specific metadata address, and
// set the authentication type to the id of the policy
MetadataAddress = string.Format(Globals.AadInstance, Globals.TenantName, policy),
AuthenticationType = policy,
AuthenticationMode = AuthenticationMode.Active,
// These are standard OpenID Connect parameters, with values pulled from web.config
ClientId = Globals.ClientIdForLogin,
RedirectUri = Globals.RedirectUri,
PostLogoutRedirectUri = Globals.RedirectUri,
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = AuthenticationFailed,
SecurityTokenValidated = SecurityTokenValidated
},
Scope = "openid",
ResponseType = "id_token",
// This piece is optional - it is used for displaying the user's name in the navigation bar.
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
}
};
}
private async Task SecurityTokenValidated(SecurityTokenValidatedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> token)
{
var groups = await _metaDataService.GetGroups(token.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value);
if (groups?.Value != null && groups.Value.Any())
{
foreach (IGroup group in groups.Value.ToList())
{
token.AuthenticationTicket.Identity.AddClaim(
new Claim(ClaimTypes.Role, group.DisplayName, ClaimValueTypes.String, "GRAPH"));
}
}
}
// Used for avoiding yellow-screen-of-death
private Task AuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
{
notification.HandleResponse();
if (notification.Exception.Message == "access_denied")
{
notification.Response.Redirect("/");
}
else
{
notification.Response.Redirect("/error?message=" + notification.Exception.Message);
}
return Task.FromResult(0);
}
}
Run Code Online (Sandbox Code Playgroud)
我的GetGroups
方法只是在Users API上查询getMemberGroups
方法
然后我有一个简单的帮助方法来确定用户是否在角色中:
public static bool UserIsInRole(IPrincipal user, string roleName)
{
var claims = user.Identity as ClaimsIdentity;
if (claims == null) return false;
return claims.FindAll(x => x.Type == ClaimTypes.Role).Any(x => x.Value == roleName);
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3921 次 |
最近记录: |