Azure SSO integration issue

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

Describe the issue:
Hi All, I am trying to configure Azure SSO for opensearch using a helm chart.
But I am getting the below error.

Failed to get saml header: Error: Error: failed parsing SAML config

i have added my configs below,
Configuration:
config.yml

  config.yml: |-
    _meta:
      type: "config"
      config_version: "2"
    config:
      dynamic:
        http:
          anonymous_auth_enabled: false
        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: true
            authentication_backend:
              type: intern
          saml_auth_domain:
            order: 1
            description: "SAML provider"
            http_enabled: true
            transport_enabled: false
            http_authenticator:
              type: saml
              challenge: true
              config:
                idp:
                  metadata_url: https://login.microsoftonline.com/XXXXX
                  entity_id: https://sts.windows.net/XXXXX
                sp:
                  entity_id: dm-saml
                kibana_url: https://dashboard-url.net/
                exchange_key : "435234gsdfgsty45yfjydfwewefrthju67i5vdsr;lkfs;6utjy"
                roles_key: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
            authentication_backend:
              type: noop

dashboard-config

opensearch_dashboards.yml: |
server:
host: “0”
ssl:
enabled: “false”
xsrf:
allowlist: [“/_plugins/_security/api/authtoken”, “/_opendistro/_security/api/authtoken”, “/_opendistro/_security/saml/acs/idpinitiated”, “/_opendistro/_security/saml/acs”, “/_opendistro/_security/saml/logout”, “/_plugins/_security/saml/acs/idpinitiated”, “/_plugins/_security/saml/acs”, “/_plugins/_security/saml/logout”]
opensearch_security:
multitenancy:
enabled: “true”
tenants:
preferred: [“Private”, “Global”]
auth:
type: [“basicauth”,“saml”]
multiple_auth_enabled: “true”

opensearch:
  ssl:
    verificationMode: "none"
  hosts: ["https://opensearch-cluster-master:9200"]
  requestHeadersAllowlist: ["securitytenant", "security_tenant", "Authorization"]

At idp side we have changed redirect url from /_opendistro/_security/saml/acs to /_plugins/_security/saml/acs
but still i am getting the same error, can someone help.

Thanks in advance.

Do you use a reverse proxy with OpenSearch Dashboards?
Have you noticed any errors in OpenSearch nodes during the startup?

The correct URL is /_opendistro/_security/saml/acs.

Please share the output of the below command.

curl --insecure -u admin:admin -XGET https://<OpenSearch_node_FQDN_or_IP>:9200/_plugins/_security/api/securityconfig?pretty

Hi @pablo,
thanks for your quick response.

Do you use a reverse proxy with OpenSearch Dashboards?
No, we use istio. but i have disabled it by making sidecar as false.

Have you noticed any errors in OpenSearch nodes during the startup?
i don’t see any error or exception on opensearch and i can see the below logs,
[2023-09-01T12:28:31,909][INFO ][o.o.s.m.r.i.AbstractReloadingMetadataResolver] [opensearch-cluster-master-1] Metadata Resolver SamlHTTPMetadataResolver com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator_1: New metadata successfully loaded for 'https://login.microsoftonline.com/

initially i have configured this api only /_opendistro/_security/saml/acs there as well i got the same error so i changed it to /_plugins/_security/saml/acs

And please find the below curl response for securityconfig.

