通过Azure AD B2C自定义策略尝试登录时,Discord api返回未经授权的401

时间:2018-08-11 12:08:38

标签: xml azure oauth-2.0 discord azure-ad-b2c

我正在构建一个使用Discord OAuth2达到各种目的(包括用户身份)的应用程序,但是遇到一个问题,当用户尝试登录时Discord api返回401(未经授权)错误。

我有一个B2C租户,该租户的自定义策略包含ClaimsProbider,写为:

  <ClaimsProvider>
      <!-- The following Domain element allows this profile to be used if the request comes with domain_hint 
           query string parameter, e.g. domain_hint=Discord.com  -->
      <Domain>Discord.com</Domain>
      <DisplayName>Discord</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="Discord-OAUTH">
          <!-- The text in the following DisplayName element is shown to the user on the claims provider 
               selection screen. -->
          <DisplayName>Discord</DisplayName>
          <Protocol Name="OAuth2" />
          <Metadata>
            <Item Key="ProviderName">Discord</Item>
            <Item Key="authorization_endpoint">https://discordapp.com/api/oauth2/authorize</Item>
            <Item Key="AccessTokenEndpoint">https://discordapp.com/api/oauth2/token</Item>
            <Item Key="ClaimsEndpoint">https://discordapp.com/api/users/@me</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">0</Item>
            <Item Key="client_id">[my key]</Item>
            <Item Key="scope">identify email connections guilds.join rpc rpc.api rpc.notifications.read messages.read</Item>
            <Item Key="AccessTokenResponseFormat">json</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="B2C_1A_DiscordSecret" />
          </CryptographicKeys>
          <InputClaims />
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="socialIdpUserId" DefaultValue="id" />
            <OutputClaim ClaimTypeReferenceId="givenName" DefaultValue="first_name" />
            <OutputClaim ClaimTypeReferenceId="surname" DefaultValue="last_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" DefaultValue="name" />
            <OutputClaim ClaimTypeReferenceId="email" DefaultValue="email"/>
            <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="Discord.com" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>

我通过Application Insights收集的错误是:

{
    ""Kind"": ""HandlerResult"",
    ""Content"": {
      ""Result"": true,
      ""RecorderRecord"": {
        ""Values"": [
          {
            ""Key"": ""SendErrorTechnicalProfile"",
            ""Value"": ""OAuth2ProtocolProvider""
          },
          {
            ""Key"": ""Exception"",
            ""Value"": {
              ""Kind"": ""Handled"",
              ""HResult"": ""80131500"",
              ""Message"": ""An exception was caught when making a request to URL \""https://discordapp.com/api/users/@me\"" using method \""Get\"". The exception status code was \""ProtocolError\"" with the following message: {scrubbed}."",
              ""Data"": {},
              ""Exception"": {
                ""Kind"": ""Handled"",
                ""HResult"": ""80131509"",
                ""Message"": ""The remote server returned an error: (401) Unauthorized."",
                ""Data"": {}
              }
            }
          }
        ]
      }
    }

Here是一种避免在请求api索赔时获得401的解决方案,但是我不确定使用B2C租户的自定义策略在这种情况下该方法如何工作。

有人可以对此问题提出建议吗?

1 个答案:

答案 0 :(得分:2)

Discord API要求在Authorization HTTP标头中发送访问令牌。

默认情况下,Azure AD B2C在查询字符串中发送访问令牌,因此必须将 BearerTokenTransmissionMethod 元数据项添加到技术配置文件中:

<TechnicalProfile Id="Discord-OAUTH">
  <Metadata>
    <Item Key="BearerTokenTransmissionMethod">AuthorizationHeader</Item>
  </Metadata>
</TechnicalProfile>