-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KNOX-2390 - Let end-users configure SAML2 client configuration using …
…Pac4J provider parameters (#348)
- Loading branch information
Showing
8 changed files
with
369 additions
and
12 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
...c/main/java/org/apache/knox/gateway/pac4j/config/AzureADClientConfigurationDecorator.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,40 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.pac4j.core.client.Client; | ||
import org.pac4j.core.http.callback.PathParameterCallbackUrlResolver; | ||
import org.pac4j.oidc.client.AzureAdClient; | ||
|
||
public class AzureADClientConfigurationDecorator implements ClientConfigurationDecorator { | ||
private static final String AZURE_AD_CLIENT_CLASS_NAME = AzureAdClient.class.getSimpleName(); | ||
|
||
@Override | ||
public void decorateClients(List<Client> clients, Map<String, String> properties) { | ||
for (Client client : clients) { | ||
if (AZURE_AD_CLIENT_CLASS_NAME.equalsIgnoreCase(client.getName())) { | ||
// special handling for Azure AD, use path separators instead of query params | ||
((AzureAdClient) client).setCallbackUrlResolver(new PathParameterCallbackUrlResolver()); | ||
} | ||
} | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
...ac4j/src/main/java/org/apache/knox/gateway/pac4j/config/ClientConfigurationDecorator.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,40 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.pac4j.core.client.Client; | ||
|
||
/** | ||
* Defines the contract of decorating different type of Pac4J client configurations | ||
*/ | ||
public interface ClientConfigurationDecorator { | ||
|
||
/** | ||
* Decorates the given clients' configuration using the given properties (if applicable) | ||
* | ||
* @param clients | ||
* the client, whose configuration should be decorated | ||
* @param properties | ||
* the properties which may contain the required information to decorate the clients | ||
*/ | ||
void decorateClients(List<Client> clients, Map<String, String> properties); | ||
|
||
} |
45 changes: 45 additions & 0 deletions
45
...src/main/java/org/apache/knox/gateway/pac4j/config/Pac4jClientConfigurationDecorator.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,45 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.pac4j.core.client.Client; | ||
|
||
public class Pac4jClientConfigurationDecorator implements ClientConfigurationDecorator { | ||
|
||
private static final List<ClientConfigurationDecorator> DEFAULT_DECORATORS = Arrays.asList(new SAML2ClientConfigurationDecorator(), new AzureADClientConfigurationDecorator()); | ||
private final List<ClientConfigurationDecorator> decorators; | ||
|
||
public Pac4jClientConfigurationDecorator() { | ||
this(DEFAULT_DECORATORS); | ||
} | ||
|
||
// package protected so that it's visible in unit tests | ||
Pac4jClientConfigurationDecorator(List<ClientConfigurationDecorator> decorators) { | ||
this.decorators = decorators; | ||
} | ||
|
||
@Override | ||
public void decorateClients(List<Client> clients, Map<String, String> properties) { | ||
decorators.forEach(decorator -> decorator.decorateClients(clients, properties)); | ||
} | ||
|
||
} |
75 changes: 75 additions & 0 deletions
75
...src/main/java/org/apache/knox/gateway/pac4j/config/SAML2ClientConfigurationDecorator.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,75 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
import org.pac4j.core.client.Client; | ||
import org.pac4j.saml.client.SAML2Client; | ||
|
||
public class SAML2ClientConfigurationDecorator implements ClientConfigurationDecorator { | ||
|
||
private static final String SAML2_CLIENT_CLASS_NAME = SAML2Client.class.getSimpleName(); | ||
private static final String CONFIG_NAME_USE_NAME_QUALIFIER = "useNameQualifier"; | ||
private static final String CONFIG_NAME_USE_FORCE_AUTH = "forceAuth"; | ||
private static final String CONFIG_NAME_USE_PASSIVE = "passive"; | ||
private static final String CONFIG_NAME_NAMEID_POLICY_FORMAT = "nameIdPolicyFormat"; | ||
|
||
@Override | ||
public void decorateClients(List<Client> clients, Map<String, String> properties) { | ||
for (Client client : clients) { | ||
if (SAML2_CLIENT_CLASS_NAME.equalsIgnoreCase(client.getName())) { | ||
final SAML2Client saml2Client = (SAML2Client) client; | ||
setUseNameQualifierFlag(properties, saml2Client); | ||
setForceAuthFlag(properties, saml2Client); | ||
setPassiveFlag(properties, saml2Client); | ||
setNameIdPolicyFormat(properties, saml2Client); | ||
} | ||
} | ||
} | ||
|
||
private void setUseNameQualifierFlag(Map<String, String> properties, final SAML2Client saml2Client) { | ||
final String useNameQualifier = properties.get(CONFIG_NAME_USE_NAME_QUALIFIER); | ||
if (StringUtils.isNotBlank(useNameQualifier)) { | ||
saml2Client.getConfiguration().setUseNameQualifier(Boolean.valueOf(useNameQualifier)); | ||
} | ||
} | ||
|
||
private void setForceAuthFlag(Map<String, String> properties, final SAML2Client saml2Client) { | ||
final String forceAuth = properties.get(CONFIG_NAME_USE_FORCE_AUTH); | ||
if (StringUtils.isNotBlank(forceAuth)) { | ||
saml2Client.getConfiguration().setForceAuth(Boolean.valueOf(forceAuth)); | ||
} | ||
} | ||
|
||
private void setPassiveFlag(Map<String, String> properties, final SAML2Client saml2Client) { | ||
final String passive = properties.get(CONFIG_NAME_USE_PASSIVE); | ||
if (StringUtils.isNotBlank(passive)) { | ||
saml2Client.getConfiguration().setPassive(Boolean.valueOf(passive)); | ||
} | ||
} | ||
|
||
private void setNameIdPolicyFormat(Map<String, String> properties, final SAML2Client saml2Client) { | ||
final String nameIdPolicyFormat = properties.get(CONFIG_NAME_NAMEID_POLICY_FORMAT); | ||
if (StringUtils.isNotBlank(nameIdPolicyFormat)) { | ||
saml2Client.getConfiguration().setNameIdPolicyFormat(nameIdPolicyFormat); | ||
} | ||
} | ||
} |
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
40 changes: 40 additions & 0 deletions
40
...st/java/org/apache/knox/gateway/pac4j/config/AzureADClientConfigurationDecoratorTest.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,40 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import static org.junit.Assert.assertTrue; | ||
|
||
import java.util.Collections; | ||
|
||
import org.junit.Test; | ||
import org.pac4j.core.http.callback.PathParameterCallbackUrlResolver; | ||
import org.pac4j.oidc.client.AzureAdClient; | ||
import org.pac4j.oidc.config.AzureAdOidcConfiguration; | ||
|
||
public class AzureADClientConfigurationDecoratorTest { | ||
|
||
@Test | ||
public void testAzureADClientConfigurationDecoration() throws Exception { | ||
final AzureAdOidcConfiguration azureAdConfig = new AzureAdOidcConfiguration(); | ||
final AzureAdClient client = new AzureAdClient(azureAdConfig); | ||
final AzureADClientConfigurationDecorator azureConfigDecorator = new AzureADClientConfigurationDecorator(); | ||
azureConfigDecorator.decorateClients(Collections.singletonList(client), null); | ||
assertTrue(client.getCallbackUrlResolver() instanceof PathParameterCallbackUrlResolver); | ||
} | ||
|
||
} |
71 changes: 71 additions & 0 deletions
71
...test/java/org/apache/knox/gateway/pac4j/config/Pac4jClientConfigurationDecoratorTest.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,71 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package org.apache.knox.gateway.pac4j.config; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
import org.easymock.EasyMock; | ||
import org.junit.Test; | ||
import org.pac4j.core.client.Client; | ||
|
||
public class Pac4jClientConfigurationDecoratorTest { | ||
|
||
@Test | ||
public void testClientConfigDecoration() throws Exception { | ||
final AtomicInteger tested = new AtomicInteger(0); | ||
final AtomicInteger decorated = new AtomicInteger(0); | ||
|
||
final ClientConfigurationDecorator passiveDecorator = new TestClientConfigurationDecorator(tested, decorated, false); | ||
final ClientConfigurationDecorator activeDecorator = new TestClientConfigurationDecorator(tested, decorated, true); | ||
final Pac4jClientConfigurationDecorator pac4jConfigurationDecorator = new Pac4jClientConfigurationDecorator(Arrays.asList(passiveDecorator, activeDecorator)); | ||
final Client client = EasyMock.createNiceMock(Client.class); | ||
pac4jConfigurationDecorator.decorateClients(Collections.singletonList(client), null); | ||
assertEquals(2, tested.get()); | ||
assertEquals(1, decorated.get()); | ||
} | ||
|
||
private static class TestClientConfigurationDecorator implements ClientConfigurationDecorator { | ||
|
||
private final AtomicInteger tested; | ||
private final AtomicInteger decorated; | ||
private final boolean decorate; | ||
|
||
TestClientConfigurationDecorator(AtomicInteger testedClientsNum, AtomicInteger decoratedClientsNum, boolean decorate) { | ||
this.tested = testedClientsNum; | ||
this.decorated = decoratedClientsNum; | ||
this.decorate = decorate; | ||
} | ||
|
||
@Override | ||
public void decorateClients(List<Client> clients, Map<String, String> properties) { | ||
clients.forEach(client -> { | ||
tested.incrementAndGet(); | ||
if (decorate) { | ||
decorated.incrementAndGet(); | ||
} | ||
}); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.