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

How to get Keycloak's roles? #4811

Closed
heitorvrb opened this issue Jul 1, 2022 · 4 comments
Closed

How to get Keycloak's roles? #4811

heitorvrb opened this issue Jul 1, 2022 · 4 comments
Labels
question Ask how to do something or how something works

Comments

@heitorvrb
Copy link

Question 💬

How to get keycloak's user roles in next-auth?

I need to check if the user has a certain role to allow/deny him access to certain pages. You can normally do this by checking the realmAccess.roles object inside keycloak's token, something like this:

const admin = token.realmAccess.roles.includes('admin');

But next-auth's Keycloak token doesn't seem to have a realmAccess object.

How can I get the roles Keycloak has set for my logged in user?

How to reproduce ☕️

import KeycloakProvider from "next-auth/providers/keycloak";
//...
providers: [
  KeycloakProvider({
    clientId: process.env.KEYCLOAK_ID,
    clientSecret: process.env.KEYCLOAK_SECRET,
    issuer: process.env.KEYCLOAK_ISSUER,
  })
],
callbacks: {
    async jwt({ token }) {
      // token does not have a realmAccess object defined
      return token
    },
  },
//...

Contributing 🙌🏽

No, I am afraid I cannot help regarding this

@heitorvrb heitorvrb added the question Ask how to do something or how something works label Jul 1, 2022
@balazsorban44
Copy link
Member

It's likely on account or profile. token is basically empty for the first time, see how to persist more information: https://next-auth.js.org/configuration/callbacks#jwt-callback

@fabpico
Copy link

fabpico commented Aug 5, 2024

It's likely on account or profile. token is basically empty for the first time, see how to persist more information: https://next-auth.js.org/configuration/callbacks#jwt-callback

I did the following, still can't be found, even though a user is logged in with an assigned role:

    callbacks: {
        jwt({token, account, profile, user}) {
            console.log(token)
            console.log(account)
            console.log(profile)
            console.log(user)
            let decodedIDToken = jwt.decode(token?.id_token)
            console.log(decodedIDToken)
            // ..
            return token
        },
    },

Reopen?

@AienTech
Copy link

AienTech commented Dec 5, 2024

@fabpico have you checked whether the information you're looking for is getting mapped in the token in the first place? Usually, roles won't be mapped by keycloak unless explicitly enabled.

@MichalNemec
Copy link

callbacks: {
    async jwt({ token, user, account, profile }: any) {
      let roles = undefined as
        | { [key: string]: { roles: Array<any> } }
        | undefined;

      if (account?.access_token) {
        let decodedToken = jwt.decode(account?.access_token);
        if (decodedToken && typeof decodedToken !== "string") {
          roles = decodedToken?.client_roles;
        }
      }
      var tokenCustom = { ...token, roles: roles };
      console.log("[jwt callback] token " + JSON.stringify(tokenCustom));
      return tokenCustom;
    },
    session: async ({ session, token, user }) => {
      if (session?.user) {
        console.log("[session callback] token " + JSON.stringify(token));
        return {
          ...session,
          user: {
            ...session.user,
            id: token.sub!,
            roles: token.roles,
          },
        };
      }

      return session;
    },
    async redirect({ url, baseUrl }) {
      return baseUrl;
    },
  },
[jwt callback] token {"name":"xx","email":"[email protected]","sub":"eb806f79-db1c-4f8d-8f59-3dfaf26b6324","roles":["developer","support","maintainer"]}
[jwt callback] token {"name":"xx","email":"[email protected]","sub":"eb806f79-db1c-4f8d-8f59-3dfaf26b6324","iat":1736564064,"exp":1739156064,"jti":"ed36bf38-d114-458e-bc40-7bcbc9cc2dc7"}
[session callback] token {"name":"xx","email":"[email protected]","sub":"eb806f79-db1c-4f8d-8f59-3dfaf26b6324","iat":1736564064,"exp":1739156064,"jti":"ed36bf38-d114-458e-bc40-7bcbc9cc2dc7"}

as you can see, first callback has roles properly, then its gone and session does not store it, can someone please help with this?

I thought that auth.js would have already roles property and i wouldnt have to deal with this.

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

5 participants