Hi
This is really making me go crazy. I have read, and re-read this whole post so many times its not funny.
connecting straight to ES works:
https://10.251.254.8:9200/?Authorization=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJyb2xlcyI6ImVtcGxveWVlIn0.OHfus-c1-fV6J9kQAZ2nadq_nUAIzVyK1mZbLdMG1WI
But when i go to kibana using this link, it just takes me to the kibana plugin login page
http://10.251.254.8:5601/?authorization=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJyb2xlcyI6ImVtcGxveWVlIn0.OHfus-c1-fV6J9kQAZ2nadq_nUAIzVyK1mZbLdMG1WI
Here are the 2 config files:
kibana.yml
searchguard.jwt.enabled: true
(removed the other 2 lines so it just goes with the default)
sg_config.yml
authc:
kerberos_auth_domain:
enabled: false
order: 6
http_authenticator:
type: kerberos # NOT FREE FOR COMMERCIAL USE
challenge: true
config:
If true a lot of kerberos/security related debugging output will be logged to standard out
krb_debug: false
If true then the realm will be stripped from the user name
strip_realm_from_principal: true
authentication_backend:
type: noop
basic_internal_auth_domain:
enabled: true ##############
order: 4
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: intern
proxy_auth_domain:
enabled: false
order: 3
http_authenticator:
type: proxy
challenge: false
config:
user_header: “x-proxy-user”
roles_header: “x-proxy-roles”
authentication_backend:
type: noop
host_auth_domain:
enabled: false
order: 1
http_authenticator:
type: host #DEPRECATED, will be removed in a future version
challenge: false
authentication_backend:
type: noop
jwt_auth_domain:
enabled: true
order: 0
http_authenticator:
type: jwt
challenge: false
config:
signing_key: “bmlzaGFudG5pc2hhbnQ=”
jwt_header: “Authorization”
jwt_url_parameter: “Authorization”
roles_key: roles
subject_key: name
authentication_backend:
type: noop
clientcert_auth_domain:
enabled: false
order: 2
http_authenticator:
type: clientcert
config:
username_attribute: cn #optional, if omitted DN becomes username
challenge: false
authentication_backend:
type: noop
ldap:
enabled: false
order: 5
http_authenticator:
type: basic
challenge: false
authentication_backend:
LDAP authentication backend (authenticate users against a LDAP or Active Directory)
type: ldap # NOT FREE FOR COMMERCIAL USE
config:
enable ldaps
enable_ssl: false
enable start tls, enable_ssl should be false
enable_start_tls: false
send client certificate
enable_ssl_client_auth: false
verify ldap hostname
verify_hostnames: true
hosts:
bind_dn: null
password: null
userbase: ‘ou=people,dc=example,dc=com’
Filter to search for users (currently in the whole subtree beneath userbase)
{0} is substituted with the username
usersearch: ‘(sAMAccountName={0})’
Use this attribute from the user as username (if not set then DN is used)
username_attribute: null
What have a done wrong? I downloaded all the SG modules/jars 2 weeks ago - so i would expect the kibana plugin would include the functionality, as the one in the above link is for 5.4.0, while i am running 5.6.0.
Thanks
···
On Friday, October 27, 2017 at 12:35:57 AM UTC+11, Jochen Kressin wrote:
Basically you can name and configure the JWT URL parameter as you like. This is to make it possible to integrate Search Guard in already existing infrastructures, where the name of the parameter is already fixed and you can’t change it. Example including Kibana:
In kibana.yml you can set two config keys:
- searchguard.jwt.url_param (default: authorization)
- searchguard.jwt.header (default: Authorization)
If the SG Kibana plugins finds a token in the url parameter specified by the searchguard.jwt.url_param config (or the default if the key is not set), it copies it to an HTTP header specified by searchguard.jwt.header (or the default if this key is not set).
Copying from an url parameter to an HTTP header is needed because Kibana internally only supports to add HTTP headers, not parameters.
The JWT module installed on the Kibana side then looks for a token in the HTTP header configured by the jwt_header key in the JWT module config. Default is “Authorization”. Again, Kibana only supports HTTP headers, that’s why you need to use HTTP header based tokens. It then validates the token and continues with the authentication flow.
So if you don’t change the defaults, just add your token as “authorization” url parameter to every request to Kibana.
If you want to use a different HTTP header, other than “Authorization”, note that Kibana requires you to whitelist any of these additional HTTP headers in kibana.yml:
elasticsearch.requestHeadersWhitelist: [ “authorization”, “my_other_header”, “…” ]
On Thursday, October 26, 2017 at 3:01:24 PM UTC+2, Paul Azad wrote:
Hi
We are trying the same thing, and have a question regarding your example above.
You put searchguard.jwt.url_param: jwtparam , yet in your Kibana URL you put ?authorization=
Is this a mistake or correct?
From what i can tell your grabbing the token from the kibana URL path (in your example the token after the jwtparam=, and your converting it to the http header by the name of jwtheader. Then elasticsearch is grabbing that header value and treating it based on the elasticsearc config - specifically this line:
jwt_header: “jwtheader”.
Is that correct?
thanks
On Wednesday, May 24, 2017 at 12:06:51 AM UTC+10, Jochen Kressin wrote:
Hi Michael,
we’ve just prepared a first release candidate of the next version of our Kibana plugin, including the JWT support we’ve talked about.
You can install the RC1 for KI 5.4.0 like:
bin/kibana-plugin install https://cdn.filestackcontent.com/u9mGutyCQDq0mIQhKTIB
It works like explained above: It takes the JWT token from the URL, stores it in an encrpyted session cookie, and adds it as http header to each request.
Sample Kibana configuration:
searchguard.jwt.enabled: true
searchguard.jwt.url_param: jwtparam
searchguard.jwt.header: jwtheader
searchguard.jwt.enabled: Enabled/disables the JWT support
searchguard.jwt.url_param: The name of the query param we use to look up the JWT token
searchguard.jwt.header: The name of the HTTP header we copy the token to
On the ES side, you need to place the JWT authenticator before the Basic Auth you probably use for the Kibana server user. This is important, otherwise the JWT token will be ignored!
So, place the JWT authenticator first, and use the value of searchguard.jwt.header you used in the KI configuration as jwt_header value in the JWT configuration in ES, for example:
jwt_auth_domain:
enabled: true
order: 0
http_authenticator:
type: jwt
challenge: false
config:
signing_key: “…”
jwt_header: “jwtheader”
jwt_url_parameter: null
roles_key: roles
subject_key: username
You can then append the JWT key to any Kibana URL, like:
http://localhost:5601/?authorization=……
The URL param takes precedence and will overwrite any already stored JWT token. We use session cookies, so you can “log out” by closing the browser. You can also use an empty JWT token in the URL to delete the stored one.
Let me know if this works for you, and if you need anything else!
Thanks,
Jochen
On Wednesday, May 17, 2017 at 5:20:04 PM UTC+2, Jochen Kressin wrote:
No, that’s not possible due to the inner workings of Kibana. The only way would be to patch core Kibana somehow (would need to investigate this a bit further) , but due to the fast release cycles of ES/KI supporting such a patch is not really an option.
On Wednesday, May 17, 2017 at 2:36:07 PM UTC+2, mic...@hull.io wrote:
Thanks for the clarification. It should work for us.
We plan to deploy the 5.4.0 version
Do you think that in next step we could work on query param only solution which is session independent? Is it even possible due to Kibana implementation?
On Wednesday, May 17, 2017 at 2:29:42 PM UTC+2, Jochen Kressin wrote:
Yes, I see your point. First regarding the precedence, the sequence would be:
- check if there is any JWT token in the get parameter in the URL
- The name of this parameter would be configurable in kibana.yml
- If so, take this value and store it in the session cookie, regardless if there is an existing value
- This would overwrite the existing session information, and you could also set the param to an empty string, basically removing the session information completely
- For all subsequent requests, if there is a token stored in the session cookie, add it as HTTP header
You’re right, this approach would not support working in two tabs with two different JWT tokens simultaneously since we’re storing the credentials in a cookie. You could work with different browser, or different browser windows in private mode, that should work.
So if you think this approach could work, let me know your KI/ES version you’re on, and we can prepare a snapshot for you to test.
On Wednesday, May 17, 2017 at 1:11:57 PM UTC+2, mic...@hull.io wrote:
Big thanks for in-depth information.
The solution you described is great for us since we can pass the JWT directly, for example in an iframe. For header we would need to employ a proxy to modify the request on the fly.
We would like to combine that with one role with username substitution to control access. Then generate a JWTs with different subjects (hence usernames) to easily filter the available data.
Do you see any risk of mixing sessions between different users in that solution? I understand that using session cookies on kibana, parsing and storing the JWT on the initial call to kibana would make it impossible for one user to work on two tabs in one browser with two different JWTs. That would need passing JWT param around in kibana all the time. Am I right? I’m not familiar with kibana internals, so please correct me.
If the url query param based solution is not possible right now, we should be fine with session limitation, but we would need an option to force JWT reset in the session, so if the get url param is present it takes precedence over session information.
Do you see our idea here?
On Wednesday, May 17, 2017 at 12:41:21 PM UTC+2, Jochen Kressin wrote:
Hi,
thanks for your input.
- The docs are not correct regarding the Authentication vs. Authorization part, we’ll update it.
- I would also expect that SG looks in both the URL param and the Header, I think this is a bug on our side. I have opened an issue here: https://github.com/floragunncom/search-guard-authbackend-jwt/issues/4
Regarding Kibana, this is a bit tricky, but we can probably offer a workaround.
Background: Kibana acts like a proxy for Elasticsearch. While it is possible to add HTTP header to the KI ↔ ES calls, it’s not possible to change the URLs of the KI/ES endpoints: If you issue an HTTP request to Kibana, one or more internal requests to ES are being made, with a fixed URL scheme. So, it’s not possible to add arbitrary URL parameters, like the JWT token.
A working workaround would look like this:
- Make sure that the JWT authenticator comes before the HTTP Basic Auth for the Kibana server user in your sg_config.yml.
- Configure the JWT authenticator to use token in the HTTP header
We could then extend the Kibana plugin like this:
- When a JWT token parameter is found in the URL, we grab it and store it in a session cookie
- If we find a JWT token in the said session cookie, we add it to the ES request as HTTP header
Which basically means we transform the query param to an HTTP header. You would “logout” by closing the browser, thus deleting the session cookie.
If https://github.com/floragunncom/search-guard-authbackend-jwt/issues/4 is fixed, you can leave both HTTP header and URL get param enabled if this is a requirement.
We have a working protoype/snapshot of the Kibana plugin, so the approach seems to work fine.
Before we start working on this further, please let me know if this approach is an option for you. If so, let us also know the exact KI/ES version you are using, so we can prepare a snapshot for you to try.
On Wednesday, May 17, 2017 at 12:24:18 PM UTC+2, mic...@hull.io wrote:
And I wanted to confirm that using Authorization header works correctly here.
I would just point out two things in the documentation (http://floragunncom.github.io/search-guard-docs/jwt.html)
-
it says that the default name of the header is Authentication
while it’s Authorization
https://github.com/floragunncom/search-guard-authbackend-jwt/blob/master/src/main/java/com/floragunn/dlic/auth/http/jwt/HTTPJwtAuthenticator.java#L64
-
it doesn’t say that if you set url param name the header would be ignored, I would expect that it would try to obtain the token from both places
https://github.com/floragunncom/search-guard-authbackend-jwt/blob/master/src/main/java/com/floragunn/dlic/auth/http/jwt/HTTPJwtAuthenticator.java#L93
I hope you find that feedback helpful.
On Tuesday, May 16, 2017 at 5:51:12 PM UTC+2, Jochen Kressin wrote:
Hm … JWT and Kibana should work, we have that covered in our integration tests. There’s no need to install the Search Guard Kibana plugin for it to work.
Seems like an issue with Kibana itself. If direct access to ES with a JWT token as URL param works, then Kibana does not seem to forward the query string to Elasticsearch.
Could you please open an issue on GitHub so we can investigate further:
https://github.com/floragunncom/search-guard-kibana-plugin/issues
Thanks!
On Tuesday, May 16, 2017 at 5:44:04 PM UTC+2, mic...@hull.io wrote:
Hey,
we are trying to setup an “automatic” kibana authorization using JWT passed via url param.
We already set the jwt_auth_domain
on the elastic search with jwt_url_parameter
which works perfectly fine when trying to call the ES.
But it doesn’t work while trying to pass the same param to the kibana - it always leads to the login page.
I found a topic about the JWT header authorization:
https://groups.google.com/forum/#!searchin/search-guard/kibana$20jwt%7Csort:relevance/search-guard/WniTr0mLgZ0/7cH5ZXZHBwAJ
but for our use case the url param is a key feature here.
We have briefly reviewed the code of the https://github.com/floragunncom/search-guard-kibana-plugin/ and didn’t find anything related to the JWT.
Is there any chance to get that working? How can we achieve that?
Thanks,
Michal