AAD B2C:在 JWT 中为 Hasura 输出一个嵌套的 JSON 对象
AAD B2C: Output a nested JSON object in a JWT for Hasura
我们正在使用 Hasura 向消费者提供我们的 GraphQL API。目前我们使用 Auth0 对用户进行身份验证,但我们想迁移到 Azure AD B2C。
JWT security with Hasura is using the "https://hasura.io/jwt/claims" 命名空间要求提供自定义声明(例如 X-Hasura-Org-Id、X-Hasura-App-Id 等)。
我已经能够将 AAD B2C 用于:
- 使用 REST API;
收集这些自定义声明所需的值
- 使用
ClaimsTransformation
将单个 string
/ stringCollection
值转换为 JSON 对象;和
- Return JWT 中转换后的声明。
但是,我无法弄清楚如何让 JSON 对象出现在最终的 JWT 中而不对内容进行转义 - 即作为字符串而不是对象输出。
AAD B2C 是否能够在 JWT 中输出嵌套对象?
我们希望实现的目标
这就是 Hasura 希望 JWT 命名空间的样子(注意 https://hasura.io/jwt/claims
对象)
{
"exp": 1588405829,
"nbf": 1588402229,
"ver": "1.0",
"iss": "https://<redacted>.b2clogin.com/<redacted>/v2.0/",
"sub": "<redacted>",
"aud": "<redacted>",
"acr": "b2c_1a_aaa_signupsignin",
"nonce": "defaultNonce",
"iat": 1588402229,
"auth_time": 1588402229,
"given_name": "Test",
"family_name": "User",
"name": "Test User",
"email": "test@example.com",
"idp": "facebook.com",
"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles":["role1","role2","role3"],
"x-hasura-default-role":"role1",
"x-hasura-org-id":"test-org",
"x-hasura-user-id":"test-user-id",
"x-hasura-app-id":"<redacted>"
}
}
我们目前得到的
这是来自 AAD B2C 的 JWT 示例:
{
"exp": 1588405829,
"nbf": 1588402229,
"ver": "1.0",
"iss": "https://<redacted>.b2clogin.com/<redacted>/v2.0/",
"sub": "<redacted>",
"aud": "<redacted>",
"acr": "b2c_1a_aaa_signupsignin",
"nonce": "defaultNonce",
"iat": 1588402229,
"auth_time": 1588402229,
"given_name": "Test",
"family_name": "User",
"name": "Test User",
"email": "test@example.com",
"idp": "facebook.com",
"https://hasura.io/jwt/claims": "{\"x-hasura-allowed-roles\":[\"role1\",\"role2\",\"role3\"],\"x-hasura-default-role\":\"role1\",\"x-hasura-org-id\":\"test-org\",\"x-hasura-user-id\":\"test-user-id\",\"x-hasura-app-id\":\"<redacted>\"}"
}
似乎没有将声明存储为对象的选项,只有一个字符串。
我们是如何到达那里的
ClaimsTransformation
的例子:
<ClaimsTransformation Id="hasuraClaimsToJson" TransformationMethod="GenerateJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="x-hasura-allowed-roles" TransformationClaimType="x-hasura-allowed-roles" />
<InputClaim ClaimTypeReferenceId="x-hasura-default-role" TransformationClaimType="x-hasura-default-role" />
<InputClaim ClaimTypeReferenceId="x-hasura-org-id" TransformationClaimType="x-hasura-org-id" />
<InputClaim ClaimTypeReferenceId="x-hasura-user-id" TransformationClaimType="x-hasura-user-id" />
</InputClaims>
<InputParameters>
<InputParameter Id="x-hasura-app-id" DataType="string" Value="internal-redacted-uuid" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="hasuraClaims" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
示例 RelyingParty
配置:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="hasuraClaims" PartnerClaimType="https://hasura.io/jwt/claims" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
<OutputClaim ClaimTypeReferenceId="identityProvider" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
你能分享你想要从 B2C 获得的 JSON 的 desired/expected 输出吗?如果您查看文档:https://docs.microsoft.com/en-us/azure/active-directory-b2c/json-transformations,B2C 能够返回复杂的 JSON.
示例 JSON 生成的输出JSON:
"personalizations": [
{
"to": [
{
"email": "someone@example.com"
}
],
"dynamic_template_data": {
"otp": "346349",
"verify-email" : "someone@example.com"
},
"subject": "Contoso account email verification code"
}
],
"template_id": "d-989077fbba9746e89f3f6411f596fb96",
"from": {
"email": "service@contoso.com"
}
}
对于那些感兴趣的人,事实证明这目前无法通过 Azure AD B2C 实现。
相反,我们从使用 Hasura 中的内部 JWT 身份验证切换到 using webhooks,并使用小型 Node.js 功能应用程序验证 B2C 令牌。
编辑:
根据上面的回答,Hasura 有一个使用 claims_format
参数的解决方法。这意味着您可以潜在地使用 AAD B2C 进行 Hasura 身份验证,而无需实施 Webhooks。
您是否考虑过使用 stringified_json
在 HASURA_GRAPHQL_JWT_SECRET 中传递 claims_format
,以便 Hasura 可以接受声明作为字符串而不是对象。我在这里找到了文档条目:https://hasura.io/docs/1.0/graphql/manual/auth/authentication/jwt.html
我们正在使用 Hasura 向消费者提供我们的 GraphQL API。目前我们使用 Auth0 对用户进行身份验证,但我们想迁移到 Azure AD B2C。
JWT security with Hasura is using the "https://hasura.io/jwt/claims" 命名空间要求提供自定义声明(例如 X-Hasura-Org-Id、X-Hasura-App-Id 等)。
我已经能够将 AAD B2C 用于:
- 使用 REST API; 收集这些自定义声明所需的值
- 使用
ClaimsTransformation
将单个string
/stringCollection
值转换为 JSON 对象;和 - Return JWT 中转换后的声明。
但是,我无法弄清楚如何让 JSON 对象出现在最终的 JWT 中而不对内容进行转义 - 即作为字符串而不是对象输出。
AAD B2C 是否能够在 JWT 中输出嵌套对象?
我们希望实现的目标
这就是 Hasura 希望 JWT 命名空间的样子(注意 https://hasura.io/jwt/claims
对象)
{
"exp": 1588405829,
"nbf": 1588402229,
"ver": "1.0",
"iss": "https://<redacted>.b2clogin.com/<redacted>/v2.0/",
"sub": "<redacted>",
"aud": "<redacted>",
"acr": "b2c_1a_aaa_signupsignin",
"nonce": "defaultNonce",
"iat": 1588402229,
"auth_time": 1588402229,
"given_name": "Test",
"family_name": "User",
"name": "Test User",
"email": "test@example.com",
"idp": "facebook.com",
"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles":["role1","role2","role3"],
"x-hasura-default-role":"role1",
"x-hasura-org-id":"test-org",
"x-hasura-user-id":"test-user-id",
"x-hasura-app-id":"<redacted>"
}
}
我们目前得到的
这是来自 AAD B2C 的 JWT 示例:
{
"exp": 1588405829,
"nbf": 1588402229,
"ver": "1.0",
"iss": "https://<redacted>.b2clogin.com/<redacted>/v2.0/",
"sub": "<redacted>",
"aud": "<redacted>",
"acr": "b2c_1a_aaa_signupsignin",
"nonce": "defaultNonce",
"iat": 1588402229,
"auth_time": 1588402229,
"given_name": "Test",
"family_name": "User",
"name": "Test User",
"email": "test@example.com",
"idp": "facebook.com",
"https://hasura.io/jwt/claims": "{\"x-hasura-allowed-roles\":[\"role1\",\"role2\",\"role3\"],\"x-hasura-default-role\":\"role1\",\"x-hasura-org-id\":\"test-org\",\"x-hasura-user-id\":\"test-user-id\",\"x-hasura-app-id\":\"<redacted>\"}"
}
似乎没有将声明存储为对象的选项,只有一个字符串。
我们是如何到达那里的
ClaimsTransformation
的例子:
<ClaimsTransformation Id="hasuraClaimsToJson" TransformationMethod="GenerateJson">
<InputClaims>
<InputClaim ClaimTypeReferenceId="x-hasura-allowed-roles" TransformationClaimType="x-hasura-allowed-roles" />
<InputClaim ClaimTypeReferenceId="x-hasura-default-role" TransformationClaimType="x-hasura-default-role" />
<InputClaim ClaimTypeReferenceId="x-hasura-org-id" TransformationClaimType="x-hasura-org-id" />
<InputClaim ClaimTypeReferenceId="x-hasura-user-id" TransformationClaimType="x-hasura-user-id" />
</InputClaims>
<InputParameters>
<InputParameter Id="x-hasura-app-id" DataType="string" Value="internal-redacted-uuid" />
</InputParameters>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="hasuraClaims" TransformationClaimType="outputClaim" />
</OutputClaims>
</ClaimsTransformation>
示例 RelyingParty
配置:
<RelyingParty>
<DefaultUserJourney ReferenceId="SignUpOrSignIn" />
<TechnicalProfile Id="PolicyProfile">
<DisplayName>PolicyProfile</DisplayName>
<Protocol Name="OpenIdConnect" />
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="displayName" />
<OutputClaim ClaimTypeReferenceId="givenName" />
<OutputClaim ClaimTypeReferenceId="surname" />
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="hasuraClaims" PartnerClaimType="https://hasura.io/jwt/claims" />
<OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub"/>
<OutputClaim ClaimTypeReferenceId="identityProvider" />
</OutputClaims>
<SubjectNamingInfo ClaimType="sub" />
</TechnicalProfile>
</RelyingParty>
你能分享你想要从 B2C 获得的 JSON 的 desired/expected 输出吗?如果您查看文档:https://docs.microsoft.com/en-us/azure/active-directory-b2c/json-transformations,B2C 能够返回复杂的 JSON.
示例 JSON 生成的输出JSON:
"personalizations": [
{
"to": [
{
"email": "someone@example.com"
}
],
"dynamic_template_data": {
"otp": "346349",
"verify-email" : "someone@example.com"
},
"subject": "Contoso account email verification code"
}
],
"template_id": "d-989077fbba9746e89f3f6411f596fb96",
"from": {
"email": "service@contoso.com"
}
}
对于那些感兴趣的人,事实证明这目前无法通过 Azure AD B2C 实现。
相反,我们从使用 Hasura 中的内部 JWT 身份验证切换到 using webhooks,并使用小型 Node.js 功能应用程序验证 B2C 令牌。
编辑:
根据上面的回答,Hasura 有一个使用 claims_format
参数的解决方法。这意味着您可以潜在地使用 AAD B2C 进行 Hasura 身份验证,而无需实施 Webhooks。
您是否考虑过使用 stringified_json
在 HASURA_GRAPHQL_JWT_SECRET 中传递 claims_format
,以便 Hasura 可以接受声明作为字符串而不是对象。我在这里找到了文档条目:https://hasura.io/docs/1.0/graphql/manual/auth/authentication/jwt.html