Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Public client + authentication code flow with PKCE does not work in Azure AD B2C #4706

Closed
hiko1ron opened this issue Jun 13, 2022 · 3 comments
Labels
question Ask how to do something or how something works

Comments

@hiko1ron
Copy link

Question 💬

Hi, everyone!
Thank you for nice software.

When I try to authenticate with NextAuth.js + Azure AD B2C, it returns a callback error as an invalid request which said
Public clients should not send a client_secret when redeeming a publicly acquired grant.
I guess this problem is Authorization Header is given when the public client request to grant against token endpoint.
Is there any way around this?

AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.

frontend_1  | [next-auth][error][OAUTH_CALLBACK_ERROR]
frontend_1  | https://next-auth.js.org/errors#oauth_callback_error invalid_request (AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.
frontend_1  | Correlation ID: 75054f2b-52bf-486b-aa98-0eaba13f4621
frontend_1  | Timestamp: 2022-06-13 04:19:16Z
frontend_1  | ) {
frontend_1  |   error: {
frontend_1  |     message: 'invalid_request (AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.\r\n' +
frontend_1  |       'Correlation ID: 75054f2b-52bf-486b-aa98-0eaba13f4621\r\n' +
frontend_1  |       'Timestamp: 2022-06-13 04:19:16Z\r\n' +
frontend_1  |       ')',
frontend_1  |     stack: 'OPError: invalid_request (AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.\r\n' +
frontend_1  |       'Correlation ID: 75054f2b-52bf-486b-aa98-0eaba13f4621\r\n' +
frontend_1  |       'Timestamp: 2022-06-13 04:19:16Z\r\n' +
frontend_1  |       ')\n' +
frontend_1  |       '    at processResponse (/app/node_modules/openid-client/lib/helpers/process_response.js:38:13)\n' +
frontend_1  |       '    at Client.grant (/app/node_modules/openid-client/lib/client.js:1347:22)\n' +
frontend_1  |       '    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n' +
frontend_1  |       '    at async Client.callback (/app/node_modules/openid-client/lib/client.js:474:24)\n' +
frontend_1  |       '    at async oAuthCallback (/app/node_modules/next-auth/core/lib/oauth/callback.js:112:16)\n' +
frontend_1  |       '    at async Object.callback (/app/node_modules/next-auth/core/routes/callback.js:50:11)\n' +
frontend_1  |       '    at async NextAuthHandler (/app/node_modules/next-auth/core/index.js:139:28)\n' +
frontend_1  |       '    at async NextAuthNextHandler (/app/node_modules/next-auth/next/index.js:21:19)\n' +
frontend_1  |       '    at async /app/node_modules/next-auth/next/index.js:57:32\n' +
frontend_1  |       '    at async Object.apiResolver (/app/node_modules/next/dist/server/api-utils/node.js:185:9)',
frontend_1  |     name: 'OPError'
frontend_1  |   },
frontend_1  |   providerId: 'azure-ad-b2c',
frontend_1  |   message: 'invalid_request (AADB2C90084: Public clients should not send a client_secret when redeeming a publicly acquired grant.\r\n' +
frontend_1  |     'Correlation ID: 75054f2b-52bf-486b-aa98-0eaba13f4621\r\n' +
frontend_1  |     'Timestamp: 2022-06-13 04:19:16Z\r\n' +
frontend_1  |     ')'
frontend_1  | }

I tried to find out where this cause was, then I read code followed these error stacks.

So, I tried to assign ‘none’ for ‘token_endpoint_auth_method’ when client request to grant against token endpoint.
But, it couldn’t assign ‘none’ for ‘token_endpoint_auth_method’ by NextAuth.js (and openid-client) and ‘client_secret_post’ was assigned forcibly if this method isn't included by 'token_endpoint_auth_methods_supported' which returned by well-known endpoint. code is here.
I confirmed well-known endpoint of Azure AD B2C allows ‘client_secret_basic’ and ‘client_secret_post’ only. ('none' is not included.)

