No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'

Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):

opensearchproject/opensearch:3
my docker-compose file

services:
  opensearch-node1:
    image: opensearchproject/opensearch:3
    container_name: opensearch-node1
    environment:
      - cluster.name=opensearch-cluster
      - discovery.type=single-node
      - bootstrap.memory_lock=true  
      - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m  
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}  
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536  # maximum number of open files for the OpenSearch user, set to at least 65536 on modern systems
        hard: 65536
    volumes:
      - opensearch-data1:/usr/share/opensearch/data
    ports:
      - 9200:9200
      - 9600:9600  # required for Performance Analyzer
    networks:
      - opensearch-net
  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:3
    container_name: opensearch-dashboards
    ports:
      - 5601:5601
    expose:
      - '5601'
    environment:
      - OPENSEARCH_HOSTS:'["https://opensearch-node1:9200"]'
      - TZ=Asia/Shanghai
    networks:
      - opensearch-net
    volumes:
      - ./opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
      - ./roles_mapping.yml:/usr/share/opensearch/config/opensearch-security/roles_mapping.yml
      - ./roles.yml:/usr/share/opensearch/config/opensearch-security/roles.yml
  logsthash:
    image: logstash-with-opensearch:9.0.2
    privileged: true
    container_name: opensearch-logstash
    volumes:
      - /root/data/backup_server_log:/var/log
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    networks:
    - opensearch-net
volumes:
  opensearch-data1:

networks:
  opensearch-net:

config.yml

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    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: sub
            jwt_header: "Authorization"
            roles_key: roles
            openid_connect_url: https://my_server/connect/.well-known/openid-configuration

dashbroad.yml

logging.verbose: true
opensearch.hosts: [https://opensearch-node1:9200]
opensearch.ssl.verificationMode: none
opensearch.username: admin
opensearch.password: ***
opensearch.requestHeadersWhitelist: ["Authorization","securitytenant"]

opensearch_security.multitenancy.enabled: true
opensearch_security.auth.multiple_auth_enabled: true

opensearch_security.auth.type: ["basicauth","openid"]
opensearch_security.ui.openid.login.showbrandimage: true
opensearch_security.openid.base_redirect_url: "http://***:5601"

opensearch_security.openid.connect_url: "https://my_server/connect/.well-known/openid-configuration" 
opensearch_security.openid.client_id: ***
opensearch_security.openid.client_secret: ***
opensearch_security.openid.scope: "openid email,nickname,fullname"

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

role.yml

dashboard_user:
  index_permissions:
    - index_patterns: ["logs-*"]
      allowed_actions: ["read", "search"]

role_mapping.yml

all_access:
  reserved: false
  backend_roles:
  - "admin"
  description: "Maps admin to all_access"
read_only_role:
  users:
    - "my_name@***.com"
dashboard_user:
  users:
    - ""my_name@***.com"
    - "user2@company.com"
  backend_roles: ["dashboard_user"] 
admin_role:
  users:
    - "admin@company.com"
own_index:
  reserved: false
  users:
  - "*"
  description: "Allow full access to an index named like the username"
custom_role:
  reserved: false
  users:
  - "*"
oidc_dashboards_user:
  backend_roles: ["*"]
logstash:
  reserved: false
  backend_roles:
  - "logstash"

kibana_user:
  reserved: false
  backend_roles:
  - "kibanauser"
  description: "Maps kibanauser to kibana_user"

readall:
  reserved: false
  backend_roles:
  - "readall"

manage_snapshots:
  reserved: false
  backend_roles:
  - "snapshotrestore"

kibana_server:
  reserved: true
  users:
  - "kibanaserver"

curl https://my_server/connect/.well-known/openid-configuration

{"userinfo_endpoint": "https://my_server/connect/userinfo", "jwks_uri": "https://my_server/connect/jwks", "subject_types_supported": ["public"], "token_endpoint": "https://my_server/connect/token", "id_token_signing_alg_values_supported": ["HS256", "RS256"], "token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"], "response_types_supported": ["code", "id_token", "id_token token"], "end_session_endpoint": "https://my_server/connect/logout", "authorization_endpoint": "https://my_server/connect/authorize", "issuer": "https://my_server/connect"}

I successfully jumped to the login page and successfully logged in back to the http://my_host:5601/auth/openid/login?state=zx3Z4ExrX6RKxeCtSBKGsG&code=6cf8bcaf76e741f6a3b0a511b519555c.
response
{"statusCode":401,"error":"Unauthorized","message":"Unauthorized"}
dashbroads`s log

{"type":"log","@timestamp":"2025-07-01T01:27:33+08:00","tags":["error","plugins","securityDashboards"],"pid":1,"message":"OpenId authentication failed: Error: Authentication Exception"}
{"type":"response","@timestamp":"2025-07-01T01:27:33+08:00","tags":[],"pid":1,"method":"get","statusCode":401,"req":{"url":"/auth/openid/login?state=Ge9STqcVN0u4so7zoLjG0S&code=5691a636fa204acd991c9dd45194a117","method":"get","headers":{"host":"my_host:5601","connection":"keep-alive","cache-control":"max-age=0","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","accept-encoding":"gzip, deflate","accept-language":"zh-CN,zh;q=0.9"},"remoteAddress":"*****","userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"},"res":{"statusCode":401,"responseTime":57,"contentLength":9},"message":"GET /auth/openid/login?state=Ge9STqcVN0u4so7zoLjG0S&code=5691a636fa204acd991c9dd45194a117 401 57ms - 9.0B"}

opensearch`s log

[2025-06-30T17:27:33,988][WARN ][o.o.s.h.HTTPBasicAuthenticator] [edcb676fd3f3] No 'Basic Authorization' header, send 401 and 'WWW-Authenticate Basic'

I couldn’t analyze from the log where the problem occurred. My jenkins successfully used the authentication service, which means that the authentication server itself was fine.
How do I debug the oidc login service?
Thanks!

Could you try without comas?

opensearch_security.openid.scope: "openid email nickname fullname"

I have tried

openid email nickname fullname
openid,email,nickname,fullname

They are all the same error log

@daming Try running the following command against your IdP.

curl -k --noproxy '*' -d 'client_id=<client_id>' -d 'username=<username>' -d 'password=<password>' -d 'grant_type=password' -d 'client_secret=<client_secret>' -d 'scope=openid' 'https://<your_idp>/<path_to_token>/openid-connect/token')

You can find valid token URL at https://my_server/connect/.well-known/openid-configuration

This should generate a JWT token. You can decode it and check how the roles and username are passed.