Search code examples
graphqljwtkeycloakmicronaut

How to use Keycloak JWT for authentication in Micronaut GraphQL


I'm trying to use Micronaut GraphQL using keycloak JWT. I was able to get things working with Basic Auth, trying to move over to bearer token instead, and I'm missing something, as I always get a 401 Unauthorized, but I'm not seeing any useful error messages in the log, even with the logging set to TRACE

Using Micronaut 3.0.0.

My application.yml looks like this:

micronaut:
  application:
    name: myapp
  server:
    cors:
      enabled: true
    port: 8080
  security:
    authentication: bearer
    intercept-url-map:
      - pattern: /graphiql
        access:
          - isAnonymous()
      - pattern: /graphql
        access:
          - isAuthenticated()
    endpoints:
      login:
        enabled: false
    token:
      jwt:
        enabled: true
        signatures:
          jwks:
            keycloak:
              url: http://xx.xx.xx.xx:8090/auth/realms/myrealm/protocol/openid-connect/certs
    oauth2.clients.keycloak:
      grant-type: password
      client-id: myapp-backend
      client-secret: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      authorization:
        url:  http://xx.xx.xx.xx:8090/auth/realms/myrealm/protocol/openid-connect/auth
custom:
  keycloak:
    url: http://xx.xx.xx.xx:8090

graphql:
  enabled: true
  path: /graphql
  graphiql:
    enabled: true
    path: /graphiql

here is what I'm posting to test:

curl --location --request POST 'localhost:8080/graphql' \
--header 'Authorization: Bearer {exceptionally long jwt token}' \
--header 'Content-Type: application/json' \
--data-raw '{"query":"query test { scenarios { id } }","operationName":"test"}'

I'm not sure what else would be useful to provide. Any thoughts?


Solution

  • After more searching and stepping through in the debugger, I was able to finally determine that I had mistyped my realm name.

    However, for posterity, here is the minimal configuration that I needed to run:

    micronaut:
      application:
        name: myapplication
      server:
        cors:
          enabled: true
        port: 8080
      security:
        enabled: true
        authentication: bearer
        intercept-url-map:
          - pattern: /graphiql
            access:
              - isAnonymous()
          - pattern: /graphql
            access:
              - isAuthenticated()
        endpoints:
          login:
            enabled: false
        token:
          jwt:
            enabled: true
            signatures:
              jwks:
                keycloak:
                  url: http://xx.xx.xx.xx:8090/auth/realms/MyRealm/protocol/openid-connect/certs
        oauth2.clients.keycloak:
          grant-type: password
          client-id: myapp-backend
          client-secret: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
          authorization:
            url: http://xx.xx.xx.xx:8090/auth/realms/MyRealm/protocol/openid-connect/auth
    
    custom:
      keycloak:
        url: http://xx.xx.xx.xx:8090/auth/realms/MyRealm
    
    graphql:
      enabled: true
      graphiql.enabled: true
      graphql-ws.enabled: true