jackma
February 20, 2024, 10:39am
1
Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
opensearch version:2.7.0
opensearch-dashboards version:2.7.0
Describe the issue :
In the process of integrating SSO, when opensearch-dashboards execute blow logic to retrieve authinfo
public async authenticateWithHeader(
request: OpenSearchDashboardsRequest,
headerName: string,
headerValue: string,
whitelistedHeadersAndValues: any = {},
additionalAuthHeaders: any = {}
): Promise<User> {
try {
const credentials: any = {
headerName,
headerValue,
};
const headers: any = {};
if (headerValue) {
headers[headerName] = headerValue;
}
// cannot get config elasticsearch.requestHeadersWhitelist from kibana.yml file in new platfrom
// meanwhile, do we really need to save all headers in cookie?
const esResponse = await this.esClient
.asScoped(request)
.callAsCurrentUser('opensearch_security.authinfo', {
headers,
});
return {
username: esResponse.user_name,
roles: esResponse.roles,
backendRoles: esResponse.backend_roles,
tenants: esResponse.teanats,
selectedTenant: esResponse.user_requested_tenant,
credentials,
};
} catch (error: any) {
throw new Error(error.message);
}
}
it failed with:
{“msg”:“Authentication Exception”,“path”:“/_plugins/_security/authinfo”,“query”:{},“statusCode”:401,“response”:“Unauthorized”,“wwwAuthenticateDirective”:“Basic realm="OpenSearch Security"”}
Configuration :
authc:
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 1
http_authenticator:
type: basic
challenge: true
authentication_backend:
type: intern
openid_auth_domain:
description: "SSO test"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: openid
challenge: false
config:
subject_key: user_name
roles_key: user_type
openid_connect_url: http://xxx/api/v1/nes/sso/getOpenIDConfiguration
authentication_backend:
type: noop
Relevant Logs or Screenshots :
Mantas
February 20, 2024, 4:32pm
2
Hi @jackma ,
What IdP are you using for OpenID?
Thanks,
mj
jackma
February 21, 2024, 1:43am
3
@Mantas firstly, thanks for your reply, I am using my own company’s idp, please refer:
I add some log in /usr/share/opensearch-dashboards/plugins/securityDashboards/server/auth/types/openid/helper.js
, so far i can get token(idToken & accessToken) info from tokenEndPoint(from IDP)
jackma
February 21, 2024, 2:45am
4
@Mantas this is log releated tokenEndPoint:
401 Unauthorized
occured on authenticateWithHeader function in opensearch_security_client.js, below is code fragment:
const esResponse = await this.esClient
.asScoped(request)
.callAsCurrentUser('opensearch_security.authinfo', {
headers,
});
when 401 Unauthorized occured , I checked audit log:
{
"type": "audit",
"timestamp": "2024-02-21T11:36:21,577+09:00",
"level": "INFO",
"component": "audit",
"cluster.name": "sso-check",
"node.name": "sso-check-m-1l6l",
"message": "{\"audit_cluster_name\":\"sso-check\",\"audit_node_name\":\"sso-check-m-1l6l\",\"audit_rest_request_method\":\"GET\",\"audit_category\":\"FAILED_LOGIN\",\"audit_request_origin\":\"REST\",\"audit_node_id\":\"rQcIEj1sSVmr6OtZKrB2MQ\",\"audit_request_layer\":\"REST\",\"audit_rest_request_path\":\"/_plugins/_security/authinfo\",\"@timestamp\":\"2024-02-21T02:36:21.576+00:00\",\"audit_request_effective_user_is_admin\":false,\"audit_format_version\":4,\"audit_request_remote_address\":\"10.0.4.31\",\"audit_node_host_address\":\"10.0.4.31\",\"audit_rest_request_headers\":{\"x-opensearch-product-origin\":[\"opensearch-dashboards\"],\"Connection\":[\"keep-alive\"],\"x-opaque-id\":[\"af6458ef-a231-4201-a5b2-51282aa69c2f\"],\"Host\":[\"10.0.4.31:9200\"],\"Content-Length\":[\"0\"]},\"audit_request_effective_user\":\"<NONE>\",\"audit_node_host_name\":\"10.0.4.31\"}",
"cluster.uuid": "OxtFkZbbQROYZb6pVRweSA",
"node.id": "rQcIEj1sSVmr6OtZKrB2MQ"
}
Mantas
February 21, 2024, 10:14am
5
Hi @jackma ,
Could you share a sample of your JWT token sent to Openserch from your IdP(please mask all sensitive data), together with your roles.yml
and roles_mapping.yml
?
best,
mj
jackma
February 21, 2024, 11:07am
6
@Mantas first, thank you for your enthusiastic help
this is JWT token info
roles.yml:
[root@sso-check-m-1l6l opensearch-security]# more roles.yml
_meta:
type: "roles"
config_version: 2
# Restrict users so they can only view visualization and dashboard on OpenSearchDashboards
kibana_read_only:
reserved: true
# The security REST API access role is used to assign specific users access to change the security settings through the REST API.
security_rest_api_access:
reserved: true
# Allows users to view monitors, destinations and alerts
alerting_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/alerting/alerts/get'
- 'cluster:admin/opendistro/alerting/destination/get'
- 'cluster:admin/opendistro/alerting/monitor/get'
- 'cluster:admin/opendistro/alerting/monitor/search'
- 'cluster:admin/opensearch/alerting/findings/get'
# Allows users to view and acknowledge alerts
alerting_ack_alerts:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/alerting/alerts/*'
# Allows users to use all alerting functionality
alerting_full_access:
reserved: true
cluster_permissions:
- 'cluster_monitor'
- 'cluster:admin/opendistro/alerting/*'
- 'cluster:admin/opensearch/alerting/*'
- 'cluster:admin/opensearch/notifications/feature/publish'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices_monitor'
- 'indices:admin/aliases/get'
- 'indices:admin/mappings/get'
# Allow users to read Anomaly Detection detectors and results
anomaly_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/ad/detector/info'
- 'cluster:admin/opendistro/ad/detector/search'
- 'cluster:admin/opendistro/ad/detectors/get'
- 'cluster:admin/opendistro/ad/result/search'
- 'cluster:admin/opendistro/ad/tasks/search'
- 'cluster:admin/opendistro/ad/detector/validate'
- 'cluster:admin/opendistro/ad/result/topAnomalies'
# Allows users to use all Anomaly Detection functionality
anomaly_full_access:
reserved: true
cluster_permissions:
- 'cluster_monitor'
- 'cluster:admin/opendistro/ad/*'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices_monitor'
- 'indices:admin/aliases/get'
- 'indices:admin/mappings/get'
# Allow users to execute read only k-NN actions
knn_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/knn_search_model_action'
- 'cluster:admin/knn_get_model_action'
- 'cluster:admin/knn_stats_action'
# Allow users to use all k-NN functionality
knn_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/knn_training_model_action'
- 'cluster:admin/knn_training_job_router_action'
- 'cluster:admin/knn_training_job_route_decision_info_action'
- 'cluster:admin/knn_warmup_action'
- 'cluster:admin/knn_delete_model_action'
- 'cluster:admin/knn_remove_model_from_cache_action'
- 'cluster:admin/knn_update_model_graveyard_action'
- 'cluster:admin/knn_search_model_action'
- 'cluster:admin/knn_get_model_action'
- 'cluster:admin/knn_stats_action'
# Allows users to read Notebooks
notebooks_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/notebooks/list'
- 'cluster:admin/opendistro/notebooks/get'
# Allows users to all Notebooks functionality
notebooks_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/notebooks/create'
- 'cluster:admin/opendistro/notebooks/update'
- 'cluster:admin/opendistro/notebooks/delete'
- 'cluster:admin/opendistro/notebooks/get'
- 'cluster:admin/opendistro/notebooks/list'
# Allows users to read observability objects
observability_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/observability/get'
# Allows users to all Observability functionality
observability_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/observability/create'
- 'cluster:admin/opensearch/observability/update'
- 'cluster:admin/opensearch/observability/delete'
- 'cluster:admin/opensearch/observability/get'
# Allows users to read and download Reports
reports_instances_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/reports/instance/list'
- 'cluster:admin/opendistro/reports/instance/get'
- 'cluster:admin/opendistro/reports/menu/download'
# Allows users to read and download Reports and Report-definitions
reports_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/reports/definition/get'
- 'cluster:admin/opendistro/reports/definition/list'
- 'cluster:admin/opendistro/reports/instance/list'
- 'cluster:admin/opendistro/reports/instance/get'
- 'cluster:admin/opendistro/reports/menu/download'
# Allows users to all Reports functionality
reports_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/reports/definition/create'
- 'cluster:admin/opendistro/reports/definition/update'
- 'cluster:admin/opendistro/reports/definition/on_demand'
- 'cluster:admin/opendistro/reports/definition/delete'
- 'cluster:admin/opendistro/reports/definition/get'
- 'cluster:admin/opendistro/reports/definition/list'
- 'cluster:admin/opendistro/reports/instance/list'
- 'cluster:admin/opendistro/reports/instance/get'
- 'cluster:admin/opendistro/reports/menu/download'
# Allows users to use all asynchronous-search functionality
asynchronous_search_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/asynchronous_search/*'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices:data/read/search*'
# Allows users to read stored asynchronous-search results
asynchronous_search_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opendistro/asynchronous_search/get'
# Allows user to use all index_management actions - ism policies, rollups, transforms
index_management_full_access:
reserved: true
cluster_permissions:
- "cluster:admin/opendistro/ism/*"
- "cluster:admin/opendistro/rollup/*"
- "cluster:admin/opendistro/transform/*"
- "cluster:admin/opensearch/notifications/feature/publish"
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices:admin/opensearch/ism/*'
# Allows users to use all cross cluster replication functionality at leader cluster
cross_cluster_replication_leader_full_access:
reserved: true
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- "indices:admin/plugins/replication/index/setup/validate"
- "indices:data/read/plugins/replication/changes"
- "indices:data/read/plugins/replication/file_chunk"
# Allows users to use all cross cluster replication functionality at follower cluster
cross_cluster_replication_follower_full_access:
reserved: true
cluster_permissions:
- "cluster:admin/plugins/replication/autofollow/update"
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- "indices:admin/plugins/replication/index/setup/validate"
- "indices:data/write/plugins/replication/changes"
- "indices:admin/plugins/replication/index/start"
- "indices:admin/plugins/replication/index/pause"
- "indices:admin/plugins/replication/index/resume"
- "indices:admin/plugins/replication/index/stop"
- "indices:admin/plugins/replication/index/update"
- "indices:admin/plugins/replication/index/status_check"
# Allow users to read ML stats/models/tasks
ml_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/ml/stats/nodes'
- 'cluster:admin/opensearch/ml/models/get'
- 'cluster:admin/opensearch/ml/models/search'
- 'cluster:admin/opensearch/ml/tasks/get'
- 'cluster:admin/opensearch/ml/tasks/search'
# Allows users to use all ML functionality
ml_full_access:
reserved: true
cluster_permissions:
- 'cluster_monitor'
- 'cluster:admin/opensearch/ml/*'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices_monitor'
# Allows users to use all Notifications functionality
notifications_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/notifications/*'
# Allows users to read Notifications config/channels
notifications_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/notifications/configs/get'
- 'cluster:admin/opensearch/notifications/features'
- 'cluster:admin/opensearch/notifications/channels/get'
# Allows users to use all snapshot management functionality
snapshot_management_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/snapshot_management/*'
- 'cluster:admin/opensearch/notifications/feature/publish'
- 'cluster:admin/repository/*'
- 'cluster:admin/snapshot/*'
# Allows users to see snapshots, repositories, and snapshot management policies
snapshot_management_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/snapshot_management/policy/get'
- 'cluster:admin/opensearch/snapshot_management/policy/search'
- 'cluster:admin/opensearch/snapshot_management/policy/explain'
- 'cluster:admin/repository/get'
- 'cluster:admin/snapshot/get'
# Allows user to use point in time functionality
point_in_time_full_access:
reserved: true
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'manage_point_in_time'
# Allows users to see security analytics detectors and others
security_analytics_read_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/securityanalytics/alerts/get'
- 'cluster:admin/opensearch/securityanalytics/detector/get'
- 'cluster:admin/opensearch/securityanalytics/detector/search'
- 'cluster:admin/opensearch/securityanalytics/findings/get'
- 'cluster:admin/opensearch/securityanalytics/mapping/get'
- 'cluster:admin/opensearch/securityanalytics/mapping/view/get'
- 'cluster:admin/opensearch/securityanalytics/rule/get'
- 'cluster:admin/opensearch/securityanalytics/rule/search'
# Allows users to use all security analytics functionality
security_analytics_full_access:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/securityanalytics/alerts/*'
- 'cluster:admin/opensearch/securityanalytics/detector/*'
- 'cluster:admin/opensearch/securityanalytics/findings/*'
- 'cluster:admin/opensearch/securityanalytics/mapping/*'
- 'cluster:admin/opensearch/securityanalytics/rule/*'
index_permissions:
- index_patterns:
- '*'
allowed_actions:
- 'indices:admin/mapping/put'
- 'indices:admin/mappings/get'
# Allows users to view and acknowledge alerts
security_analytics_ack_alerts:
reserved: true
cluster_permissions:
- 'cluster:admin/opensearch/securityanalytics/alerts/*'
# Allows users to monitor cluster for ZCloud Insight
zcloud_insight:
cluster_permissions:
- "cluster_monitor"
reserved: true
roles_mapping.yml
[root@sso-check-m-1l6l opensearch-security]# more roles_mapping.yml
---
# In this file users, backendroles and hosts can be mapped to Security roles.
# Permissions for OpenSearch roles are configured in roles.yml
_meta:
type: "rolesmapping"
config_version: 2
# Define your roles mapping here
## Demo roles mapping
all_access:
reserved: false
backend_roles:
- "admin"
description: "Maps admin to all_access"
own_index:
reserved: false
users:
- "*"
description: "Allow full access to an index named like the username"
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"
# Allows users to monitor cluster for ZCloud Insight
zcloud_insight:
reserved: true
users:
- "ses-insight-admin"
I tryied add internal user(in opensearh-dashboard) according user_name in JWT token, but it’s still 401 error
Mantas
February 21, 2024, 11:27am
7
jackma:
roles_key: user_type
Hi @jackma ,
“user_type”: “CUSTOMER” This will be assumed as a back_end role and needs to be mapped using roles_mapping.yml to a role with access permission.
For testing purposes could you map it to all_access (or any alternative role that has access to OpenSearch) and test it again:
all_access:
reserved: false
backend_roles:
- "admin"
- "CUSTOMER"
description: "Maps admin to all_access"
Best,
mj
jackma
February 21, 2024, 12:30pm
8
@Mantas Hi, I have update roles_mapping.yml as your suggest:
[root@sso-check-m-1l6l opensearch-security]# more roles_mapping.yml
---
# In this file users, backendroles and hosts can be mapped to Security roles.
# Permissions for OpenSearch roles are configured in roles.yml
_meta:
type: "rolesmapping"
config_version: 2
# Define your roles mapping here
## Demo roles mapping
all_access:
reserved: false
backend_roles:
- "admin"
- "CUSTOMER"
description: "Maps admin to all_access"
own_index:
reserved: false
users:
- "*"
description: "Allow full access to an index named like the username"
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"
# Allows users to monitor cluster for ZCloud Insight
zcloud_insight:
reserved: true
users:
- "ses-insight-admin"
jackma
February 21, 2024, 12:32pm
9
@Mantas Hi, I checked in opensearch-dashboards, the changes in roles_mapping.yml took effect:
jackma
February 21, 2024, 12:33pm
10
@Mantas Hi, I test sso login again, it is still failed with 401, refer:
Mantas
February 21, 2024, 1:05pm
11
Could you run the below and share the output:
curl --insecure -H "Authorization: Bearer <Bearer_token>" https://<OpenSearch_node>:9200/_plugins/_security/authinfo?pretty
thanks,
mj
jackma
February 21, 2024, 1:34pm
12
@Mantas Hi, i tried with newest idToken, it’s Unauthorized, refer:
Are you familiar with the internal logic of “https://10.0.4.31:9200/_plugins/_security/authinfo?pretty ”? , how it check idToken? for example: whether the issuer information(“iss” field in IdToken) will be verified?
i didn’t find this parts in opensearch source code.
jackma
February 23, 2024, 8:19am
13
@Mantas hello, my problem resolved, my issue caused by proxy
Background:
our test env cannot acquire openid connect meta config(due to network, connect url is not avaiable directly), so we use nginx to proxy, this maybe cause idToken is invalid(iss in JWT is inconsistent with openid connect domain), refer below:
After revised(using another openid connect url):
SSO login sucessfully:
thank you so much, sincerely!
1 Like
Mantas
February 23, 2024, 10:46am
14
Thank you @jackma for documenting and sharing your solution, this will benefit the community!
Thanks,
Mantas