Authorization issue using OpenID (Keycloak)

Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
Opensearch: 2.11.0 (I use the tag latest)
Opensearch-Dashboard: 2.11.0 (I use the tag latest)
Windows 10
Docker Desktop 4.25.0
Tested with Edge 119.0 and Chrome 119.0
Keycloak 22.0.5

Describe the issue:
I’m trying to integrate opensearch and opensearch-dashboards, launched on my laptop using docker compose, and a keycloak instance located in another machine.

The keycloak is available using the following address (http://keycloak:8080). I know this is http but this is only a test setup.

When I try to connect, I am able to enter my credentials but then, opensearch-dashboards return me the following error:

{
    "statusCode": 401,
    "error": "Unauthorized",
    "message": "Unauthorized"
}

I changed the log level to verbose and I activated the security traces as proposed in Troubleshoot OpenID Connect - OpenSearch documentation.

The opensearch-dashboard logs are:

2023-11-13 11:34:03 {"type":"log","@timestamp":"2023-11-13T10:34:03Z","tags":["error","plugins","securityDashboards"],"pid":1,"message":"OpenId authentication failed: Error: Authentication Exception"}
2023-11-13 11:34:03 {"type":"response","@timestamp":"2023-11-13T10:34:03Z","tags":[],"pid":1,"method":"get","statusCode":401,"req":{"url":"/auth/openid/login?state=VRHx2nGfYq4P3dgS9HdBB_&session_state=84c63e91-86e8-4095-87a3-ca798ebd5649&code=63fa4acb-2458-4c3b-a2d1-6b40cdd277d2.84c63e91-86e8-4095-87a3-ca798ebd5649.c0d53dac-7633-4c24-b2ac-9f05e97df2ff","method":"get","headers":{"host":"localhost:5601","connection":"keep-alive","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","sec-fetch-site":"none","sec-fetch-mode":"navigate","sec-fetch-user":"?1","sec-fetch-dest":"document","sec-ch-ua":"\"Microsoft Edge\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","accept-encoding":"gzip, deflate, br","accept-language":"en,fr;q=0.9,fr-FR;q=0.8,en-GB;q=0.7,en-US;q=0.6"},"remoteAddress":"172.23.0.1","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0"},"res":{"statusCode":401,"responseTime":100,"contentLength":9},"message":"GET /auth/openid/login?state=VRHx2nGfYq4P3dgS9HdBB_&session_state=84c63e91-86e8-4095-87a3-ca798ebd5649&code=63fa4acb-2458-4c3b-a2d1-6b40cdd277d2.84c63e91-86e8-4095-87a3-ca798ebd5649.c0d53dac-7633-4c24-b2ac-9f05e97df2ff 401 100ms - 9.0B"}

and the opensearch traces (with trace level) are:

2023-11-13 11:34:03 [2023-11-13T10:34:03,090][TRACE][o.o.i.b.request          ] [opensearch-node1] [request] Adjusted breaker by [-16440] bytes, now [0]
2023-11-13 11:34:03 [2023-11-13T10:34:03,420][TRACE][o.o.i.IndexService       ] [opensearch-node1] [.kibana_1] scheduling refresh every 1s
2023-11-13 11:34:03 [2023-11-13T10:34:03,426][TRACE][o.o.i.IndexService       ] [opensearch-node1] [.opensearch-sap-log-types-config] scheduling refresh every 1s
2023-11-13 11:34:03 [2023-11-13T10:34:03,429][TRACE][o.o.i.IndexService       ] [opensearch-node1] [.opensearch-observability] scheduling refresh every 1s
2023-11-13 11:34:03 [2023-11-13T10:34:03,430][TRACE][o.o.h.AbstractHttpServerTransport] [opensearch-node1] Http channel accepted: Netty4HttpChannel{localAddress=/172.23.0.5:9200, remoteAddress=/172.23.0.2:38364}
2023-11-13 11:34:03 [2023-11-13T10:34:03,432][TRACE][o.o.i.IndexService       ] [opensearch-node1] [security-auditlog-2023.11.10] scheduling refresh every 1s
2023-11-13 11:34:03 [2023-11-13T10:34:03,437][DEBUG][i.n.h.s.SslHandler       ] [opensearch-node1] [id: 0x8bd7336f, L:/172.23.0.5:9200 - R:/172.23.0.2:38364] HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_256_GCM_SHA384
2023-11-13 11:34:03 [2023-11-13T10:34:03,437][TRACE][o.o.s.h.XFFResolver      ] [opensearch-node1] resolve /172.23.0.2:38364
2023-11-13 11:34:03 [2023-11-13T10:34:03,437][TRACE][o.o.s.h.XFFResolver      ] [opensearch-node1] no xff done (enabled or no netty request) false,class org.opensearch.security.filter.NettyRequestChannel,{},{}
2023-11-13 11:34:03 [2023-11-13T10:34:03,437][TRACE][o.o.s.a.BackendRegistry  ] [opensearch-node1] Rest authentication request from 172.23.0.2:38364 [original: /172.23.0.2:38364]
2023-11-13 11:34:03 [2023-11-13T10:34:03,438][DEBUG][o.o.s.a.BackendRegistry  ] [opensearch-node1] Check authdomain for rest internal/4 or 1 in total
2023-11-13 11:34:03 [2023-11-13T10:34:03,438][TRACE][o.o.s.a.BackendRegistry  ] [opensearch-node1] Try to extract auth creds from basic http authenticator
2023-11-13 11:34:03 [2023-11-13T10:34:03,438][WARN ][o.o.s.h.HTTPBasicAuthenticator] [opensearch-node1] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'
2023-11-13 11:34:03 [2023-11-13T10:34:03,438][TRACE][o.o.s.a.i.AuditLogImpl   ] [opensearch-node1] Check for REST category:FAILED_LOGIN, effectiveUser:<NONE>, request:/_plugins/_security/authinfo
2023-11-13 11:34:03 [2023-11-13T10:34:03,439][TRACE][o.o.s.a.r.AuditMessageRouter] [opensearch-node1] will store on sink InternalOpenSearchSink asynchronously
2023-11-13 11:34:03 [2023-11-13T10:34:03,439][TRACE][o.o.s.a.BackendRegistry  ] [opensearch-node1] No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'
2023-11-13 11:34:03 [2023-11-13T10:34:03,440][TRACE][o.o.h.HttpTracer         ] [opensearch-node1] [15][d4a8de2f-cebf-449f-9dae-2b417d32a168][GET][/_plugins/_security/authinfo] received request from [Netty4HttpChannel{localAddress=/172.23.0.5:9200, remoteAddress=/172.23.0.2:38364}]
2023-11-13 11:34:03 [2023-11-13T10:34:03,440][TRACE][o.o.i.b.in_flight_requests] [opensearch-node1] [in_flight_requests] Adding [0b][<http_request>] to used bytes [new used: [0b], limit: 536870912 [512mb], estimate: 0 [0b]]
2023-11-13 11:34:03 [2023-11-13T10:34:03,440][TRACE][o.o.i.b.in_flight_requests] [opensearch-node1] [in_flight_requests] Adjusted breaker by [0] bytes, now [0]
2023-11-13 11:34:03 [2023-11-13T10:34:03,441][TRACE][o.o.h.HttpTracer         ] [opensearch-node1] [15][d4a8de2f-cebf-449f-9dae-2b417d32a168][UNAUTHORIZED][text/plain; charset=UTF-8][0] sent response to [Netty4HttpChannel{localAddress=/172.23.0.5:9200, remoteAddress=/172.23.0.2:38364}] success [true]
2023-11-13 11:34:03 [2023-11-13T10:34:03,441][TRACE][o.o.t.TaskManager        ] [opensearch-node1] register 157 [transport] [indices:data/write/index] [index {[security-auditlog-2023.11.13][null], source[{"audit_cluster_name":"opensearch-cluster","audit_node_name":"opensearch-node1","audit_rest_request_method":"GET","audit_category":"FAILED_LOGIN","audit_request_origin":"REST","audit_node_id":"Kt3r0fC2SSmTKIILoU2wXg","audit_request_layer":"REST","audit_rest_request_path":"/_plugins/_security/authinfo","@timestamp":"2023-11-13T10:34:03.438+00:00","audit_request_effective_user_is_admin":false,"audit_format_version":4,"audit_request_remote_address":"172.23.0.2","audit_node_host_address":"172.23.0.5","audit_rest_request_headers":{"x-opensearch-product-origin":["opensearch-dashboards"],"Connection":["keep-alive"],"x-opaque-id":["d4a8de2f-cebf-449f-9dae-2b417d32a168"],"Host":["opensearch:9200"],"Content-Length":["0"]},"audit_request_effective_user":"<NONE>","audit_node_host_name":"172.23.0.5"}]}]
2023-11-13 11:34:03 [2023-11-13T10:34:03,441][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/index (): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null
2023-11-13 11:34:03 [2023-11-13T10:34:03,442][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/bulk (1): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null
2023-11-13 11:34:03 [2023-11-13T10:34:03,450][TRACE][o.o.t.TaskManager        ] [opensearch-node1] register 158 [transport] [indices:data/write/bulk[s]] [requests[1], index[security-auditlog-2023.11.13][0], refresh[IMMEDIATE]]
2023-11-13 11:34:03 [2023-11-13T10:34:03,451][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/bulk[s] (): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null

The user I’m trying to connect with has the “all_access” role.

I tryed to followed all the tuto and troubleshooting I found but I have no idea where my error can be.

Thanks in advance for your help!

Configuration:

  • Opensearch security configuration:
_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
        internalProxies: '192\.168\.0\.10|192\.168\.0\.11'
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: basic
          challenge: true
        authentication_backend:
          type: intern
      openid_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
            type: openid
            challenge: false
            config:
                subject_key: preferred_username
                roles_key: roles
                openid_connect_url: http://keycloak:8080/realms/Remi_Support_Prototype/.well-known/openid-configuration
                jwt_header: Authorization
                openid_connect_idp:
                    enable_ssl: false
            authentication_backend:
                type: noop

  • Opensearch dashboard configuration:
opensearch.hosts: [https://localhost:9200]
opensearch.ssl.verificationMode: none
opensearch.username: kibanaserver
opensearch.password: kibanaserver
opensearch.requestHeadersWhitelist: [authorization, securitytenant]

opensearch_security.multitenancy.enabled: false
opensearch_security.readonly_mode.roles: [kibana_read_only]
# Use this setting if you are running opensearch-dashboards without https
opensearch_security.cookie.secure: false
server.host: '0.0.0.0'

opensearch_security.auth.type: "openid"
opensearch_security.openid.connect_url: http://keycloak:8080/realms/Remi_Support_Prototype/.well-known/openid-configuration
opensearch_security.openid.client_id: opensearch
opensearch_security.openid.client_secret: QumkJeSWXBJJu3AczsDlB2Vt68CTz6lw
opensearch_security.openid.verify_hostnames: false
opensearch_security.openid.refresh_tokens: false
opensearch_security.openid.base_redirect_url: "http://localhost:5601"

logging.verbose: true
  • Keycloak client configuration:
{
  "clientId": "opensearch",
  "name": "",
  "description": "",
  "rootUrl": "http://localhost:5601/",
  "adminUrl": "",
  "baseUrl": "",
  "surrogateAuthRequired": false,
  "enabled": true,
  "alwaysDisplayInConsole": false,
  "clientAuthenticatorType": "client-secret",
  "secret": "QumkJeSWXBJJu3AczsDlB2Vt68CTz6lw",
  "redirectUris": [
    "http://localhost:5601/*"
  ],
  "webOrigins": [
    "http://localhost:5601"
  ],
  "notBefore": 0,
  "bearerOnly": false,
  "consentRequired": false,
  "standardFlowEnabled": true,
  "implicitFlowEnabled": true,
  "directAccessGrantsEnabled": true,
  "serviceAccountsEnabled": true,
  "authorizationServicesEnabled": true,
  "publicClient": false,
  "frontchannelLogout": true,
  "protocol": "openid-connect",
  "attributes": {
    "oidc.ciba.grant.enabled": "false",
    "client.secret.creation.time": "1699864768",
    "backchannel.logout.session.required": "true",
    "oauth2.device.authorization.grant.enabled": "false",
    "display.on.consent.screen": "false",
    "backchannel.logout.revoke.offline.tokens": "false"
  },
  "authenticationFlowBindingOverrides": {},
  "fullScopeAllowed": true,
  "nodeReRegistrationTimeout": -1,
  "protocolMappers": [
    {
      "name": "client roles",
      "protocol": "openid-connect",
      "protocolMapper": "oidc-usermodel-client-role-mapper",
      "consentRequired": false,
      "config": {
        "multivalued": "true",
        "userinfo.token.claim": "true",
        "user.attribute": "foo",
        "id.token.claim": "true",
        "access.token.claim": "true",
        "claim.name": "roles",
        "jsonType.label": "String"
      }
    },
    {
      "name": "Client IP Address",
      "protocol": "openid-connect",
      "protocolMapper": "oidc-usersessionmodel-note-mapper",
      "consentRequired": false,
      "config": {
        "user.session.note": "clientAddress",
        "id.token.claim": "true",
        "access.token.claim": "true",
        "claim.name": "clientAddress",
        "jsonType.label": "String"
      }
    },
    {
      "name": "Client ID",
      "protocol": "openid-connect",
      "protocolMapper": "oidc-usersessionmodel-note-mapper",
      "consentRequired": false,
      "config": {
        "user.session.note": "client_id",
        "id.token.claim": "true",
        "access.token.claim": "true",
        "claim.name": "client_id",
        "jsonType.label": "String"
      }
    },
    {
      "name": "Client Host",
      "protocol": "openid-connect",
      "protocolMapper": "oidc-usersessionmodel-note-mapper",
      "consentRequired": false,
      "config": {
        "user.session.note": "clientHost",
        "id.token.claim": "true",
        "access.token.claim": "true",
        "claim.name": "clientHost",
        "jsonType.label": "String"
      }
    }
  ],
  "defaultClientScopes": [
    "web-origins",
    "acr",
    "roles",
    "profile",
    "email"
  ],
  "optionalClientScopes": [
    "address",
    "phone",
    "offline_access",
    "microprofile-jwt"
  ],
  "access": {
    "view": true,
    "configure": true,
    "manage": true
  }
}

Relevant Logs or Screenshots:

Hi @rborredon,

Could you please make sure that on your Keycloak you have as per below:

navigate to : Client Scopes > roles > Tab “Mappers” > Realm Roles

set:
Token Claim Name = roles
Add to ID token → On
Add to access token → On
Add to userinfo → On

Please try the above and let me know if it worked.
Best,

Mantas

Hello.

I did the proposed modification and try defining the all_access at realm and client level.

Unfortunately it did not work.

Here is a generated ID token for this client (after the modifications):

{
  "exp": 1699880265,
  "iat": 1699879965,
  "auth_time": 0,
  "jti": "f972edee-d607-49b4-af49-14ca941a4886",
  "iss": "http://keycloak:8080/realms/Remi_Support_Prototype",
  "aud": "opensearch",
  "sub": "06dfbe62-7aca-404d-8162-b553292c5680",
  "typ": "ID",
  "azp": "opensearch",
  "session_state": "b9c2adea-48ef-4dd6-a220-b210a10fff16",
  "acr": "1",
  "sid": "b9c2adea-48ef-4dd6-a220-b210a10fff16",
  "resource_access": {
    "grafana-oauth": {
      "roles": [
        "admin"
      ]
    },
    "opensearch": {
      "roles": [
        "all_access"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "email_verified": true,
  "roles": [
    "default-roles-remi_support_prototype",
    "offline_access",
    "all_access",
    "uma_authorization"
  ],
  "name": "admin user",
  "preferred_username": "adminuser",
  "given_name": "admin",
  "family_name": "user",
  "email": "admin@mymail.com"
}

Here you need “admin” and not “all_access”:

.
.
"roles": [
    "admin"
  ],
.
.

alternatively you could modify your ../opensearch/config/opensearch-security/roles_mapping.yml as per below (adding "all_access" to a all_access.backend_roles:)

all_access:
  reserved: false
  backend_roles:
  - "admin"
  - "all_access"
  description: "Maps admin to all_access"

Please see here how to apply new configurations:

Ok. I understand that I inverted the backend roles and the front end roles.

I modified the realm role to “admin” so now the generated token id is:

{
  "exp": 1699881983,
  "iat": 1699881683,
  "auth_time": 0,
  "jti": "21bf211a-b428-41fe-95b5-18178db129a0",
  "iss": "http://keycloak:8080/realms/Remi_Support_Prototype",
  "aud": "opensearch",
  "sub": "06dfbe62-7aca-404d-8162-b553292c5680",
  "typ": "ID",
  "azp": "opensearch",
  "session_state": "9eb4b89e-bdb7-42fd-a6a9-e5bfa507ca67",
  "acr": "1",
  "sid": "9eb4b89e-bdb7-42fd-a6a9-e5bfa507ca67",
  "resource_access": {
    "grafana-oauth": {
      "roles": [
        "admin"
      ]
    },
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "email_verified": true,
  "roles": [
    "default-roles-remi_support_prototype",
    "offline_access",
    "admin",
    "uma_authorization"
  ],
  "name": "admin user",
  "preferred_username": "adminuser",
  "given_name": "admin",
  "family_name": "user",
  "email": "admin@mymail.com"
}

Unfortunatelly it is still not working. The generated logs are:

2023-11-13 14:23:23 [2023-11-13T13:23:23,738][DEBUG][o.o.s.a.BackendRegistry  ] [opensearch-node1] Check authdomain for rest internal/4 or 1 in total
2023-11-13 14:23:23 [2023-11-13T13:23:23,738][TRACE][o.o.s.a.BackendRegistry  ] [opensearch-node1] Try to extract auth creds from basic http authenticator
2023-11-13 14:23:23 [2023-11-13T13:23:23,738][WARN ][o.o.s.h.HTTPBasicAuthenticator] [opensearch-node1] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'
2023-11-13 14:23:23 [2023-11-13T13:23:23,738][TRACE][o.o.s.a.i.AuditLogImpl   ] [opensearch-node1] Check for REST category:FAILED_LOGIN, effectiveUser:<NONE>, request:/_plugins/_security/authinfo
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.s.a.r.AuditMessageRouter] [opensearch-node1] will store on sink InternalOpenSearchSink asynchronously
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.s.a.BackendRegistry  ] [opensearch-node1] No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.h.HttpTracer         ] [opensearch-node1] [206][6d48f6a2-b14b-4c30-9ebc-c9493daaef87][GET][/_plugins/_security/authinfo] received request from [Netty4HttpChannel{localAddress=/172.23.0.11:9200, remoteAddress=/172.23.0.3:55770}]
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.t.TaskManager        ] [opensearch-node1] register 1157 [transport] [indices:data/write/index] [index {[security-auditlog-2023.11.13][null], source[{"audit_cluster_name":"opensearch-cluster","audit_node_name":"opensearch-node1","audit_rest_request_method":"GET","audit_category":"FAILED_LOGIN","audit_request_origin":"REST","audit_node_id":"Kt3r0fC2SSmTKIILoU2wXg","audit_request_layer":"REST","audit_rest_request_path":"/_plugins/_security/authinfo","@timestamp":"2023-11-13T13:23:23.738+00:00","audit_request_effective_user_is_admin":false,"audit_format_version":4,"audit_request_remote_address":"172.23.0.3","audit_node_host_address":"172.23.0.11","audit_rest_request_headers":{"x-opensearch-product-origin":["opensearch-dashboards"],"Connection":["keep-alive"],"x-opaque-id":["6d48f6a2-b14b-4c30-9ebc-c9493daaef87"],"Host":["opensearch:9200"],"Content-Length":["0"]},"audit_request_effective_user":"<NONE>","audit_node_host_name":"172.23.0.11"}]}]
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.i.b.in_flight_requests] [opensearch-node1] [in_flight_requests] Adding [0b][<http_request>] to used bytes [new used: [0b], limit: 536870912 [512mb], estimate: 0 [0b]]
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/index (): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null
2023-11-13 14:23:23 [2023-11-13T13:23:23,739][TRACE][o.o.i.b.in_flight_requests] [opensearch-node1] [in_flight_requests] Adjusted breaker by [0] bytes, now [0]
2023-11-13 14:23:23 [2023-11-13T13:23:23,740][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/bulk (1): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null
2023-11-13 14:23:23 [2023-11-13T13:23:23,740][TRACE][o.o.h.HttpTracer         ] [opensearch-node1] [206][6d48f6a2-b14b-4c30-9ebc-c9493daaef87][UNAUTHORIZED][text/plain; charset=UTF-8][0] sent response to [Netty4HttpChannel{localAddress=/172.23.0.11:9200, remoteAddress=/172.23.0.3:55770}] success [true]
2023-11-13 14:23:23 [2023-11-13T13:23:23,740][TRACE][o.o.t.TaskManager        ] [opensearch-node1] register 1158 [transport] [indices:data/write/bulk[s]] [requests[1], index[security-auditlog-2023.11.13][0], refresh[IMMEDIATE]]
2023-11-13 14:23:23 [2023-11-13T13:23:23,741][TRACE][opendistro_security_action_trace] [opensearch-node1] Node opensearch-node1 -> indices:data/write/bulk[s] (): userIsAdmin=false/conRequest=true/internalRequest=falseorigin=LOCAL/directRequest=true/remoteAddress=null
2023-11-13 14:23:23 [2023-11-13T13:23:23,741][TRACE][o.o.a.b.TransportShardBulkAction] [opensearch-node1] send action [indices:data/write/bulk[s][p]] to local primary [[security-auditlog-2023.11.13][0]] for request [BulkShardRequest [[security-auditlog-2023.11.13][0]] containing [index {[security-auditlog-2023.11.13][pMvZyIsBMh1PshAt36rc], source[{"audit_cluster_name":"opensearch-cluster","audit_node_name":"opensearch-node1","audit_rest_request_method":"GET","audit_category":"FAILED_LOGIN","audit_request_origin":"REST","audit_node_id":"Kt3r0fC2SSmTKIILoU2wXg","audit_request_layer":"REST","audit_rest_request_path":"/_plugins/_security/authinfo","@timestamp":"2023-11-13T13:23:23.738+00:00","audit_request_effective_user_is_admin":false,"audit_format_version":4,"audit_request_remote_address":"172.23.0.3","audit_node_host_address":"172.23.0.11","audit_rest_request_headers":{"x-opensearch-product-origin":["opensearch-dashboards"],"Connection":["keep-alive"],"x-opaque-id":["6d48f6a2-b14b-4c30-9ebc-c9493daaef87"],"Host":["opensearch:9200"],"Content-Length":["0"]},"audit_request_effective_user":"<NONE>","audit_node_host_name":"172.23.0.11"}]}] and a refresh] with cluster state version [521] to [Kt3r0fC2SSmTKIILoU2wXg] 
2023-11-13 14:23:23 [2023-11-13T13:23:23,741][DEBUG][o.o.t.TransportService   ] [opensearch-node1] Action: indices:data/write/bulk[s][p]

Could you please run a test with (../opensearch-dashboards/config/opensearch_dashboards.yml):

#opensearch.requestHeadersWhitelist: [authorization, securitytenant]
opensearch.requestHeadersAllowlist: ['security_tenant','Authorization']

Please use a new browser in incognito/private mode.

Thanks,
Mantas

Is this your full ../opensearch/config/opensearch-security/config.yml file or just OpenID(keycloak) portion?

It is the full one. I took the one present in the docker image as a basis.

Could you please try the below as “Opensearch security configuration”:

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    http:
      anonymous_auth_enabled: false
      xff:
        enabled: false
        internalProxies: '192\.168\.0\.10|192\.168\.0\.11'
    authc:
      basic_internal_auth_domain:
        description: "Authenticate via HTTP Basic against internal users database"
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: intern
          
      openid_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 1
        http_authenticator:
            type: openid
            challenge: true
            config:
                subject_key: preferred_username
                roles_key: roles
                openid_connect_url: http://keycloak:8080/realms/Remi_Support_Prototype/.well-known/openid-configuration
                jwt_header: Authorization
                openid_connect_idp:
                    enable_ssl: false
            authentication_backend:
                type: noop

Moreover replace the above with (…/opensearch-dashboards/config/opensearch_dashboards.yml):
opensearch_security.auth.type: ['basicauth','openid']

Reboot the Dashboards server after applying changes.

I did the change. The only change is that now, we first have an error

image

And when I refresh I have the previous error (code 401).

Note: I answered this before seeing your last answers :slight_smile:

Just to confirm, have you run the ./securityadmin_demo.sh after modifying “Opensearch security configuration”?

No I never did it as I was just restarting the Docker compose.

I just did it and it look there is some issues:

**************************************************************************
** This tool will be deprecated in the next major release of OpenSearch **
** https://github.com/opensearch-project/security/issues/1755           **
**************************************************************************
Security Admin v7
Will connect to localhost:9200 ... done
Connected as "CN=kirk,OU=client,O=client,L=test,C=de"
OpenSearch Version: 2.11.0
Contacting opensearch cluster 'opensearch' and wait for YELLOW clusterstate ...
Clustername: opensearch-cluster
Clusterstate: YELLOW
Number of nodes: 1
Number of data nodes: 1
.opendistro_security index already exists, so we do not need to create one.
Populate config from /usr/share/opensearch/config/opensearch-security/
ERR: Seems /usr/share/opensearch/config/opensearch-security/config.yml is not in OpenSearch Security 7 format: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "authentication_backend" (class org.opensearch.security.securityconf.impl.v7.ConfigV7$HttpAuthenticator), not marked as ignorable (3 known properties: "type", "challenge", "config"])
 at [Source: UNKNOWN; line: 1, column: 882] (through reference chain: org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration["config"]->org.opensearch.security.securityconf.impl.v7.ConfigV7["dynamic"]->org.opensearch.security.securityconf.impl.v7.ConfigV7$Dynamic["authc"]->org.opensearch.security.securityconf.impl.v7.ConfigV7$Authc["openid_auth_domain"]->org.opensearch.security.securityconf.impl.v7.ConfigV7$AuthcDomain["http_authenticator"]->org.opensearch.security.securityconf.impl.v7.ConfigV7$HttpAuthenticator["authentication_backend"])
Will update '/roles' with /usr/share/opensearch/config/opensearch-security/roles.yml 
   SUCC: Configuration for 'roles' created or updated
Will update '/rolesmapping' with /usr/share/opensearch/config/opensearch-security/roles_mapping.yml 
   SUCC: Configuration for 'rolesmapping' created or updated
Will update '/internalusers' with /usr/share/opensearch/config/opensearch-security/internal_users.yml 
   SUCC: Configuration for 'internalusers' created or updated
Will update '/actiongroups' with /usr/share/opensearch/config/opensearch-security/action_groups.yml 
   SUCC: Configuration for 'actiongroups' created or updated
Will update '/tenants' with /usr/share/opensearch/config/opensearch-security/tenants.yml 
   SUCC: Configuration for 'tenants' created or updated
Will update '/nodesdn' with /usr/share/opensearch/config/opensearch-security/nodes_dn.yml 
   SUCC: Configuration for 'nodesdn' created or updated
Will update '/whitelist' with /usr/share/opensearch/config/opensearch-security/whitelist.yml 
   SUCC: Configuration for 'whitelist' created or updated
Will update '/audit' with /usr/share/opensearch/config/opensearch-security/audit.yml 
   SUCC: Configuration for 'audit' created or updated
Will update '/allowlist' with /usr/share/opensearch/config/opensearch-security/allowlist.yml 
   SUCC: Configuration for 'allowlist' created or updated
ERR: cannot upload configuration, see errors above

can you share the output of vi config/opensearch-security/config.yml

I just found the isse: the “authentication_backend” in your proposal was under “http_authenticator”, not under “openid_auth_domain”

Thanks a lot for your support!!!

you are very welcome! is it working as expected now?

Yes it works fine