forked from elastic/elasticsearch
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support excluding roles for SAML realm (elastic#105445)
This PR adds a new `exclude_roles` setting for SAML realm. This setting allows to exclude certain roles from being mapped to users that are authenticated via SAML realm - regardless of the configured role mappings. The `exclude_roles` setting supports only explicit role names. Regular expressions and wildcards are not supported. The exclusion is possible only if the role mapping is handled by the SAML realm. Hence, it is not possible to configure it along with `authorization_realms` setting. Note: It is intentional that this setting is not registered in this PR. The registration will be addressed in a separate PR.
- Loading branch information
1 parent
a874f47
commit 4f07020
Showing
8 changed files
with
403 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...c/main/java/org/elasticsearch/xpack/core/security/authc/support/SecuritySettingsUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.core.security.authc.support; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
/** | ||
* Utilities for validating security settings. | ||
*/ | ||
public final class SecuritySettingsUtil { | ||
|
||
/** | ||
* Validates that a given setting's value is not empty nor null. | ||
* | ||
* @param settingKey The full setting key which is validated. Used for building a proper error messages. | ||
* @param settingValue The value to validate that it's not null nor empty. | ||
*/ | ||
public static void verifyNonNullNotEmpty(final String settingKey, final String settingValue) { | ||
verifyNonNullNotEmpty(settingKey, settingValue, null); | ||
} | ||
|
||
/** | ||
* Validates that a given setting's value is not empty nor null and that it is one of the allowed values. | ||
* | ||
* @param settingKey The full setting key which is validated. Used for building a proper error messages. | ||
* @param settingValue The value to validate that it's not null nor empty and that is one of the allowed values. | ||
* @param allowedValues Optional allowed values, against which to validate the given setting value. | ||
* If provided, it will be checked that the setting value is one of these allowed values. | ||
*/ | ||
public static void verifyNonNullNotEmpty(final String settingKey, final String settingValue, final Collection<String> allowedValues) { | ||
assert settingValue != null : "Invalid null value for [" + settingKey + "]."; | ||
if (settingValue.isEmpty()) { | ||
throw new IllegalArgumentException("Invalid empty value for [" + settingKey + "]."); | ||
} | ||
if (allowedValues != null) { | ||
if (allowedValues.contains(settingValue) == false) { | ||
throw new IllegalArgumentException( | ||
"Invalid value [" + settingValue + "] for [" + settingKey + "]. Allowed values are " + allowedValues + "." | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Validates that a given setting's values are not empty nor null. | ||
* | ||
* @param settingKey The full setting key which is validated. Used for building a proper error messages. | ||
* @param settingValues The values to validate that are not null nor empty. | ||
*/ | ||
public static void verifyNonNullNotEmpty(final String settingKey, final List<String> settingValues) { | ||
verifyNonNullNotEmpty(settingKey, settingValues, null); | ||
} | ||
|
||
/** | ||
* Validates that a given setting's values are not empty nor null and that are one of the allowed values. | ||
* | ||
* @param settingKey The full setting key which is validated. Used for building a proper error messages. | ||
* @param settingValues The values to validate that are not null nor empty and that are one of the allowed values. | ||
* @param allowedValues The allowed values against which to validate the given setting values. | ||
* If provided, this method will check that the setting values are one of these allowed values. | ||
*/ | ||
public static void verifyNonNullNotEmpty( | ||
final String settingKey, | ||
final List<String> settingValues, | ||
final Collection<String> allowedValues | ||
) { | ||
assert settingValues != null : "Invalid null list of values for [" + settingKey + "]."; | ||
if (settingValues.isEmpty()) { | ||
if (allowedValues == null) { | ||
throw new IllegalArgumentException("Invalid empty list for [" + settingKey + "]."); | ||
} else { | ||
throw new IllegalArgumentException( | ||
"Invalid empty list for [" + settingKey + "]. Allowed values are " + allowedValues + "." | ||
); | ||
} | ||
} | ||
for (final String settingValue : settingValues) { | ||
verifyNonNullNotEmpty(settingKey, settingValue, allowedValues); | ||
} | ||
} | ||
|
||
private SecuritySettingsUtil() { | ||
throw new IllegalAccessError("not allowed!"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
.../main/java/org/elasticsearch/xpack/security/authc/support/mapper/ExcludingRoleMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.security.authc.support.mapper; | ||
|
||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.common.util.set.Sets; | ||
import org.elasticsearch.xpack.core.security.authc.support.CachingRealm; | ||
import org.elasticsearch.xpack.core.security.authc.support.UserRoleMapper; | ||
|
||
import java.util.Collection; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
|
||
/** | ||
* Implementation of role mapper which wraps a {@link UserRoleMapper} | ||
* and filters out the resolved roles by removing the configured roles to exclude. | ||
*/ | ||
public class ExcludingRoleMapper implements UserRoleMapper { | ||
|
||
private final UserRoleMapper delegate; | ||
private final Set<String> rolesToExclude; | ||
|
||
public ExcludingRoleMapper(UserRoleMapper delegate, Collection<String> rolesToExclude) { | ||
this.delegate = Objects.requireNonNull(delegate); | ||
this.rolesToExclude = Set.copyOf(rolesToExclude); | ||
} | ||
|
||
@Override | ||
public void resolveRoles(UserData user, ActionListener<Set<String>> listener) { | ||
delegate.resolveRoles(user, listener.delegateFailureAndWrap((l, r) -> l.onResponse(excludeRoles(r)))); | ||
} | ||
|
||
private Set<String> excludeRoles(Set<String> resolvedRoles) { | ||
if (rolesToExclude.isEmpty()) { | ||
return resolvedRoles; | ||
} else { | ||
return Sets.difference(resolvedRoles, rolesToExclude); | ||
} | ||
} | ||
|
||
@Override | ||
public void refreshRealmOnChange(CachingRealm realm) { | ||
delegate.refreshRealmOnChange(realm); | ||
} | ||
} |
Oops, something went wrong.