# Both Opensearch backend and dashboard replys 401 in oidc configuration

**URL:** <https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651>\
**Category:** Security\
**Tags:** troubleshoot, configure\
**Created:** [December 3, 2024, 9:21am UTC](https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651 "2024-12-03T09:21:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![latituder](https://avatars.discourse-cdn.com/v4/letter/l/b19c9b/32.png) [@latituder](https://forum.opensearch.org/u/latituder)\
**Post date:** [December 3, 2024, 9:21am UTC](https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651/1 "2024-12-03T09:21:53Z")

</div>

**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:

```auto

{

"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:

```auto

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.

```auto

[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:

```auto
{
    "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
            }
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![cwperks](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/cwperks/32/4968_2.png) [@cwperks](https://forum.opensearch.org/u/cwperks)\
**Post date:** [December 10, 2024, 2:39am UTC](https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651/2 "2024-12-10T02:39:10Z")

</div>

> 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.

Could the IdP be encrypting the header? A JWT has three parts: Header, Payload and Signature and will be of the form `xxxxx.yyyyy.zzzzz`.

---

<div class="post-metadata">

**Author:** ![latituder](https://avatars.discourse-cdn.com/v4/letter/l/b19c9b/32.png) [@latituder](https://forum.opensearch.org/u/latituder)\
**Post date:** [December 10, 2024, 6:26am UTC](https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651/3 "2024-12-10T06:26:17Z")

</div>

Thanks, the issue showhow resolved.  
I guess it was because the JWT parser tried to use the string from Authentication header, however the header didn’t contain proper JWT token during the parse.

I somehow changed the basic auth order from 0 to a number larger than the openid order, then it works

---

<div class="post-metadata">

**Author:** ![cwperks](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/cwperks/32/4968_2.png) [@cwperks](https://forum.opensearch.org/u/cwperks)\
**Post date:** [December 10, 2024, 2:58pm UTC](https://forum.opensearch.org/t/both-opensearch-backend-and-dashboard-replys-401-in-oidc-configuration/22651/4 "2024-12-10T14:58:49Z")

</div>

Does the Authorization header contain the type of token sent with the request. i.e. `Authorization: Bearer <jwt>` or `Authorization: Basic <...>`. I believe if the request is missing `Bearer` or `Basic` in the Authorization header, that the JWT authenticator will take whatever the value in `Authorization` is.

Code ref: [security/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java at main · opensearch-project/security · GitHub](https://github.com/opensearch-project/security/blob/main/src/main/java/com/amazon/dlic/auth/http/jwt/HTTPJwtAuthenticator.java#L136-L166)
