AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79200791
Accepted
mohamed amine salah
mohamed amine salah
Asked: 2024-11-19 01:06:11 +0800 CST2024-11-19 01:06:11 +0800 CST 2024-11-19 01:06:11 +0800 CST

O nonce está faltando no id_token na resposta

  • 772

Estou usando o Keycloak 21 para autenticação e estou tendo um problema em que o valor nonce não está incluído no id_token retornado após eu invocar /token. Estou passando o nonce na solicitação /auth,

keycloak
  • 1 1 respostas
  • 30 Views

1 respostas

  • Voted
  1. Best Answer
    Bench Vue
    2024-11-19T11:06:50+08:002024-11-19T11:06:50+08:00

    Você pode obter por este método

    URL

    GET ${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth?
    

    query parameters

            client_id: CLIENT_ID,
            redirect_uri: REDIRECT_URI,
            response_type: 'code',
            scope: 'openid',
            nonce: nonce,
    

    Em seguida, obtenha o token de ID no URL de retorno de chamada

    Passos

    Etapa 1: iniciando o Keycloak v21 pelo docker compose

    version: '3.9'
    
    services:
      keycloak:
        image: quay.io/keycloak/keycloak:21.1.2
        container_name: keycloak
        command:
          - start-dev
        environment:
          KEYCLOAK_ADMIN: admin
          KEYCLOAK_ADMIN_PASSWORD: admin
          KC_DB: postgres
          KC_DB_URL_HOST: keycloak-db
          KC_DB_URL_DATABASE: keycloak
          KC_DB_USERNAME: keycloak
          KC_DB_PASSWORD: keycloakpassword
          KC_HOSTNAME: localhost
        ports:
          - "8080:8080"
        depends_on:
          - keycloak-db
        volumes:
          - keycloak-data:/opt/keycloak/data
    
      keycloak-db:
        image: postgres:15
        container_name: keycloak-db
        environment:
          POSTGRES_USER: keycloak
          POSTGRES_PASSWORD: keycloakpassword
          POSTGRES_DB: keycloak
        ports:
          - "5432:5432"
        volumes:
          - postgres-data:/var/lib/postgresql/data
    
    volumes:
      keycloak-data:
      postgres-data:
    

    mais detalhes aqui

    Etapa 2. crie my-realm, my-cleint e user1

    insira a descrição da imagem aqui

    URL de retorno de chamada

    http://localhost:3000/callback
    

    insira a descrição da imagem aqui

    Cópia do segredo do cliente da IU

    insira a descrição da imagem aqui

    usernameé User1 e passwordé 1234

    insira a descrição da imagem aqui

    insira a descrição da imagem aqui

    Etapa 3: executando o servidor expresso

    install dependencies

    npm install express axios querystring [email protected] crypto
    

    demo.js

    const express = require('express');
    const axios = require('axios');
    const crypto = require('crypto');
    const querystring = require('querystring');
    const jwtDecode = require('jwt-decode');
    
    const app = express();
    const PORT = 3000; //replace your Redirect PORT
    
    // Keycloak Configuration
    const KEYCLOAK_URL = 'http://localhost:8080'; // Replace with your Keycloak server URL
    const REALM = 'my-realm'; // Replace with your realm name
    const CLIENT_ID = 'my-client'; // Replace with your client ID
    const CLIENT_SECRET = '[your my-client password]'; // Replace if your client is confidential
    const REDIRECT_URI = 'http://localhost:3000/callback'; // Replace with your app's redirect URI
    
    // Generate a random nonce
    const generateNonce = () => crypto.randomBytes(16).toString('base64');
    
    // Store the nonce temporarily (use a proper session store in production)
    let storedNonce;
    
    // Routes
    
    // 1. Start Authorization
    app.get('/login', (req, res) => {
        const nonce = generateNonce();
        storedNonce = nonce; // Save the nonce for validation later
    
        const authUrl = `${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth?` + querystring.stringify({
            client_id: CLIENT_ID,
            redirect_uri: REDIRECT_URI,
            response_type: 'code',
            scope: 'openid',
            nonce: nonce,
        });
    
        res.redirect(authUrl); // Redirect user to Keycloak login
    });
    
    // Step 2. Handle Callback for get tokens
    app.get('/callback', async (req, res) => {
        const { code } = req.query;
    
        if (!code) {
            return res.status(400).send('Authorization code not found!');
        }
    
        try {
            const tokenResponse = await axios.post(
                `${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token`,
                querystring.stringify({
                    grant_type: 'authorization_code',
                    code: code,
                    redirect_uri: REDIRECT_URI,
                    client_id: CLIENT_ID,
                    client_secret: CLIENT_SECRET,
                }),
                { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
            );
    
            const { id_token } = tokenResponse.data;
    
            // Decode and validate the ID token
            const decodedToken = jwtDecode(id_token);
    
            if (decodedToken.nonce !== storedNonce) {
                return res.status(401).send('Invalid nonce!');
            }
    
            res.send({
                message: 'Login successful!',
                id_token: decodedToken,
            });
        } catch (error) {
            console.error('Error exchanging code for tokens:', error);
            res.status(500).send('Error exchanging code for tokens.');
        }
    });
    
    // Start the Express server
    app.listen(PORT, () => {
        console.log(`Server running at http://localhost:${PORT}`);
    });
    

    run it

    node demo.js
    

    insira a descrição da imagem aqui

    Etapa 4 Obtenha o token pelo navegador

    http://localhost:3000/login
    

    Resultado

    insira a descrição da imagem aqui

    • 1

relate perguntas

  • client-credentials é unsupported_grant_type

  • StackOverflow com Keycloak como provedor de login retorna endereço de e-mail vazio

  • Erro de troca de token Keycloak - O cliente não está dentro do público do token

  • Como listar usuários de contas de serviço no keycloak

  • Criar usuário via API no KeyCloak sem admin-cli?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve