You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Azure AD B2C自定义策略中用客户端凭据传递查询参数

问题:Azure AD B2C客户端凭据流自定义策略无法识别查询参数

我正尝试使用客户端凭据(client_id和client_secret)访问Azure AD B2C的自定义策略以获取自定义JWT,目前已实现基础功能,但无法让自定义策略识别传递的查询参数。

当前配置与正常执行情况

我的自定义策略文件MyPolicy.xml内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrustFrameworkPolicy
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://schemas.microsoft.com/online/cpim/schemas/2013/06"
    PolicySchemaVersion="0.3.0.0"
    TenantId="{tenant}.onmicrosoft.com"
    PolicyId="B2C_1A_MyPolicy"
    PublicPolicyUri="http://{tenant}.onmicrosoft.com/B2C_1A_MyPolicy"
    DeploymentMode="Development"
    UserJourneyRecorderEndpoint="urn:journeyrecorder:applicationinsights">

    <BasePolicy>
        <TenantId>{tenant}.onmicrosoft.com</TenantId>
        <PolicyId>B2C_1A_TrustFrameworkBase</PolicyId>
    </BasePolicy>

    <BuildingBlocks>
        <ClaimsSchema>
            <!-- JWT -->
            <ClaimType Id="value">
                <DataType>string</DataType>
            </ClaimType>
        </ClaimsSchema>
    </BuildingBlocks>

    <ClaimsProviders>
        <ClaimsProvider>
            <DisplayName></DisplayName>
            <TechnicalProfiles>
                <TechnicalProfile Id="SetQueryParams">
                    <DisplayName>Set the BrandId and other query params from the OIDC:ClientId field in the url params</DisplayName>
                    <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                    <Metadata>
                        <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
                    </Metadata>
                    <OutputClaims>
                        <OutputClaim ClaimTypeReferenceId="value" DefaultValue="{OAUTH-KV:value}" AlwaysUseDefaultValue="true" />
                    </OutputClaims>
                    <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
                </TechnicalProfile>
            </TechnicalProfiles>
        </ClaimsProvider>
    </ClaimsProviders>

    <UserJourneys>
        <UserJourney Id="MyUserJourney">
            <OrchestrationSteps>
                <OrchestrationStep Order="1" Type="ClaimsExchange">
                    <ClaimsExchanges>
                        <ClaimsExchange Id="SetQueryParamsStep" TechnicalProfileReferenceId="SetQueryParams" />
                    </ClaimsExchanges>
                </OrchestrationStep>

                <!-- Issue JWT -->
                <OrchestrationStep Order="2" Type="SendClaims" CpimIssuerTechnicalProfileReferenceId="JwtIssuer" />
            </OrchestrationSteps>
        </UserJourney>
    </UserJourneys>

    <RelyingParty>
        <DefaultUserJourney ReferenceId="MyUserJourney" />
        <UserJourneyBehaviors>
            <JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="623badc9-900b-44e3-bd44-bf00d97d9d93" DeveloperMode="true" ClientEnabled="true" ServerEnabled="true" TelemetryVersion="1.0.0" />
            <ScriptExecution>Allow</ScriptExecution>
        </UserJourneyBehaviors>
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" AlwaysUseDefaultValue="true" DefaultValue="8186c7b3-adca-4c17-b318-939e9d8170b8" />
                <OutputClaim ClaimTypeReferenceId="value" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
</TrustFrameworkPolicy>

我使用以下x-www-form-urlencoded格式的请求调用策略:

https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/B2C_1A_MyPolicy/oauth2/v2.0/token?grant_type=client_credentials&client_id=<appId>&client_secret=<client_secret>&scope=https://{tenant}.onmicrosoft.com/api/.default

此时策略可正常执行,返回包含硬编码默认值字段的JWT。

错误场景

当我修改RelyingParty部分,为value声明添加默认值{OAUTH-KV:value}后:

