keycloak, Apache, mod_auth_openidc, elasticsearch opendistro

1.1k views Asked by At

I'm trying to setup single sign-on (SSO) for accessing private directory on apache 2.4 and assign role in elasticsearch (opendistro) for keycloak logged user. No real problem assigning role to user in keycloak (and succeed to connect to openldap server too). If I send Bearer token to ES, it links roles to backend roles. everything greet.

problem is that elasticsearch is stateless and it seems , it doesn't read cookie obtained from keycloak and mod_auth_openidc (couldnt succeed setup config.xml correctly). So, I could not get ES to work with opendid connect session.

So, I decided to opt for Bearer Authentication for ES and I need to add Bearer http header in each http request to ES.

I get a Bearer token from mod_auth_openidc by adding :

Header set Authorization "Bearer %{OIDC_access_token}e" env=OIDC_access_token

to my protected Location in the apache conf (enabled headers module). But when I try to use that token with curl (for testing) , it wont work

 curl -i -k --noproxy '*' -H "Authorization: thebearerfromapache" https://es.*****.com:9200/protectedresources 

I get 401 Unauthorized. ElasticSearch log :

[2020-11-22T14:58:58,404][DEBUG][c.a.o.s.a.BackendRegistry] [node-1] Check authdomain for rest noop/0 or 2 in total
[2020-11-22T14:58:58,405][DEBUG][c.a.o.s.a.BackendRegistry] [node-1] 'java.lang.IllegalArgumentException: No enum constant org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm.R{"alg":"RS256","typ" : "JWT","kid" : "BHQ5Qu3GJKSAUYKPy3itq5oZLmmrAD_eFdZQa88oX8c' extracting credentials from jwt-key-by-oidc http authenticator
java.lang.IllegalArgumentException: No enum constant org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm.R{"alg":"RS256","typ" : "JWT","kid" : "BHQ5Qu3GJKSAUYKPy3itq5oZLmmrAD_eFdZQa88oX8c
        at java.lang.Enum.valueOf(Enum.java:273) ~[?:?]

Edit: I changed algorithm for access token in keycloak to HS256, now I get

[2020-11-22T15:27:31,195][INFO ][c.a.d.a.h.j.k.JwtVerifier] [node-1] Escaped Key ID from JWT Token
[2020-11-22T15:27:31,196][DEBUG][c.a.d.a.h.j.k.SelfRefreshingKeySet] [node-1] performRefresh(c3145a71-0a3c-4b99-86e0-a8bf30c33f23)
[2020-11-22T15:27:31,197][INFO ][c.a.d.a.h.j.k.SelfRefreshingKeySet] [node-1] Performing refresh 1
[2020-11-22T15:27:31,450][INFO ][c.a.d.a.h.j.k.SelfRefreshingKeySet] [node-1] KeySetProvider finished
[2020-11-22T15:27:31,452][INFO ][c.a.d.a.h.j.AbstractHTTPJwtAuthenticator] [node-1] Extracting JWT token from eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjMzE0NWE3MS0wYTNjLTRiOTktODZlMC1hOGJmMzBjMzNmMjMifQ.eyJleHAiOjE2MDYwNTkwMzEsImlhdCI6MTYwNjA1ODczMSwiYXV0aF90aW1lIjoxNjA2MDU4NzMxLCJqdGkiOiI2MzFjYmIyZS1hODhjLTQwZmItYjU1My1lYzM0YmI2NTQ5YzEiLCJpc3MiOiJodHRwczovL2F1dGguc2VhcmNoZXZvbHV0aW9uLmNvbTo4NDQzL2F1dGgvcmVhbG1zL3dlYiIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiJkNDgxNTE5OS0zZTExLTQyOTktYmY3My1jZGUzYmI3MDMwM2UiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhcGFjaGUtbm9kZTEiLCJub25jZSI6IjFwd3lQUUpOZlhFOTlTaTVNbjF2NGd2MXBtdkZQdWtqZEpYS3pnd3RiM0EiLCJzZXNzaW9uX3N0YXRlIjoiOGZjMTk0ZDQtMjY2Yy00ZTc0LWE0MGQtNmFjOGY0ZDU2NDEyIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIiLCJodHRwczovL25vZGUxLnNlYXJjaGV2b2x1dGlvbi5jb20vIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsImhyIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsImhyIiwidW1hX2F1dGhvcml6YXRpb24iXSwibmFtZSI6IkpvaG4gRG9lIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiamRvZSIsImdpdmVuX25hbWUiOiJKb2huIiwiZmFtaWx5X25hbWUiOiJEb2UifQ.dpX_F5r-KqSYr7atK7K9B3FzJ9VbDiIdqmhYBMsHyV0 failed
com.amazon.dlic.auth.http.jwt.keybyoidc.BadCredentialsException: Unknown kid c3145a71-0a3c-4b99-86e0-a8bf30c33f23

this shell script works:

RESULT=`curl -k --noproxy '*' -d 'client_id=apache-node1' -d 'username=jdoe' -d 'password=*****' -d 'grant_type=password' -d 'client_secret=6a7a0299-e420-4206-ae02-9e68bf7044ff' -d 'scope=openid' 
'https://auth.****.com:8443/auth/realms/web/protocol/openid-connect/token'`

TOKEN=`echo $RESULT | sed 's/.*access_token":"\([^"]*\).*/\1/'`

curl -i -k --noproxy '*' -H "Authorization: Bearer $TOKEN" https://es.****.com:9200/humanresources/_search

opendistro security plugin config:

 jwt_auth_domain:
        description: "Authenticate via Json Web Token"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: openid
          challenge: false
          config:
            jwt_header: Authorization
            subject_key: preferred_username
            roles_key: roles
            openid_connect_url: https://auth.****.com:8443/auth/realms/web/.well-known/openid-configuration

            jwks_uri: https://auth.****.com:8443/auth/realms/web/protocol/openid-connect/certs
        authentication_backend:
          type: noop

Any Ideas how to setup elasticsearch to recognize that token?

1

There are 1 answers

0
Germain On

Finally, the correct apache config was to include the ID token (not the access token)

so,

 Header set Authorization "Bearer %{OIDC_id_token}e" env=OIDC_id_token

and in the global configuration of the virtualhost (else the id token not added in the http headers)

OIDCPassIDTokenAs serialized

and I used "ES256" in keycloak administration: Fine Grain OpenID Connect Configuration ID Token Signature Algorithm