JWT authentication support
This section offers an overview of how to integrate Siren Investigate with the Search Guard Classic JWT authenticator when Siren Investigate is embedded into an iframe by another application.
Prerequisites
Before you begin, ensure that you have completed the following steps:
-
Set up security certificates
-
Integrate Search Guard Classic
Siren Investigate proxy
It is required that Siren Investigate and the container application are published on the same domain to enable cross frame communication. This can be achieved by implementing a proxy to Siren Investigate in the container application routes or configuring a reverse proxy on a path in the application server configuration.
JWT token issuance
The application that embeds Siren Investigate is responsible for generating JWT tokens; jwt.io provides a good overview of the technology, a browser based debugging tool and a list of libraries for several platforms.
The Search Guard Classic documentation provides an overview of all the claims supported by the add-on and a list of all the configuration options.
Note that the application must specify an expiration date claim
(exp
) to avoid creating tokens with unlimited duration.
Configuration
After the add-on has been installed in the cluster, you must modify
sg_config.yml
file and upload it to the cluster using sgadmin
.
If you are using the Search Guard Classic management API, ensure that you include only
the sg_config.yml
in the sgadmin
configuration folder or you
will overwrite internal users, actiongroups, roles and mappings defined
through the API.
To enable JWT authentication over HTTP, you need to add a JWT
authenticator stanza ( the authc.jwt_auth_domain
in the example below) to searchguard.authc
; an example
sg_config.yml
follows:
searchguard:
dynamic:
http:
anonymous_auth_enabled: false
xff:
enabled: false
authc:
jwt_auth_domain:
enabled: true
order: 1
http_authenticator:
type: jwt
challenge: false
config:
signing_key: "cGFzc3dvcmQ="
jwt_header: "Authorization"
authentication_backend:
type: noop
basic_internal_auth_domain:
enabled: true
order: 2
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: internal
With this configuration, Search Guard Classic will check if the
Authorization
header contains a JWT token signed with the signing
key specified in http_authenticator.signing_key
.
The signing key must be encoded using the base64
algorithm; in the
example the decoded key is password
; when using RSA public keys, it
is also possible to write them on multiple lines as follows:
searchguard:
...
authc:
jwt_auth_domain:
...
http_authenticator:
...
config:
signing_key: |-
-----BEGIN PUBLIC KEY-----
123123abcbc
-----END PUBLIC KEY-----
If the token is decoded successfully, Search Guard Classic will validate the following claims:
-
iat
: Issued At: the date when the token was issued (optional). -
exp
: Expiration Time: the date after which the token should expired; this claim is optional but you should set it, otherwise tokens will have unlimited duration. -
nbf
: Not Before: the date before which the token should be rejected (optional).
All dates are expressed as seconds since the Epoch in UTC. |
If time claims are validated, Search Guard Classic will get the username from
the Subject claim (sub
), assign role mappings and evaluate role
permissions.
If an HTTP request to the cluster contains an HTTP Basic authorization
header it will be authenticated by the HTTP authenticator defined in
basic_internal_auth_domain
; it is necessary to leave this enabled as
the Siren Investigate backend uses this method to authenticate with the
cluster.
It is possible to customize the claim used to retrieve the username
through the parameter subject_key
, for example:
searchguard:
dynamic:
http:
anonymous_auth_enabled: false
xff:
enabled: false
authc:
jwt_auth_domain:
enabled: true
order: 1
http_authenticator:
type: jwt
challenge: false
config:
signing_key: |-
-----BEGIN PUBLIC KEY-----
123123abcbc
-----END PUBLIC KEY-----
subject_key: "service:username"
jwt_header: "Authorization"
authentication_backend:
type: noop
User cache
When using the JWT authentication mechanism it is recommended to switch
off the Search Guard Classic user cache as each token contains the complete
description of the user; this can be done by adding the following
setting to elasticsearch.yml :
|
searchguard.cache.ttl_minutes: 0
Each node must be restarted after the setting has been added.
Roles
It is possible to specify user roles in a token claim by setting the
roles_key
attribute in the authenticator configuration to the
desired claim name, for example:
#...
jwt_auth_domain:
enabled: true
order: 1
http_authenticator:
type: jwt
challenge: false
config:
roles_key: "roles"
signing_key: "cGFzc3dvcmQ="
jwt_header: "Authorization"
#...
After the attribute is set and the configuration is updated, it is
possible to assign backend roles to the user by setting the claim
defined in http_authenticator.config.roles_key
in the token payload,
for example :
{
"sub": "sirenuser",
"exp": 1495711765,
"roles": "sales,marketing"
}
To map roles set in the JWT token to Search Guard Classic roles you must define a role mapping such as the following: |
Verification
To verify that Search Guard Classic JWT authentication is working correctly, you can generate a JWT token from your application and pass it to Elasticsearch using curl’s -H
option, for example:
curl -k -H "Content-Type: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJraWJpdXNlciJ9.tqCYxJsORvro59Q01J9HUeFpQtauc81CcTlS5bVl93Y" https://localhost:9200/_searchguard/authinfo
To test if it is working correctly before the application is ready, you
can use the jwt.io debugger to generate tokens
using the signing key defined in sg_config.yml
.
Siren Investigate JWT configuration
To enable JWT support in Siren Investigate, set the
investigate_access_control.backends.searchguard.authenticator
option
in investigate.yml
to http-jwt
, for example:
investigate_access_control:
#... existing options
backends:
searchguard:
#... existing options
authenticator: 'http-jwt'
Then restart Siren Investigate and open it in a browser; you should get
a blank page and the URL should end with login
.
To test JWT authentication, open your browser console
(Ctrl+Shift+I on Chrome and Firefox) and call
setJWTToken
of the sireninvestigate
object, for example:
document.getElementById('investigateframe')
.contentWindow
.sireninvestigate
.setJWTToken(yourtoken)
.then(function() {
console.log('JWT token set.');
})
.catch(function(error) {
console.log('An error occurred setting the token.');
});
After the token is set, Siren Investigate will store it in an encrypted cookie and send it in every request to the backend; the backend will then forward the JWT token to Search Guard Classic to authenticate the user.
After the token is set, you can switch to the desired Siren Investigate
URL by changing location.href
.
When the user is logged out from the main application, sessionStorage and localStorage should be cleared.