<RelyingParty>
    <DefaultUserJourney ReferenceId="MyUserJourney" />
    <UserJourneyBehaviors>
        <JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="{Settings:AppInsightsKey}" DeveloperMode="true" ClientEnabled="true" ServerEnabled="true" TelemetryVersion="1.0.0" />
        <ScriptExecution>Allow</ScriptExecution>
    </UserJourneyBehaviors>
    <TechnicalProfile Id="PolicyProfile">
        <DisplayName>PolicyProfile</DisplayName>
        <Protocol Name="OpenIdConnect" />
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" AlwaysUseDefaultValue="true" DefaultValue="8186c7b3-adca-4c17-b318-939e9d8170b8" />
            <OutputClaim ClaimTypeReferenceId="value" DefaultValue="{OAUTH-KV:value}" AlwaysUseDefaultValue="true" />
        </OutputClaims>
        <SubjectNamingInfo ClaimType="sub" />
    </TechnicalProfile>
</RelyingParty>

调用后返回错误:

{
    "error": "invalid_grant",
    "error_description": "AADB2C90085: The service has encountered an internal error. Please reauthenticate and try again.\r\nCorrelation ID: 1c7b50fa-87bb-4588-8ec0-90e8ed3554be\r\nTimestamp: 2022-12-18 22:05:45Z\r\n"
}

我需要实现通过客户端凭据完成认证并传递自定义输入参数的功能,求解决方案。


解决方案

核心问题原因

在客户端凭据流中,RelyingParty的OpenIdConnect技术配置文件不支持直接使用{OAUTH-KV:}解析器,这会触发内部错误。另外,客户端凭据流的标准参数传递方式是表单体(x-www-form-urlencoded),而非URL查询字符串,这也会导致参数无法被正确捕获。

具体修复步骤

  1. 调整参数传递方式
    将自定义参数value放在请求的表单体中,修改后的请求示例:

    POST https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/B2C_1A_MyPolicy/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=client_credentials&client_id=<appId>&client_secret=<client_secret>&scope=https://{tenant}.onmicrosoft.com/api/.default&value=your_custom_value
    
  2. 修改参数解析器
    在SetQueryParams技术配置文件中,使用{OAUTH-BODY:}解析器读取表单体中的参数,替换原有的{OAUTH-KV:}:

    <OutputClaim ClaimTypeReferenceId="value" DefaultValue="{OAUTH-BODY:value}" AlwaysUseDefaultValue="true" />
    
  3. 恢复RelyingParty配置
    移除RelyingParty中value声明的默认值配置,保持仅引用声明:

    <OutputClaim ClaimTypeReferenceId="value" />
    

完整修复后的关键配置片段

  • SetQueryParams技术配置文件

    <TechnicalProfile Id="SetQueryParams">
        <DisplayName>Set custom parameters from request body</DisplayName>
        <Protocol Name="Proprietary" Handler="Web.TPEngine.Providers.ClaimsTransformationProtocolProvider, Web.TPEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        <Metadata>
            <Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
        </Metadata>
        <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="value" DefaultValue="{OAUTH-BODY:value}" AlwaysUseDefaultValue="true" />
        </OutputClaims>
        <UseTechnicalProfileForSessionManagement ReferenceId="SM-Noop" />
    </TechnicalProfile>
    
  • RelyingParty部分

    <RelyingParty>
        <DefaultUserJourney ReferenceId="MyUserJourney" />
        <UserJourneyBehaviors>
            <JourneyInsights TelemetryEngine="ApplicationInsights" InstrumentationKey="623badc9-900b-44e3-bd44-bf00d97d9d93" DeveloperMode="true" ClientEnabled="true" ServerEnabled="true" TelemetryVersion="1.0.0" />
            <ScriptExecution>Allow</ScriptExecution>
        </UserJourneyBehaviors>
        <TechnicalProfile Id="PolicyProfile">
            <DisplayName>PolicyProfile</DisplayName>
            <Protocol Name="OpenIdConnect" />
            <OutputClaims>
                <OutputClaim ClaimTypeReferenceId="objectId" PartnerClaimType="sub" AlwaysUseDefaultValue="true" DefaultValue="8186c7b3-adca-4c17-b318-939e9d8170b8" />
                <OutputClaim ClaimTypeReferenceId="value" />
            </OutputClaims>
            <SubjectNamingInfo ClaimType="sub" />
        </TechnicalProfile>
    </RelyingParty>
    

验证逻辑

  1. 部署修改后的自定义策略
  2. 使用表单体传递value参数的POST请求调用token端点
  3. 检查返回的JWT,确认value字段包含你传递的自定义值

内容的提问来源于stack exchange,提问作者Dessus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:01:08