Forbidden 403 when trying to use jwt in kibana

I am trying to set up readonlyrest to read a jwt and give access to kibana based on this, but I can’t get it working. I am new to using jwt and ror so it is probably just me who have configured somthing wrong.

My setup
OS: centos-release-7-6.1810.2.el7.centos.x86_64
Elasticsearch version: 6.5.4
ROR version: readonlyrest-1.16.33_es6.5.4
Kibana is behind a reverse proxy called webseal. This will send a header called jwt containing a jwt with the username and kibana roles.

Decrypting the jwt using jwt.io it looks like this:

{
  "sub": "user123",
  "iss": "https://www.example.com",
  "aud": "urn:liberty",
  "iat": 1549282285,
  "exp": 1549285885,
  "sess": "faf6d1e0-2875-11e9-a92b-005056826ed8",
  "groups": [
    "kibana_admin"
  ]
}

The algorithm is RS256. The username is given in the soub field and roles in the groups field.

Config Elasticsearch
The only line I added to elasticsearch.yml is:

xpack.security.enabled: false

Kibana Config

xpack.graph.enabled: false
xpack.ml.enabled: false
xpack.monitoring.enabled: true
xpack.security.enabled: false
xpack.watcher.enabled: false

readonlyrest_kbn.jwt_query_param: "jwt"

ROR Configuration

readonlyrest:
    access_control_rules:
    - name: "::KIBANA-SRV::"
      auth_key: kibana:kibana

    - name: adminuser
      kibana_access: admin
      jwt_auth:
        name: "webseal"
        roles: ["kibana_admin"]

    jwt:
    - name: webseal
      signature_algo: RSA
      signature_key: "lots of text"
      user_claim: sub
      roles_claim: groups
      header_name: jwt

I got a certificare from my collegue who set up the jwt stuff in webseal. Which has the following layout:

-----BEGIN CERTIFICATE-----
"lots of text"
-----END CERTIFICATE-----

I pasted this in the public certificate section on jwt.io and it then says “signature verified” so this should be correct. I removed the header and footer and specified “lots of text” in one line in readonlyrest.yml (where lots of text is a long string). Does that make sense? And is this the correct way of specifying the key?

I get the following lines in the log if I try to go to the login-page and specify the jwt in the url like

http://mydomain:5601/login?jwt=eyJraWQiOiJkTmZscXUtU2pyLUgzbVZsU0IwSHIwSHFTQ3dhSFN0cHRxd2RyYTdqRk8wIiwiYWxnIjoi
UlMyNTYifQ.eyJzdWIiOiJHMDE5NDk2IiwiaXNzIjoiaHR0cHM6Ly93d3cuZ2plbnNpZGlnZS5ubyIsI
mF1ZCI6InVybjpsaWJlcnR5IiwiaWF0IjoxNTQ5MjgyMjg1LCJleHAiOjE1NDkyODU4ODUsInNlc3MiO
iJmYWY2ZDFlMC0yODc1LTExZTktYTkyYi0wMDUwNTY4MjZlZDgiLCJncm91cHMiOlsia2liYW5hX2Fkb
WluIl19.0xWeBXE8qryVTh9x615j3zyA0CdipsxT2XO4x8G2XBSWPNuaVAA7MI70U8Aa24KSXRJ3fkgu
BNaoYXXth96HnDdmJA3aQtjRV-K1BAWLkymvGRUDjCBBcHOey33Jdogxbf13dV6Yog_1agRe5nxtByxC
qiWcPmW9T9JHibRuf6jyMj2uTG7OTaMn5Th0hqGnyBzg4Omb-_sYco3OWWgvonRg3-iR0LfUtuuwI6il
u-y0A64kGU6K7YkOZ6MmpPLRiYoP8pWugZ358nzB2cu5I-vlFL1eX1c9VOspOlvywxyyWrS-zvjWorWn
CSHxjwi1bzwb3Da6yaWDhatxfafC0861LK35qtcEwoPKPOO4s70WgYI-84LxW6XVYRwSHmNou_zeDtKP
V_gIPB_Hr8KrIo4XqkMf7aFoXDbwXdBWs5UnH7RymSBmsbYljajv0wChd6J1O6_rMReLJexQG-lAK9lt
q64XgbAGuvlm6fnRBHPy53GXjJ_oH0vMDdbJOAzd-TWuRA33z_R7P5TKhRt7vy7BcRVxkji4HTNJfIFU
j3VJqtYGbpRCoAPnkQnMa_f6CFoZG2zMTnjRIiKVgga3xQmRJ0ojXgU80lIoF_XlpwDA4rDnwPMOAWwI
v55jOMd0WLTtK_cqC0pkrlaSdPAUZCoeAsVSorBHbBDG8Qf_Z9o

Log lines:

[2019-02-04T14:54:23,313][INFO ][t.b.r.a.ACL              ] [NpgnpOt] FORBIDDEN by default req={ ID:1671278147-1488510072#9219, TYP:RRAdminRequest, CGR:N/A, USR:[no basic auth header], BRS:false, KDX:null, ACT:cluster:admin/rradmin/refreshsettings, OA:127.0.0.1, DA:0.0.0.0, IDX:<N/A>, MET:GET, PTH:/_readonlyrest/metadata/current_user, CNT:<N/A>, HDR:{authorization=<OMITTED>, Connection=close, content-length=0, Host=localhost:9200}, HIS:[::KIBANA-SRV::->[auth_key->false]], [testuser->[auth_key->false]], [adminuser->[jwt_auth->false]] }
[2019-02-04T14:54:23,726][INFO ][t.b.r.a.ACL              ] [NpgnpOt] FORBIDDEN by default req={ ID:61335931-1085115413#9221, TYP:RRAdminRequest, CGR:N/A, USR:[no basic auth header], BRS:false, KDX:null, ACT:cluster:admin/rradmin/refreshsettings, OA:127.0.0.1, DA:0.0.0.0, IDX:<N/A>, MET:GET, PTH:/_readonlyrest/metadata/current_user, CNT:<N/A>, HDR:{authorization=<OMITTED>, Connection=close, content-length=0, Host=localhost:9200}, HIS:[::KIBANA-SRV::->[auth_key->false]], [testuser->[auth_key->false]], [adminuser->[jwt_auth->false]] }

Any ideas on what I am doing wrong here?

Thanks

Remove this, our Kibana plugin gets the JWT from the query parameter, yes. But then it forwards it to Elasticsearch as a HTTP header in the classical format Authorization: Bearer <jwt_token>.

Thanks, this helps. I now get an InvalidKeyException instead which I think is because the key I am using is a PEM certificate so this should be something else. I’ll do some research and see if I can solve this myself.

If anyone have a x5c certificate like me and need the public key, you can use this: Problem validating JWT with X509 cert/pubkey from /jwks - Auth0 Community

@anon39196365 basically you needed to remove the new lines and the start/end headers from the PEM format, right?

No, I got a different key. I am not an expert so a bit unsure about how it works, but appearently a x5c can contain an array of keys. This probably explains it better than me: java - InvalidKeySpecException data isn't an object ID (tag = -96) - Stack Overflow

One of the keys in this array is the public key we need in ROR, and can be extracted using

openssl x509 -in x5c-cert-formated.pem -pubkey -noout > public-key.pem

which I got from Problem validating JWT with X509 cert/pubkey from /jwks - Auth0 Community

So my x5c-cert-formatted.pem was 1912 characters long, and the public-key from it was 800 characers. Then removing the header, footer and newlines from public-key.pem and using this in ROR made it work.