{
“config” : {
“dynamic” : {
“filtered_alias_mode” : “warn”,
“disable_rest_auth” : false,
“disable_intertransport_auth” : false,
“respect_request_indices_options” : false,
“kibana” : {
“multitenancy_enabled” : true,
“private_tenant_enabled” : true,
“default_tenant” : “”,
“server_username” : “kibanaserver”,
“index” : “.kibana”
},
“http” : {
“anonymous_auth_enabled” : false,
“xff” : {
“enabled” : false,
“internalProxies” : “10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}”,
“remoteIpHeader” : “X-Forwarded-For”
}
},
“authc” : {
“basic_internal_auth_domain” : {
“http_enabled” : true,
“transport_enabled” : true,
“order” : 0,
“http_authenticator” : {
“challenge” : true,
“type” : “basic”,
“config” : { }
},
“authentication_backend” : {
“type” : “intern”,
“config” : { }
},
“description” : “Authenticate via HTTP Basic against internal users database”
},
“saml_auth_domain” : {
“http_enabled” : true,
“transport_enabled” : false,
“order” : 1,
“http_authenticator” : {
“challenge” : true,
“type” : “saml”,
“config” : {
“idp” : {
“metadata_url” : “https://login.microsoftonline.com/XXXXX”,
“entity_id” : “https://sts.windows.net/XXXXX/
},
“sp” : {
“entity_id” : “dm-saml”
},
“kibana_url” : “https://dashboard-url.net/”,
“exchange_key” : “435234gsdfgsty45yfjydfwewefrthju67i5vdsr;lkfs;6utjy”,
“roles_key” : “http://schemas.microsoft.com/ws/2008/06/identity/claims/role
}
},
“authentication_backend” : {
“type” : “noop”,
“config” : { }
},
“description” : “SAML provider”
}
},
“authz” : { },
“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
}
}
}

@arun_udaiyar Do you get that error message in the web browser or OpenSearch Dashboards logs?

Are you able to see the login page or you’re redirected to the error straight away?
If you get the login page, are you able to sign in to Azure or the error is before that?

Yeah @pablo ,
i am able to see the login page and internal user login works fine, when i click on login with sso. its giving below error on webpage
{“statusCode”:500,“error”:“Internal Server Error”,“message”:“Internal Error”}

and here is the error logs for that,

“res”:{“statusCode”:200,“responseTime”:2,“contentLength”:9},“message”:“GET /auth/saml/captureUrlFragment.js 200 2ms - 9.0B”}
Error: failed parsing SAML config
at SecurityClient.getSamlHeader (/usr/share/opensearch-dashboards/plugins/securityDashboards/server/backend/opensearch_security_client.ts:212:15)
at runMicrotasks ()
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at /usr/share/opensearch-dashboards/plugins/securityDashboards/server/auth/types/saml/routes.ts:78:30
at Router.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:163:44)
at handler (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:124:50)
at exports.Manager.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/toolkit.js:60:28)
at Object.internals.handler (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:46:20)
at exports.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:31:20)
at Request._lifecycle (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:371:32)
at Request._execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:281:9)
{“type”:“log”,“@timestamp”:“2023-08-31T07:11:57Z”,“tags”:[“error”,“plugins”,“securityDashboards”],“pid”:1,“message”:“Failed to get saml header: Error: Error: failed parsing SAML config”}
{“type”:“error”,“@timestamp”:“2023-08-31T07:11:57Z”,“tags”:,“pid”:1,“level”:“error”,“error”:{“message”:“Internal Server Error”,“name”:“Error”,“stack”:"Error: Internal Server Error\n at HapiResponseAdapter.toError (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:143:19)\n at HapiResponseAdapter.toHapiResponse (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:97:19)\n at HapiResponseAdapter.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/response_adapter.js:92:17)\n at Router.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:164:34)\n at runMicrotasks ()\n at

@arun_udaiyar I had the same issue recently and the issue was in the metadata_url.

Could compare App Federation Metadata Url from Azure with the one in the config.yml?
Are they exactly the same?

In regards to your kibana_url, when there is no reverse proxy you must add port number 5601 in config.yml and Azure client.

kibana_url: https://dashboard-url.net:5601/

Hi @pablo, sorry for the delayed response.

i have cross checked the metadata url its seems ok, and azure side there were no sign in logs for opensearch app.

kibana_url: https://dashboard-url.net:5601/

missed to mention we are using istio as a reverse proxy so port no not required.

hello @pablo

we are actually not even getting to the login page for azure and get the internal error right away after clicking on login with sso. we do see that opensearch is fetching metadata from the metadata url in the logs.

this is what we see in the opensearch-dashboards logs

2023-09-08 17:59:50.871	
{"type":"log","@timestamp":"2023-09-09T00:59:50Z","tags":["error","plugins","securityDashboards"],"pid":1,"message":"Failed to get saml header: Error: Error: failed parsing SAML config"}
2023-09-08 17:59:50.870	
    at Request._execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:281:9)
2023-09-08 17:59:50.870	
    at Request._lifecycle (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/request.js:371:32)
2023-09-08 17:59:50.870	
    at exports.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:31:20)


