2017-05-22 2 views
0

J'ai mis en place un serveur keycloak et je développe une API qui sera disponible sur internet. L'API recevra des appels de tiers (clients). Ces clients appellent d'abord le serveur keycloak avec un clientId et un secret afin d'obtenir le jeton, puis ils appellent mon API avec ce jeton.Obtenir l'utilisateur et valider le jeton JWT en vert.x

J'ai besoin de voir comment je peux analyser et valider ce jeton. Ce jeton sera probablement un JWT. Ainsi, dans mon cas de test, j'ai une requête http ayant un jeton Web json dans l'en-tête. Le jeton est fourni par keycloak lancé dans localhost. Je l'ai copié tout le jeton:

{"Authorization":"Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGSjg2R2NGM2pUYk5MT2NvNE52WmtVQ0lVbWZZQ3FvcXRPUWVNZmJoTmxFIn0.eyJqdGkiOiI2YWZlZjBiMC03ZmQ1LTRiOWUtOTk3NC0yOGFjMzBkMGM5OWQiLCJleHAiOjE0OTU2MTA0NTQsIm5iZiI6MCwiaWF0IjoxNDk1NjEwMTU0LCJpc3MiOiJodHRwOi8vMTI3LjAuMC4xOjgxMDAvYXV0aC9yZWFsbXMvZXhhbXBsZSIsImF1ZCI6ImpzLWNvbnNvbGUiLCJzdWIiOiJjNGY4NjE0Zi02YjFlLTRlYjItYmYxZC0wOTJmNGYxNWQwYmIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJqcy1jb25zb2xlIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiNTQ4NDJjNTgtMzYxYi00MDk2LThhNjgtNGZkZTg5OGUwNzg5IiwiYWNyIjoiMSIsImNsaWVudF9zZXNzaW9uIjoiNDNjMWEzMjAtNGZmNi00NmRmLThmZjUtNTU2ZjgxNGZhYzk1IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbInVzZXIiXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiU2FtcGxlIFVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyIiwiZ2l2ZW5fbmFtZSI6IlNhbXBsZSIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoic2FtcGxlLXVzZXJAZXhhbXBsZSJ9.n1K0KIGYJYPZkjSq1eSg5gWnCAj44mgl4M-GJOlzgCj8y5TGw5OhT7sr84o9Ja9K6WMW3t0ti6feZIgc8mps3RK0HuuXeCNcrN6H2dPEtBphTvfXEUR2iMg83iCmxjhXgXso7oX2vyreJqB6WCCFEPbAQH2e5kHZqv6cfmXRlYU"} 

Je veux:

  • Parse le jeton
  • Obtenez les paires clé/valeur que je dois
  • Valider le jeton dans le serveur keycloak.

L'objectif est de protéger les services de repos et d'accorder l'accès à des rôles spécifiques. Mon application est un 3.4.1 vert.x avec des routes.

Ce que j'est maintenant un exemple que je trouve qui établit un JWTAuthHandler

JWTAuth authProvider = JWTAuth.create(vertx, config().getJsonObject("keycloak.oidc")); 
    router.route("/protected/*").handler(JWTAuthHandler.create(authProvider)); 

    router.route("/protected/somepage").handler(ctx -> { 
     logger.info("Headers: {}", ctx.request().headers().get("Authorization")); 
     logger.info(ctx.user().principal().encodePrettily()); 
    }); 

configuration Keycloak pour l'appel de mon API (utilisé pour JWTAuth):

"keycloak.oidc": { 
    "realm": "myrealm", 
    "auth-server-url": "http://localhost:8100/auth", 
    "ssl-required": "none", 
    "resource": "app-client", 
    "public-client": true 
} 

Quand je fais la repos appel dans le facteur, le jvm ne parvient pas vraiment à entrer dans le gestionnaire et de se connecter les en-têtes bien, il jette cette exception immédiatement en disant io.vertx.ext.web.handler.impl.JWTAuthHandlerImpl AVERTISSEMENT: JWT decode failure java.lang.RuntimeException: Not enough or too many segments

+0

L'erreur que vous obtenez est vous dire que le jeton que vous avez reçu est pas un JWT valide, car un JWT nécessite au moins 2 segments. Pour plus de détails sur les segments, voir: https://jwt.io/ car cela vous donne un bon retour visuel sur son fonctionnement. Je suppose que vous obtenez autre chose qu'un JWT –

+0

Le tableau de segments String [] se compose de 3 segments (je suis en mode débogage). J'ai également vérifié cela sur jwt.io. Je ne sais pas ce qui ne va pas. – Grandmaster

+0

Ai-je besoin d'ajouter un certificat ou une clé publique/privée à l'appel? Pour l'instant, dans mon API, j'appelle keycloak avec cette configuration client: ' "keycloak.oidc": { \t \t "royaume": "mondomaine", \t \t "auth-server-url": « http:// localhost: 8100/auth », \t \t "ssl-requis": "none", \t \t "ressource": "app-client", \t \t "client public": true \t}' – Grandmaster

Répondre

0

J'ai jeté un coup d'oeil dans le code source de JWTAuthProviderImpl et j'ai réalisé que je dois fournir la clé publique dans la config.Donc, je viens d'ajouter à mon config keycloak:

"public-key": "MypublickeyblablablavOCAQ8AMvdsvseee" 
2

Si je comprends bien, vous avez une API qui fait une demande avec un JWT dans les en-têtes.

Dans ce cas, vous ne devez pas utiliser le gestionnaire OAuth2 mais le J WT handler. Ce gestionnaire peut être utilisé avec read only tokens de keycloak.

Il est important de savoir que, comme avec tout autre gestionnaire Auth, si la requête réussit la validation, vous obtiendrez un objet User. Cet objet peut être utilisé pour exécuter authorization assertions. Ou si vous êtes intéressé par la représentation JSON d'origine du jeton que vous pouvez le lire comme:

JsonObject token = context.user().principal();

Et vous pouvez y inspecter comme vous le souhaitez.

+0

J'ai mis en place un serveur keycloak et je développe l'API. Je vais recevoir des appels de tiers. Ces tiers appellent d'abord le serveur keycloak pour obtenir le jeton, puis ils appellent mon API avec le jeton. J'ai besoin de voir comment je peux analyser et valider ce jeton – Grandmaster

+0

Grâce à votre code, j'ai modifié mon code à ceci: 'JWTAuth authProvider = JWTAuth.create (vertx, config(). GetJsonObject (" keycloak.oidc ")); Router.route ("/ protected/*"). Gestionnaire (JWTAuthHandler.create (authProvider)); \t \t . \t \t \t \t router.route ("/ protected/UnePage") gestionnaire (ctx -> { \t \t \t \t chaîne theSubject = ctx.user() principale() getString ("sub");.. . \t \t \t Chaîne someKey = ctx.user() principal() getString (le "someKey"). \t \t}); ' ctx.user() est nulle dans mon cas Comment puis-je obtenir les données décodées de le JWT trouvé dans l'en-tête comme je l'ai mentionné ci-dessus? – Grandmaster

+0

Je crois que vous devriez fournir un exemple montrant votre code. Étant donné que votre gestionnaire est exécuté, l'utilisateur ne devrait pas être nul puisqu'il devrait contenir le contenu du jeton. –