By the way, It was processed successfully when I changed the code of ‘openid-client’ forcibly without Authentication Header.
It looks like an openid-client issue (or composite issue) to me but I don't know it is correct because I am not an expertise of this issue.
Please let me know if I am using something incorrectly or misunderstanding something.

How to reproduce ☕️

This occurs during callback after successful sign-in on the Azure AD B2C.

Libraries

  • node 16.15.1
  • next 12.1.6
  • next-auth 4.3.4

Azure AD B2C Settings

  • Allow public client flows: Yes
  • Platform configurations: Single-page application
  • Redirect URI: http://localhost:3000/api/auth/callback/azure-ad-b2c

src/pages/index.tsx

import { useSession, signIn, signOut } from "next-auth/react";

export default function Index() {
  const { data: session } = useSession();
  if(session) {
    return <>
      Signed in as {session.user.email} <br/>
      <button onClick={() => signOut()}>sign out</button>
    </>;
  }
  return <>
    Not signed in <br/>
    <button onClick={() => signIn()}>sign in</button>
  </>;
};

src/pages/api/auth/[...nextauth].ts

import AzureADB2CProvider from "next-auth/providers/azure-ad-b2c";

export default NextAuth({
  providers: [
...
    AzureADB2CProvider({
      tenantId: process.env.AZURE_AD_B2C_TENANT_NAME,
      clientId: process.env.AZURE_AD_B2C_CLIENT_ID,
      clientSecret: process.env.AZURE_AD_B2C_CLIENT_SECRET,
      primaryUserFlow: process.env.AZURE_AD_B2C_PRIMARY_USER_FLOW,
      authorization: { params: { scope: "offline_access openid" },  },
      checks: ["pkce"]
    }),
...
  ],
};

next.config.js

const nextConfig = {
  reactStrictMode: true,
  env: {
    AZURE_AD_B2C_TENANT_NAME: process.env.AZURE_AD_B2C_TENANT_NAME,
    AZURE_AD_B2C_CLIENT_ID: process.env.AZURE_AD_B2C_CLIENT_ID,
    AZURE_AD_B2C_CLIENT_SECRET: process.env.AZURE_AD_B2C_CLIENT_SECRET,
    AZURE_AD_B2C_PRIMARY_USER_FLOW: process.env.AZURE_AD_B2C_PRIMARY_USER_FLOW,
  }
};
module.exports = nextConfig;

** .env.local

  • set appropriate environment variables

Contributing 🙌🏽

No, I am afraid I cannot help regarding this

@hiko1ron hiko1ron added the question Ask how to do something or how something works label Jun 13, 2022
@balazsorban44
Copy link
Member

openid-client configuration options are exposed to you, if you need to change the defaults. See: https://next-auth.js.org/configuration/providers/oauth#client-option

@jvtroyen
Copy link

jvtroyen commented Jun 13, 2022

I had the exact same problem this morning and was kinda waiting for what possible replies would come here.

It did end up working for me by changing as you said the setting client.token_endpoint_auth_method to 'none'.
I assume it heavily depends on the Azure AD configuration. In my case I have no access to it and cannot change anything, but they do apprently support 'none'.

  providers: [
...
    AzureADB2CProvider({
      tenantId: process.env.AZURE_AD_B2C_TENANT_NAME,
      clientId: process.env.AZURE_AD_B2C_CLIENT_ID,
      clientSecret: process.env.AZURE_AD_B2C_CLIENT_SECRET,
      primaryUserFlow: process.env.AZURE_AD_B2C_PRIMARY_USER_FLOW,
      authorization: {params: {scope: 'offline_access openid'}},              
      
      checks: ["pkce"],
      client: {
        token_endpoint_auth_method: 'none'
      },
    }),    
...
  ],

@hiko1ron
Copy link
Author

@balazsorban44
Thank you for your answer. 🙇‍♂️
I changed the parameters based on the link you provided and it works! 🚀

@jvtroyen
Thanks. It worked with exactly the same parameters you described. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Ask how to do something or how something works
Projects
None yet
Development

No branches or pull requests

3 participants