What is the bug?
Unable to login when OpenID and refresh_tokens=true - login just cycled (too many redirects when only openid selected and multiple_auth = false). Possible reason - too long refresh_token (from openid) breaks security_authentication cookie.
Workaround: refresh_tokens=false
Possible solution (just my opinion, you know better): store refreshToken in ExtraAuthStorage (like other tokens).
How can one reproduce the bug?
Not sure that it can be reproduced on ADFS installation.
Common steps:
- Enable OpenId auth method and connect dashboard to MS ADFS 2016+ via OpenID
- Enable refresh_tokens=true
- Try to login - should be looped (too many redirects)
Maybe easier to reproduce during local development in IDE.
I check OpenSearch Data server with token - it's working with ID Token via rest api, the problem is only on OpenSearch Security Dashboards Plugin.
See Additional context.
What is the expected behavior?
Successful login when OpenID and refresh_tokens=true (with long refresh_token), token refreshing should work too.
What is your host/environment?
- Ubuntu 24
- OpenSearch Dashboard 3.2.0
- OpenSearch Security Dashboards Plugin 3.2.0.0 (from package.json)
- ADFS on Windows 2016
Do you have any screenshots?
Nope
Do you have any additional context?
First of all, I'm not a frontend-developer, so somewhere I can be inaccurate.
Response from (truncated):
{
"access_token": "<998 symbols JWT token>",
"token_type": "bearer",
"expires_in": 7200,
"resource": "urn:microsoft:userinfo",
"refresh_token": "<3042 symbols Refresh token>"
"refresh_token_expires_in": 29674,
"id_token": "<947 symbols ID token>"
}
some details from ID token:
- user_name: <23 symbols>
- backend_roles: <25 items>
During local node debug I found possible bug place:
|
if (this.config.openid?.refresh_tokens && tokenResponse.refreshToken) { |
if (this.config.openid?.refresh_tokens && tokenResponse.refreshToken) {
Object.assign(sessionStorage.credentials, {
refresh_token: tokenResponse.refreshToken,
});
}
Extra auth cookies security_authentication_oidcX was successfully set.
If refreshToken=true then refreshToken from response will be set inside sessionStorage, which stored (as I understand) in security_authentication cookie. After that security_authentication will be too long (longer than 4096 bytes, at least 4473 bytes) and will be rejected by browser. At the next request auth will be broken, because security_authentication wasn't set (rejected by browser from previous response).
When refreshToken=false the security_authentication cookie is successfully set and work - auth work too.
opensearch_dashboards.yml:
server.host: '0.0.0.0'
server.port: 443
server.customResponseHeaders : { "Access-Control-Allow-Credentials" : "true" }
server.ssl.enabled: true
server.ssl.certificate: local-ssl.pem
server.ssl.key: local-ssl.key
opensearch.hosts: [https://127.0.0.1:9200]
opensearch.ssl.verificationMode: none
opensearch.username: kibana
opensearch.password: 213123123123
opensearch.requestHeadersWhitelist: [Authorization, securitytenant, security_tenant]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: [Private, Global]
opensearch_security.readonly_mode.roles: [kibana_read_only]
opensearch_security.cookie.secure: true
opensearch.ssl.certificateAuthorities: [ "root_ca.crt" ]
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.auth.type: ["openid","basicauth"]
opensearch_security.openid.base_redirect_url: https://127.0.0.1
opensearch_security.openid.connect_url: <adfs_url>
opensearch_security.openid.client_id: <client_id>
opensearch_security.openid.client_secret: <client_secret>
opensearch_security.openid.trust_dynamic_headers: true
opensearch_security.openid.verify_hostnames: false
opensearch_security.openid.extra_storage.cookie_prefix: sec_auth_oidc
opensearch_security.openid.extra_storage.additional_cookies: 5
opensearch_security.openid.refresh_tokens: true
opensearch.logQueries: true
logging.verbose: true
What is the bug?
Unable to login when OpenID and refresh_tokens=true - login just cycled (too many redirects when only openid selected and multiple_auth = false). Possible reason - too long refresh_token (from openid) breaks security_authentication cookie.
Workaround: refresh_tokens=false
Possible solution (just my opinion, you know better): store refreshToken in ExtraAuthStorage (like other tokens).
How can one reproduce the bug?
Not sure that it can be reproduced on ADFS installation.
Common steps:
Maybe easier to reproduce during local development in IDE.
I check OpenSearch Data server with token - it's working with ID Token via rest api, the problem is only on OpenSearch Security Dashboards Plugin.
See Additional context.
What is the expected behavior?
Successful login when OpenID and refresh_tokens=true (with long refresh_token), token refreshing should work too.
What is your host/environment?
Do you have any screenshots?
Nope
Do you have any additional context?
First of all, I'm not a frontend-developer, so somewhere I can be inaccurate.
Response from (truncated):
{
"access_token": "<998 symbols JWT token>",
"token_type": "bearer",
"expires_in": 7200,
"resource": "urn:microsoft:userinfo",
"refresh_token": "<3042 symbols Refresh token>"
"refresh_token_expires_in": 29674,
"id_token": "<947 symbols ID token>"
}
some details from ID token:
During local node debug I found possible bug place:
security-dashboards-plugin/server/auth/types/openid/routes.ts
Line 205 in 36fe977
if (this.config.openid?.refresh_tokens && tokenResponse.refreshToken) {
Object.assign(sessionStorage.credentials, {
refresh_token: tokenResponse.refreshToken,
});
}
Extra auth cookies security_authentication_oidcX was successfully set.
If refreshToken=true then refreshToken from response will be set inside sessionStorage, which stored (as I understand) in security_authentication cookie. After that security_authentication will be too long (longer than 4096 bytes, at least 4473 bytes) and will be rejected by browser. At the next request auth will be broken, because security_authentication wasn't set (rejected by browser from previous response).
When refreshToken=false the security_authentication cookie is successfully set and work - auth work too.
opensearch_dashboards.yml:
server.host: '0.0.0.0'
server.port: 443
server.customResponseHeaders : { "Access-Control-Allow-Credentials" : "true" }
server.ssl.enabled: true
server.ssl.certificate: local-ssl.pem
server.ssl.key: local-ssl.key
opensearch.hosts: [https://127.0.0.1:9200]
opensearch.ssl.verificationMode: none
opensearch.username: kibana
opensearch.password: 213123123123
opensearch.requestHeadersWhitelist: [Authorization, securitytenant, security_tenant]
opensearch_security.multitenancy.enabled: true
opensearch_security.multitenancy.tenants.preferred: [Private, Global]
opensearch_security.readonly_mode.roles: [kibana_read_only]
opensearch_security.cookie.secure: true
opensearch.ssl.certificateAuthorities: [ "root_ca.crt" ]
opensearch_security.auth.multiple_auth_enabled: true
opensearch_security.auth.type: ["openid","basicauth"]
opensearch_security.openid.base_redirect_url: https://127.0.0.1
opensearch_security.openid.connect_url: <adfs_url>
opensearch_security.openid.client_id: <client_id>
opensearch_security.openid.client_secret: <client_secret>
opensearch_security.openid.trust_dynamic_headers: true
opensearch_security.openid.verify_hostnames: false
opensearch_security.openid.extra_storage.cookie_prefix: sec_auth_oidc
opensearch_security.openid.extra_storage.additional_cookies: 5
opensearch_security.openid.refresh_tokens: true
opensearch.logQueries: true
logging.verbose: true