Azure B2C:如何获得“组"身份?在JWT令牌中索赔 [英] Azure B2C: How do I get "group" claim in JWT token
问题描述
In the Azure B2C, I used to be able to get a "groups" claim in my JWT tokens by following Retrieving Azure AD Group information with JWT:
- 打开老式的Azure管理器( https://manage.windowsazure.com )
- 向B2C注册我的应用程序
- 下载该应用程序的B2C清单
- 在清单中,将"groupMembershipClaims"条目更改为
- Open the old-school Azure manager (https://manage.windowsazure.com)
- Register my application with B2C
- Download the B2C manifest for the application
- In the manifest, change the "groupMembershipClaims" entry to
"groupMembershipClaims":"SecurityGroup",
"groupMembershipClaims": "SecurityGroup",
在过去(大约一个月前),这种方法运行良好,但现在已经不行了.详情请见下文...
This has worked well in the past (about a month ago, I believe...) but it doesn't anymore. See below for details...
遵循上面的已知有效配方.
Follow the known-good recipe above.
不幸的是,它不再起作用-当此客户端尝试通过B2C对我进行身份验证时,出现以下错误:
Unfortunately that doesn't work anymore - I get the following error when this client tries to authenticate me with B2C:
AADB2C90068:提供的ID为'032fe196-e17d-4287-9cfd-25386d49c0d5'的应用程序对此服务无效.请使用通过B2C门户创建的应用程序,然后重试."
AADB2C90068: The provided application with ID '032fe196-e17d-4287-9cfd-25386d49c0d5' is not valid against this service. Please use an application created via the B2C portal and try again"
好的,很公平-他们正在将我们转移到新的门户网站.
OK, fair enough - they're moving us to the new Portal.
使用新的门户网站遵循旧的良好食谱.
Follow the good old recipe, using the new Portal.
但这也不起作用-当我进入下载清单"部分时,我找不到任何访问清单的方法(Google告诉我它可能已经消失了……).
But that doesn't work either - when I get to the "download manifest" part, I cannot find any way to access the manifest (and Googling tells me it's probably gone for good...).
有点绝望的是,我尝试混合使用计划A和计划B:使用新的门户注册应用程序,然后使用旧的Azure管理器更改清单.
Getting a little desperate, I tried mixing plans A and B: register the app using the new Portal, then change the manifest using the old Azure Manager.
但是没有运气-当我尝试上传清单时,它失败并显示消息
But no luck - when I try to upload the manifest, it fails with the message
ParameterValidationException =提供了无效的参数; BadRequestException =此版本不允许更新到聚合应用程序.
ParameterValidationException=Invalid parameters provided; BadRequestException=Updates to converged applications are not allowed in this version.
计划Z:使用Graph API检索组成员资格数据
只需放弃组"声明-相反,每当我需要组信息时,只需使用Graph API查询B2C服务器即可.
Plan Z: Use the Graph API to retrieve group membership data
Just give up the "group" claim - instead, whenever I need group info, just query the B2C server using the Graph API.
我真的很不想这样做-它将破坏访问令牌的自包含性,并使系统变得非常混乱".
I really, really don't want to do this - it would ruin the self-contained-ness of the access token, and make the system very "chatty".
但是我在这里将其作为计划Z包含在内,只是为了说:是的,我知道该选项存在,不,我还没有尝试过-我宁愿不这样做.
But I've included it as a plan Z here, just to say: yes, I know the option exists, no I haven't tried it - and I'd prefer not to.
这几天我如何在我的JWT令牌中获得团体"索赔?
How do I get the "group" claim in my JWT token these days?
推荐答案
Plan Z it is I'm afraid. I don't know why they don't return it, but it's currently marked as planned on their Feedback Portal (it's the highest rated item).
这就是我的做法.在对用户进行身份验证时查询组,您也可以按照自己的方式进行操作-仅在需要时查询.取决于您的用例.
This is how I'm doing it. Querying the groups when the user is authenticated, you can do it your way as well - just query as and when you need to. Depends on your use case.
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);
}
}
我的GetGroups
方法仅查询 getMemberGroups
方法
My GetGroups
method just queries the getMemberGroups
method on the Users API
然后,我有一个简单的帮助程序方法来确定用户是否具有角色:
Then I have a simple helper method to determine whether the user is in a role:
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);
}
这篇关于Azure B2C:如何获得“组"身份?在JWT令牌中索赔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!