Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
both Opensearch backend and dashboard are using official docker image release, in version 2.18.0
Describe the issue:
configured each-node tls cert and keys, configured both basic auth and openid in dashboard and backend.
configured my IDP to send back JWT token as both id_token
and auth_token
.
After auth step with IDP, my IDP always response “success” and issued JWT token. (from idp log)
however Opensearch always anwsers:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Unauthorized"
}
and the browser address bar path stop at e.g: <myopensearch-dashboard-url>/auth/openid/login?code=5a30144b53d56622c72e5657d2bd652a&state=TSuVruLpM0bKwSuTlhaYs3
.
Tried to use curl to get openid auth from IDP, then send auth_token
to connect to opensearch backend directly, also get the same 401 response.
i setup the log4j to trace level by:
logger.securityjwt.name = com.amazon.dlic.auth.http.jwt
logger.securityjwt.level = trace
then find below trace level message.
I see the AbstractHTTPJwtAuthenticator
trys to parse an opaque like string as JWT, however it failed in the end.
But in my OIDC, both id_token
and access_token
are already issued as JWT token type, so I don’t know where does this opaque string came from.
this string is also not my basic auth admin password.
[2024-12-02T07:24:08,434][WARN ][o.o.s.h.HTTPBasicAuthenticator] [ssdl-app-logging-opensearch-manager-1] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'
[2024-12-02T07:24:08,446][TRACE][c.a.d.a.h.j.AbstractHTTPJwtAuthenticator] [ssdl-app-logging-opensearch-manager-1] Extracting JWT token from NWM2MjY1MzgtZDM1NS00ZGZhLWExYWItOGU4NjYwMTljM2Q4Tzd0bnRaazZPTHFyRFgzTGpCeG1aTHVYUGdpX0dZeldLTmhIUno0ZGdOYw failed
com.amazon.dlic.auth.http.jwt.keybyoidc.BadCredentialsException: Invalid serialized unsecured/JWS/JWE object: Missing part delimiters
at com.amazon.dlic.auth.http.jwt.keybyoidc.JwtVerifier.getVerifiedJwtToken(JwtVerifier.java:80) ~[opensearch-security-2.18.0.0.jar:2.18.0.0]
at com.amazon.dlic.auth.http.jwt.AbstractHTTPJwtAuthenticator.extractCredentials0(AbstractHTTPJwtAuthenticator.java:130) [opensearch-security-2.18.0.0.jar:2.18.0.0]
......................
Caused by: java.text.ParseException: Invalid serialized unsecured/JWS/JWE object: Missing part delimiters
at com.nimbusds.jose.JOSEObject.split(JOSEObject.java:226) ~[nimbus-jose-jwt-9.41.2.jar:9.41.2]
...........................
... 47 more
Configuration:
I use admin basic auth to call opensearch backend with path /_plugins/_security/api/securityconfig
got below response:
{
"config": {
"dynamic": {
"filtered_alias_mode": "disallow",
"disable_rest_auth": false,
"disable_intertransport_auth": false,
"respect_request_indices_options": false,
"kibana": {
"multitenancy_enabled": false,
"private_tenant_enabled": true,
"default_tenant": "",
"server_username": "kibanaserver",
"index": ".kibana",
"sign_in_options": [
"BASIC"
]
},
"http": {
"anonymous_auth_enabled": false,
"xff": {
"enabled": false,
"internalProxies": "192\\.168\\.0\\.10|192\\.168\\.0\\.11",
"remoteIpHeader": "X-Forwarded-For"
}
},
"authc": {
"openid_auth_domain": {
"http_enabled": true,
"order": 1,
"http_authenticator": {
"challenge": false,
"type": "openid",
"config": {
"jwt_header": "Authorization",
"subject_key": "sub",
"roles_key": "groups",
"openid_connect_url": "https://<my idp url>.com/.well-known/openid-configuration",
"openid_connect_idp": {
"enable_ssl": true,
"verify_hostnames": false
}
}
},
"authentication_backend": {
"type": "noop",
"config": {}
}
},
"jwt_auth_domain": {
"http_enabled": false,
"order": 3,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
},
"ldap": {
"http_enabled": false,
"order": 6,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
},
"basic_internal_auth_domain": {
"http_enabled": true,
"order": 0,
"http_authenticator": {
"challenge": false,
"type": "basic",
"config": {}
},
"authentication_backend": {
"type": "intern",
"config": {}
},
"description": "Authenticate via HTTP Basic against internal users database"
},
"proxy_auth_domain": {
"http_enabled": false,
"order": 4,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
},
"clientcert_auth_domain": {
"http_enabled": false,
"order": 5,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
},
"saml_auth_domain": {
"http_enabled": false,
"order": 0,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
},
"kerberos_auth_domain": {
"http_enabled": false,
"order": 7,
"http_authenticator": {
"challenge": true,
"config": {}
},
"authentication_backend": {
"type": "org.opensearch.security.auth.internal.InternalAuthenticationBackend",
"config": {}
}
}
},
"authz": {
"openid_auth_domain": {
"http_enabled": true,
"authorization_backend": {
"type": "noop",
"config": {}
}
}
},
"auth_failure_listeners": {},
"do_not_fail_on_forbidden": false,
"multi_rolespan_enabled": true,
"hosts_resolver_mode": "ip-only",
"do_not_fail_on_forbidden_empty": false,
"on_behalf_of": {
"enabled": false
}
}
}
}