2023-09-08 17:59:50.870	
    at Object.internals.handler (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/handler.js:46:20)
2023-09-08 17:59:50.870	
    at exports.Manager.execute (/usr/share/opensearch-dashboards/node_modules/@hapi/hapi/lib/toolkit.js:60:28)
2023-09-08 17:59:50.870	
    at handler (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:124:50)
2023-09-08 17:59:50.870	
    at Router.handle (/usr/share/opensearch-dashboards/src/core/server/http/router/router.js:163:44)
2023-09-08 17:59:50.870	
    at /usr/share/opensearch-dashboards/plugins/securityDashboards/server/auth/types/saml/routes.ts:78:30
2023-09-08 17:59:50.870	
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
2023-09-08 17:59:50.870	
    at runMicrotasks (<anonymous>)
2023-09-08 17:59:50.870	
    at SecurityClient.getSamlHeader (/usr/share/opensearch-dashboards/plugins/securityDashboards/server/backend/opensearch_security_client.ts:212:15)
2023-09-08 17:59:50.870	
Error: failed parsing SAML config

Looking at the code here the response to the below call doesn’t have location or request id. any pointers for how to fix it?

      await this.esClient.asScoped(request).callAsCurrentUser('opensearch_security.authinfo');
  }
    @Test
    public void bagiTest() throws Exception {
        Settings settings = Settings.builder()
            .put(IDP_METADATA_URL, "https://login.microsoftonline.com/...")
            .put("kibana_url", "https://dashboard-url.net:5601/")
            .put("idp.entity_id", "https://sts.windows.net/..../")
            .put("exchange_key", "some exchange key")
            //.put("roles_key", "roles")
            .put("path.home", ".")
            .build();

        HTTPSamlAuthenticator samlAuthenticator = new HTTPSamlAuthenticator(settings, null);

        AuthenticateHeaders authenticateHeaders = getAutenticateHeaders(samlAuthenticator);

        System.out.println("location" + authenticateHeaders.location);
        System.out.println("requestId" + authenticateHeaders.requestId);
}

this prints

location=https://login.microsoftonline.com/....
requestId=ONELOGIN_.....

I tried without path.home and it fails. what is the “correct” value for path.home?

Finally figured out the issue.

https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/auth/BackendRegistry.java#L250 sets authenticator to basic_internal_auth_domain

 if (authDomain.isChallenge() && firstChallengingHttpAuthenticator == null) {

https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/auth/BackendRegistry.java#L259 returns null

 ac = httpAuthenticator.extractCredentials(request, threadContext);

https://github.com/opensearch-project/security/blob/main/src/main/java/org/opensearch/security/auth/BackendRegistry.java#L283 returns header with no location and request id

if (authDomain.isChallenge() && httpAuthenticator.reRequestAuthentication(channel, null)) {
                    auditLog.logFailedLogin("<NONE>", false, null, request);
                    log.warn("No 'Authorization' header, send 401 and 'WWW-Authenticate Basic'");
                    return false;
                } else {

although i had updated challenge to be false for basic_internal_auth_domain , it wasn’t getting reflected in the actual security config on the pod. we deployed opensearch by helm charts. so the data and configs existed on the pvc. i am guessing securityAdmin.sh didn’t run despite doing helm uninstall and helm install, and thus didn’t update the value for challenge. it should however be noted that logging config did get updated through the same mechanism. i completely deleted the pvcs, and then did helm install with challenge = false for basic_internal_auth_domain and that fixed the issue.

filed [BUG] Helm install after uninstall doesn't update the security config · Issue #37 · opensearch-project/docker-images · GitHub for the security config not updating

this works for me. no errors all smooth.

refer: Set Up Single Sign-On in OpenSearch Using Azure Active Directory