Merge branch 'stable-2.16' into stable-3.0
* stable-2.16:
Create HTTP session only for login requests
Change-Id: I432b5917224f4e56c6167384ba069d7976718aee
diff --git a/README.md b/README.md
index bb9c949..0425eaf 100644
--- a/README.md
+++ b/README.md
@@ -179,7 +179,14 @@
Default is `UserName`
-**saml.serviceProviderEntityId**: Saml service provider entity id
+**saml.serviceProviderEntityId**: SAML service provider entity id.
+
+Default is not set.
+
+**saml.identityProviderEntityId**: SAML identity provider entity id. When present
+a `IDPSSODescriptor` is expected in the SAML metadata document. When absent a
+saml service provider with its `SPSSODescriptor` is assumed.
+This value takes precedence over the value in **saml.serviceProviderEntityId**.
Default is not set.
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
index d5aae19..98f09ea 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlConfig.java
@@ -23,7 +23,7 @@
@Singleton
public class SamlConfig {
private static final String SAML_SECTION = "saml";
-
+ private final String identityProviderEntityId;
private final String serviceProviderEntityId;
private final String metadataPath;
private final String keystorePath;
@@ -42,6 +42,7 @@
@Inject
SamlConfig(@GerritServerConfig Config cfg) {
serviceProviderEntityId = getString(cfg, "serviceProviderEntityId");
+ identityProviderEntityId = getString(cfg, "identityProviderEntityId");
metadataPath = getString(cfg, "metadataPath");
keystorePath = getString(cfg, "keystorePath");
privateKeyPassword = getString(cfg, "privateKeyPassword");
@@ -119,4 +120,8 @@
public boolean useNameQualifier() {
return useNameQualifier;
}
+
+ public String getIdentityProviderEntityId() {
+ return identityProviderEntityId;
+ }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
index 7307910..2c6549f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
@@ -25,6 +25,8 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
@@ -81,14 +83,23 @@
new SAML2Configuration(
samlConfig.getKeystorePath(), samlConfig.getKeystorePassword(),
samlConfig.getPrivateKeyPassword(), samlConfig.getMetadataPath());
- samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetimeAttr());
- samlClientConfig.setServiceProviderMetadataPath(
- ensureExists(sitePaths.data_dir).resolve("sp-metadata.xml").toString());
- if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
- samlClientConfig.setServiceProviderEntityId(samlConfig.getServiceProviderEntityId());
+
+ if (!Strings.isNullOrEmpty(samlConfig.getIdentityProviderEntityId())) {
+ if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
+ log.warn(
+ "Both identityProviderEntityId as serviceProviderEntityId are set, ignoring serviceProviderEntityId.");
+ }
+ samlClientConfig.setIdentityProviderEntityId(samlConfig.getIdentityProviderEntityId());
+ } else {
+ samlClientConfig.setServiceProviderMetadataPath(
+ ensureExists(sitePaths.data_dir).resolve("sp-metadata.xml").toString());
+ if (!Strings.isNullOrEmpty(samlConfig.getServiceProviderEntityId())) {
+ samlClientConfig.setServiceProviderEntityId(samlConfig.getServiceProviderEntityId());
+ }
}
samlClientConfig.setUseNameQualifier(samlConfig.useNameQualifier());
+ samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetimeAttr());
saml2Client = new SAML2Client(samlClientConfig);
String callbackUrl = gerritConfig.getString("gerrit", null, "canonicalWebUrl") + SAML_CALLBACK;
@@ -223,13 +234,28 @@
}
private static String getAttribute(SAML2Profile user, String attrName) {
- List<?> names = (List<?>) user.getAttribute(attrName);
+ // TODO(davido): Replace with the invocation from upstream method.
+ List<String> names = extractAttributeValues(user, attrName);
if (names != null && !names.isEmpty()) {
- return (String) names.get(0);
+ return names.get(0);
}
return null;
}
+ // TODO(davido): Remove if getAttribute() uses the upstream method.
+ private static List<String> extractAttributeValues(SAML2Profile user, String attrName) {
+ final Object value = user.getAttribute(attrName);
+ if (value instanceof String) {
+ return Collections.singletonList((String) value);
+ } else if (value instanceof String[]) {
+ return Arrays.asList((String[]) value);
+ } else if (value instanceof List) {
+ return (List<String>) value;
+ } else {
+ return null;
+ }
+ }
+
private static String getAttributeOrElseId(SAML2Profile user, String attrName) {
String value = getAttribute(user, attrName);
if (value != null) {