[java-idp-plugin-duo] 15/16: Remove redundant classes, cleanup JavaDoc, fix imports, add Http Client
Phil Smart
philip.smart at jisc.ac.uk
Fri Oct 2 10:41:06 UTC 2020
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-idp-plugin-duo.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-duo.git;a=commit;h=752583fda8f0f976a7a6a0f93866eb8fd46510bf
commit 752583fda8f0f976a7a6a0f93866eb8fd46510bf
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Wed Sep 30 16:55:11 2020 +0100
Remove redundant classes, cleanup JavaDoc, fix imports, add Http Client
---
.../idp/plugin/authn/duo/DuoOIDCClient.java | 7 +
.../duo/context/DuoOIDCAuthenticationContext.java | 1 -
.../plugin/authn/duo/model/DuoAccessDevice.java | 177 -----------
.../idp/plugin/authn/duo/model/DuoApplication.java | 113 -------
.../idp/plugin/authn/duo/model/DuoAuthContext.java | 327 --------------------
.../idp/plugin/authn/duo/model/DuoAuthDevice.java | 162 ----------
.../idp/plugin/authn/duo/model/DuoAuthToken.java | 341 ---------------------
.../authn/duo/model/DuoHealthCheckResponse.java | 4 +-
.../duo/impl/DefaultDuoOIDCClientRegistry.java | 2 +-
.../idp/plugin/authn/duo/impl/DuoSupport.java | 2 +-
.../impl/ValidateDuoTokenAuthenticationResult.java | 1 -
.../flows/authn/DuoOIDC/duo-oidc-authn-beans.xml | 3 +-
.../authn/duo/impl/AbstractDuoActionTest.java | 2 +-
.../authn/duo/sdk/impl/DuoSDKClientAdaptor.java | 10 +
.../authn/duo/nimbus/DuoHttpClientFactoryBean.java | 18 ++
.../idp/plugin/authn/duo/nimbus/NimbusClient.java | 12 +-
.../authn/duo/nimbus/NimbusClientFactory.java | 9 +-
.../idp/plugin/authn/duo/nimbus/NimbusUtils.java | 9 +-
.../src/main/resources/duo-client-factory-bean.xml | 14 +-
19 files changed, 74 insertions(+), 1140 deletions(-)
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCClient.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCClient.java
index 69fcb19..78a588c 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCClient.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/DuoOIDCClient.java
@@ -64,5 +64,12 @@ public interface DuoOIDCClient {
*/
@Nonnull JWT exchangeAuthorizationCodeFor2FAResult(@Nonnull final String code,
@Nonnull final String username) throws DuoClientException;
+
+ /**
+ * Get an identifier for this client e.g. a UUID.
+ *
+ * @return the client identifier.
+ */
+ @Nonnull String getClientId();
}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/context/DuoOIDCAuthenticationContext.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/context/DuoOIDCAuthenticationContext.java
index 0a0c0cd..001cfe4 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/context/DuoOIDCAuthenticationContext.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/context/DuoOIDCAuthenticationContext.java
@@ -27,7 +27,6 @@ import com.nimbusds.jwt.JWT;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.plugin.authn.duo.DuoOIDCClient;
import net.shibboleth.idp.plugin.authn.duo.DuoOIDCIntegration;
-import net.shibboleth.idp.plugin.authn.duo.model.DuoAuthToken;
/**
* <p>Context that carries the Duo integration, request-response state, authorization code,
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAccessDevice.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAccessDevice.java
deleted file mode 100644
index 8bd29f9..0000000
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAccessDevice.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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 net.shibboleth.idp.plugin.authn.duo.model;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-/** Duo Access Device.*/
- at Immutable
-public final class DuoAccessDevice {
-
- /** IP address of the device used in 2FA.*/
- @Nonnull private final String ip;
-
- /** The hostname.*/
- @Nonnull private final String hostname;
-
- /** The state where the device is located.*/
- @Nullable private final String state;
-
- /** The city where the device is located.*/
- @Nullable private final String city;
-
- /** The country where the device is located.*/
- @Nullable private final String country;
-
-
- /**
- * @return Returns the ip.
- */
- public final String getIp() {
- return ip;
- }
-
- /**
- * @return Returns the name.
- */
- public final String getHostname() {
- return hostname;
- }
-
- /**
- * @return Returns the state.
- */
- public final String getState() {
- return state;
- }
-
- /**
- * @return Returns the city.
- */
- public final String getCity() {
- return city;
- }
-
- /**
- * @return Returns the country.
- */
- public final String getCountry() {
- return country;
- }
-
- /**
- * Private constructor, can only be called by this builder.
- *
- * @param builder the builder to build the instance with
- */
- private DuoAccessDevice(Builder builder) {
- this.ip = builder.ip;
- this.hostname = builder.hostname;
- this.state = builder.state;
- this.city = builder.city;
- this.country = builder.country;
- }
-
- /**
- * Creates builder to build {@link DuoAccessDevice}.
- * @return created builder
- */
-
- public static IIpStage builder() {
- return new Builder();
- }
-
-
- public interface IIpStage {
- public IHostnameStage withIp(String ip);
- }
-
-
- public interface IHostnameStage {
- public IBuildStage withHostname(String host);
- }
-
-
- public interface IBuildStage {
- public IBuildStage withState(String state);
-
- public IBuildStage withCity(String city);
-
- public IBuildStage withCountry(String country);
-
- public DuoAccessDevice build();
- }
-
- /**
- * Builder to build {@link DuoAccessDevice}.
- */
-
- public static final class Builder implements IIpStage, IHostnameStage, IBuildStage {
- private String ip;
-
- private String hostname;
-
- private String state;
-
- private String city;
-
- private String country;
-
- private Builder() {
- }
-
- @Override
- public IHostnameStage withIp(String ip) {
- this.ip = ip;
- return this;
- }
-
- @Override
- public IBuildStage withHostname(String host) {
- this.hostname = host;
- return this;
- }
-
- @Override
- public IBuildStage withState(String state) {
- this.state = state;
- return this;
- }
-
- @Override
- public IBuildStage withCity(String city) {
- this.city = city;
- return this;
- }
-
- @Override
- public IBuildStage withCountry(String country) {
- this.country = country;
- return this;
- }
-
- @Override
- public DuoAccessDevice build() {
- return new DuoAccessDevice(this);
- }
- }
-
-
-
-}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoApplication.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoApplication.java
deleted file mode 100644
index 423f9fa..0000000
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoApplication.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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 net.shibboleth.idp.plugin.authn.duo.model;
-
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.Immutable;
-
-/** Duo Application.*/
- at Immutable
-public final class DuoApplication {
-
- /** Application key.*/
- @Nonnull private final String key;
-
- /** Application name.*/
- @Nonnull private final String name;
-
-
- /**
- * @return Returns the key.
- */
- public final String getKey() {
- return key;
- }
-
- /**
- * @return Returns the name.
- */
- public final String getName() {
- return name;
- }
-
- /**
- * Private constructor, can only be called by this builder.
- *
- * @param builder the builder to build the instance with
- */
- private DuoApplication(final Builder builder) {
- this.key = builder.key;
- this.name = builder.name;
- }
-
- /**
- * Creates builder to build {@link DuoApplication}.
- * @return created builder
- */
-
- public static IKeyStage builder() {
- return new Builder();
- }
-
-
- public interface IKeyStage {
- public INameStage withKey(String key);
- }
-
-
- public interface INameStage {
- public IBuildStage withName(String name);
- }
-
-
- public interface IBuildStage {
- public DuoApplication build();
- }
-
- /**
- * Builder to build {@link DuoApplication}.
- */
-
- public static final class Builder implements IKeyStage, INameStage, IBuildStage {
- private String key;
-
- private String name;
-
- private Builder() {
- }
-
- @Override
- public INameStage withKey(final String key) {
- this.key = key;
- return this;
- }
-
- @Override
- public IBuildStage withName(final String name) {
- this.name = name;
- return this;
- }
-
- @Override
- public DuoApplication build() {
- return new DuoApplication(this);
- }
- }
-
-
-
-}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthContext.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthContext.java
deleted file mode 100644
index 2d7f673..0000000
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthContext.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/* Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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 net.shibboleth.idp.plugin.authn.duo.model;
-
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.Immutable;
-
-/** Duo authentication context.*/
- at Immutable
-public final class DuoAuthContext {
-
- /** Authentication result e.g. {@literal 'success'}.*/
- @Nonnull private final String result;
-
- /** Authentication timestamp.*/
- @Nonnull private final Integer timestamp;
-
- /** Device used during 2FA.*/
- @Nonnull private final DuoAuthDevice authDevice;
-
- /** Transaction id of the authentication event.*/
- @Nonnull private final String txid;
-
- /** Type of event.*/
- @Nonnull private final String eventType;
-
- /** Reason for context e.g. 'user_approved'.*/
- @Nonnull private final String reason;
-
- //TODO: difference between this and authdevice?
- @Nonnull private final DuoAccessDevice accessDevice;
-
- /** Duo 2FA application integration information.*/
- @Nonnull private final DuoApplication application;
-
- /** The factor used in the 2FA request.*/
- @Nonnull private final String factor;
-
- /** Username of the user for which 2FA was performed.*/
- @Nonnull private final String username;
-
- /** Key of the user for which 2FA was preformed.*/
- @Nonnull private final String userKey;
-
-
- /**
- * @return Returns the result.
- */
- public final String getResult() {
- return result;
- }
-
- /**
- * @return Returns the timestamp.
- */
- public final Integer getTimestamp() {
- return timestamp;
- }
-
- /**
- * @return Returns the authDevice.
- */
- public final DuoAuthDevice getAuthDevice() {
- return authDevice;
- }
-
- /**
- * @return Returns the txid.
- */
- public final String getTxid() {
- return txid;
- }
-
- /**
- * @return Returns the eventType.
- */
- public final String getEventType() {
- return eventType;
- }
-
- /**
- * @return Returns the reason.
- */
- public final String getReason() {
- return reason;
- }
-
- /**
- * @return Returns the accessDevice.
- */
- public final DuoAccessDevice getAccessDevice() {
- return accessDevice;
- }
-
- /**
- * @return Returns the application.
- */
- public final DuoApplication getApplication() {
- return application;
- }
-
- /**
- * @return Returns the factor.
- */
- public final String getFactor() {
- return factor;
- }
-
- /**
- * @return Returns the username.
- */
- public final String getUsername() {
- return username;
- }
-
- /**
- * @return Returns the userKey.
- */
- public final String getUserKey() {
- return userKey;
- }
-
- private DuoAuthContext(final Builder builder) {
- this.result = builder.result;
- this.timestamp = builder.timestamp;
- this.authDevice = builder.authDevice;
- this.txid = builder.txid;
- this.eventType = builder.eventType;
- this.reason = builder.reason;
- this.accessDevice = builder.accessDevice;
- this.application = builder.application;
- this.factor = builder.factor;
- this.username = builder.username;
- this.userKey = builder.userKey;
- }
-
- /**
- * Creates builder to build {@link DuoAuthContext}.
- * @return created builder
- */
-
- public static IResultStage builder() {
- return new Builder();
- }
-
-
- public interface IResultStage {
- public ITimestampStage withResult(String result);
- }
-
-
- public interface ITimestampStage {
- public IAuthDeviceStage withTimestamp(Integer timestamp);
- }
-
-
- public interface IAuthDeviceStage {
- public ITxidStage withAuthDevice(DuoAuthDevice authDevice);
- }
-
-
- public interface ITxidStage {
- public IEventTypeStage withTxid(String txid);
- }
-
-
- public interface IEventTypeStage {
- public IReasonStage withEventType(String eventType);
- }
-
-
- public interface IReasonStage {
- public IAccessDeviceStage withReason(String reason);
- }
-
-
- public interface IAccessDeviceStage {
- public IApplicationStage withAccessDevice(DuoAccessDevice accessDevice);
- }
-
-
- public interface IApplicationStage {
- public IFactorStage withApplication(DuoApplication application);
- }
-
-
- public interface IFactorStage {
- public IUsernameStage withFactor(String factor);
- }
-
-
- public interface IUsernameStage {
- public IUserKeyStage withUsername(String username);
- }
-
-
- public interface IUserKeyStage {
- public IBuildStage withUserKey(String userKey);
- }
-
-
- public interface IBuildStage {
- public DuoAuthContext build();
- }
-
- /**
- * Builder to build {@link DuoAuthContext}.
- */
-
- public static final class Builder
- implements IResultStage, ITimestampStage, IAuthDeviceStage, ITxidStage, IEventTypeStage, IReasonStage,
- IAccessDeviceStage, IApplicationStage, IFactorStage, IUsernameStage, IUserKeyStage, IBuildStage {
- private String result;
-
- private Integer timestamp;
-
- private DuoAuthDevice authDevice;
-
- private String txid;
-
- private String eventType;
-
- private String reason;
-
- private DuoAccessDevice accessDevice;
-
- private DuoApplication application;
-
- private String factor;
-
- private String username;
-
- private String userKey;
-
- private Builder() {
- }
-
- @Override
- public ITimestampStage withResult(final String result) {
- this.result = result;
- return this;
- }
-
- @Override
- public IAuthDeviceStage withTimestamp(final Integer timestamp) {
- this.timestamp = timestamp;
- return this;
- }
-
- @Override
- public ITxidStage withAuthDevice(final DuoAuthDevice authDevice) {
- this.authDevice = authDevice;
- return this;
- }
-
- @Override
- public IEventTypeStage withTxid(final String txid) {
- this.txid = txid;
- return this;
- }
-
- @Override
- public IReasonStage withEventType(final String eventType) {
- this.eventType = eventType;
- return this;
- }
-
- @Override
- public IAccessDeviceStage withReason(final String reason) {
- this.reason = reason;
- return this;
- }
-
- @Override
- public IApplicationStage withAccessDevice(final DuoAccessDevice accessDevice) {
- this.accessDevice = accessDevice;
- return this;
- }
-
- @Override
- public IFactorStage withApplication(final DuoApplication application) {
- this.application = application;
- return this;
- }
-
- @Override
- public IUsernameStage withFactor(final String factor) {
- this.factor = factor;
- return this;
- }
-
- @Override
- public IUserKeyStage withUsername(final String username) {
- this.username = username;
- return this;
- }
-
- @Override
- public IBuildStage withUserKey(final String userKey) {
- this.userKey = userKey;
- return this;
- }
-
- @Override
- public DuoAuthContext build() {
- return new DuoAuthContext(this);
- }
- }
-
-
-
-}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthDevice.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthDevice.java
deleted file mode 100644
index a47f118..0000000
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthDevice.java
+++ /dev/null
@@ -1,162 +0,0 @@
-
-package net.shibboleth.idp.plugin.authn.duo.model;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-/** Device used during 2FA. */
- at Immutable
-public final class DuoAuthDevice {
-
- /** IP address of the device used in 2FA.*/
- @Nonnull private final String ip;
-
- /** Name of the device e.g. phone number.*/
- @Nonnull private final String name;
-
- /** The state where the device is located.*/
- @Nullable private final String state;
-
- /** The city where the device is located.*/
- @Nullable private final String city;
-
- /** The country where the device is located.*/
- @Nullable private final String country;
-
-
- /**
- * @return Returns the ip.
- */
- public final String getIp() {
- return ip;
- }
-
- /**
- * @return Returns the name.
- */
- public final String getName() {
- return name;
- }
-
- /**
- * @return Returns the state.
- */
- public final String getState() {
- return state;
- }
-
- /**
- * @return Returns the city.
- */
- public final String getCity() {
- return city;
- }
-
- /**
- * @return Returns the country.
- */
- public final String getCountry() {
- return country;
- }
-
- /**
- * Private constructor, can only be called by this builder.
- *
- * @param builder the builder to build the instance with
- */
- private DuoAuthDevice(final Builder builder) {
- this.ip = builder.ip;
- this.name = builder.name;
- this.state = builder.state;
- this.city = builder.city;
- this.country = builder.country;
- }
-
- /**
- * Creates builder to build {@link DuoAuthDevice}.
- * @return created builder
- */
-
- public static IIpStage builder() {
- return new Builder();
- }
-
-
- public interface IIpStage {
- public INameStage withIp(String ip);
- }
-
-
- public interface INameStage {
- public IBuildStage withName(String name);
- }
-
-
- public interface IBuildStage {
- public IBuildStage withState(String state);
-
- public IBuildStage withCity(String city);
-
- public IBuildStage withCountry(String country);
-
- public DuoAuthDevice build();
- }
-
- /**
- * Builder to build {@link DuoAuthDevice}.
- */
-
- public static final class Builder implements IIpStage, INameStage, IBuildStage {
- private String ip;
-
- private String name;
-
- private String state;
-
- private String city;
-
- private String country;
-
- private Builder() {
- }
-
- @Override
- public INameStage withIp(final String ip) {
- this.ip = ip;
- return this;
- }
-
- @Override
- public IBuildStage withName(final String name) {
- this.name = name;
- return this;
- }
-
- @Override
- public IBuildStage withState(final String state) {
- this.state = state;
- return this;
- }
-
- @Override
- public IBuildStage withCity(final String city) {
- this.city = city;
- return this;
- }
-
- @Override
- public IBuildStage withCountry(final String country) {
- this.country = country;
- return this;
- }
-
- @Override
- public DuoAuthDevice build() {
- return new DuoAuthDevice(this);
- }
- }
-
-
-
-}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthToken.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthToken.java
deleted file mode 100644
index 954bca1..0000000
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoAuthToken.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/* Licensed to the University Corporation for Advanced Internet Development,
- * Inc. (UCAID) under one or more contributor license agreements. See the
- * NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The UCAID 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 net.shibboleth.idp.plugin.authn.duo.model;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-
-/**
- * <p>A Duo authentication token which describes the result of 2FA.</p>
- *
- * <p>Analogous in part to an OIDC token. Some descriptions are taken from the
- * OpenID connect core 1.0 specification, some from the DuoAPI spec (https://duo.com/docs/authapi).</p>
- *
- * <p>Includes a staged builder for fluent generation.</p>
- *
- */
- at Immutable
-public final class DuoAuthToken {
-
- /** The issuer identifier for the issuer of the response.*/
- @Nonnull @NotEmpty private final String iss;
-
- /** the subject identifier.*/
- @Nonnull @NotEmpty private final String sub;
-
- /** Shorthand name by which the End-User wishes to be referred to as.*/
- @Nullable private final String preferredUsername;
-
- /** The audience(s) that this token is indented for.*/
- @Nonnull @NotEmpty private final String aud;
-
- /**
- * Expiration time on or after which the ID Token MUST NOT be accepted for processing.
- * Represented as seconds since UNIX EPOCH
- */
- @Nonnull @NotEmpty private final Integer exp;
-
- /** Time at which the JWT was issued. In seconds since Unix EPOCH.*/
- @Nonnull @NotEmpty private final Double iat;
-
- /** Time when the End-User authentication occurred. In seconds since Unix EPOCH.*/
- @Nullable private final Integer authTime;
-
- /** Human-readable string describing the status of the authentication attempt e.g. 'Login Successful'.*/
- @Nonnull private final String authResultStatusMessage;
-
- /** String detailing the progress or outcome of the authentication attempt e.g. 'allow'.*/
- @Nonnull private final String authResultStatus;
-
- /** Result of 2FA e.g. 'allow'.*/
- @Nonnull private final String authResult;
-
- /** The authentication context. */
- @Nonnull private final DuoAuthContext authContext;
-
-
- /**
- * @return Returns the iss.
- */
- public final String getIss() {
- return iss;
- }
-
- /**
- * @return Returns the sub.
- */
- public final String getSub() {
- return sub;
- }
-
- /**
- * @return Returns the preferred_username.
- */
- public final String getPreferredUsername() {
- return preferredUsername;
- }
-
- /**
- * @return Returns the aud.
- */
- public final String getAud() {
- return aud;
- }
-
- /**
- * @return Returns the exp.
- */
- public final Integer getExp() {
- return exp;
- }
-
- /**
- * @return Returns the iat.
- */
- public final Double getIat() {
- return iat;
- }
-
- /**
- * @return Returns the auth_time.
- */
- public final Integer getAuthTime() {
- return authTime;
- }
-
- /**
- * @return Returns the authResultStatusMessage.
- */
- public final String getAuthResultStatusMessage() {
- return authResultStatusMessage;
- }
-
- /**
- * @return Returns the authResultStatus.
- */
- public final String getAuthResultStatus() {
- return authResultStatus;
- }
-
- /**
- * @return Returns the authResult.
- */
- public final String getAuthResult() {
- return authResult;
- }
-
- /**
- * @return Returns the authContext.
- */
- public final DuoAuthContext getAuthContext() {
- return authContext;
- }
-
- /**
- * Private constructor, can only be called by this builder.
- *
- * @param builder the builder to build the instance with
- */
- private DuoAuthToken(final Builder builder) {
- this.iss = builder.iss;
- this.sub = builder.sub;
- this.aud = builder.aud;
- this.exp = builder.exp;
- this.iat = builder.iat;
- this.authResultStatusMessage = builder.authResultStatusMessage;
- this.authResultStatus = builder.authResultStatus;
- this.authResult = builder.authResult;
- this.authContext = builder.authContext;
- this.preferredUsername = builder.preferredUsername;
- this.authTime = builder.authTime;
- }
-
- /**
- * Creates builder to build {@link DuoAuthToken}.
- * @return created builder
- */
-
- public static IIssStage builder() {
- return new Builder();
- }
-
-
- public interface IIssStage {
- public ISubStage withIss(String iss);
- }
-
-
- public interface ISubStage {
- public IAudStage withSub(String sub);
- }
-
-
- public interface IAudStage {
- public IExpStage withAud(String aud);
- }
-
-
- public interface IExpStage {
- public IIatStage withExp(Integer exp);
- }
-
-
- public interface IIatStage {
- public IAuthResultStatusMessageStage withIat(Double iat);
- }
-
-
- public interface IAuthResultStatusMessageStage {
- public IAuthResultStatusStage withAuthResultStatusMessage(String authResultStatusMessage);
- }
-
-
- public interface IAuthResultStatusStage {
- public IAuthResultStage withAuthResultStatus(String authResultStatus);
- }
-
-
- public interface IAuthResultStage {
- public IAuthContextStage withAuthResult(String authResult);
- }
-
-
- public interface IAuthContextStage {
- public IBuildStage withAuthContext(DuoAuthContext authContext);
- }
-
-
- public interface IBuildStage {
- public IBuildStage withPreferredUsername(String prefUsername);
-
- public IBuildStage withAuthTime(Integer auth_time);
-
- public DuoAuthToken build();
- }
-
- /**
- * Builder to build {@link DuoAuthToken}.
- */
-
- public static final class Builder implements IIssStage, ISubStage, IAudStage, IExpStage, IIatStage,
- IAuthResultStatusMessageStage, IAuthResultStatusStage, IAuthResultStage, IAuthContextStage, IBuildStage {
- private String iss;
-
- private String sub;
-
- private String aud;
-
- private Integer exp;
-
- private Double iat;
-
- private String authResultStatusMessage;
-
- private String authResultStatus;
-
- private String authResult;
-
- private DuoAuthContext authContext;
-
- private String preferredUsername;
-
- private Integer authTime;
-
- private Builder() {
- }
-
- @Override
- public ISubStage withIss(final String iss) {
- this.iss = iss;
- return this;
- }
-
- @Override
- public IAudStage withSub(final String sub) {
- this.sub = sub;
- return this;
- }
-
- @Override
- public IExpStage withAud(final String aud) {
- this.aud = aud;
- return this;
- }
-
- @Override
- public IIatStage withExp(final Integer exp) {
- this.exp = exp;
- return this;
- }
-
- @Override
- public IAuthResultStatusMessageStage withIat(final Double iat) {
- this.iat = iat;
- return this;
- }
-
- @Override
- public IAuthResultStatusStage withAuthResultStatusMessage(final String authResultStatusMessage) {
- this.authResultStatusMessage = authResultStatusMessage;
- return this;
- }
-
- @Override
- public IAuthResultStage withAuthResultStatus(final String authResultStatus) {
- this.authResultStatus = authResultStatus;
- return this;
- }
-
- @Override
- public IAuthContextStage withAuthResult(final String authResult) {
- this.authResult = authResult;
- return this;
- }
-
- @Override
- public IBuildStage withAuthContext(final DuoAuthContext authContext) {
- this.authContext = authContext;
- return this;
- }
-
- @Override
- public IBuildStage withPreferredUsername(final String prefUsername) {
- this.preferredUsername = prefUsername;
- return this;
- }
-
- @Override
- public IBuildStage withAuthTime(final Integer authTime) {
- this.authTime = authTime;
- return this;
- }
-
- @Override
- public DuoAuthToken build() {
- return new DuoAuthToken(this);
- }
- }
-
-
-
-
-
-
-}
diff --git a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoHealthCheckResponse.java b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoHealthCheckResponse.java
index 8624b91..2e46d7c 100644
--- a/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoHealthCheckResponse.java
+++ b/idp-duo-api/src/main/java/net/shibboleth/idp/plugin/authn/duo/model/DuoHealthCheckResponse.java
@@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
public final class DuoHealthCheckResponse {
/** The response timestamp in seconds since Unix EPOCH.*/
- private final Integer timestamp;
+ @Nonnull private final Integer timestamp;
public DuoHealthCheckResponse(@Nonnull @JsonProperty("timestamp") final Integer time) {
timestamp = time;
@@ -19,7 +19,7 @@ public final class DuoHealthCheckResponse {
*
* @return the response timestamp.
*/
- public Integer getTimestamp() {
+ @Nonnull public Integer getTimestamp() {
return timestamp;
}
@Override
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DefaultDuoOIDCClientRegistry.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DefaultDuoOIDCClientRegistry.java
index 14142a8..90aaeae 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DefaultDuoOIDCClientRegistry.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DefaultDuoOIDCClientRegistry.java
@@ -104,7 +104,7 @@ public class DefaultDuoOIDCClientRegistry extends AbstractIdentifiableInitializa
//this is an atomic call, avoiding the need to synchronise here e.g. two clients should never
//be created for the same integration.
final DuoOIDCClient client = clientRegistry.computeIfAbsent(integration,clientRegistryMappingFunction);
- log.trace("Duo registry returning DuoClient of type '{}'",client.getClass().getCanonicalName());
+ log.debug("Duo registry returning the DuoClient instance '{}' of type '{}'",client.getClientId(),client.getClass().getCanonicalName());
return client;
} catch (final DuoClientInitializationException e) {
throw new DuoRegistryException("DuoClient could not be found or created in the registry",e);
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DuoSupport.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DuoSupport.java
index 0ef5f5e..86ac5da 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DuoSupport.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/DuoSupport.java
@@ -115,7 +115,7 @@ public final class DuoSupport {
*
* @throws DuoException if the nonce component can not be found.
*/
- public static String extractNonceFromState(@Nonnull final String state) throws DuoException{
+ @Nonnull public static String extractNonceFromState(@Nonnull final String state) throws DuoException{
Constraint.isNotNull(state, "State can not be null");
final String[] stateSplit = state.split("\\.");
diff --git a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
index 8868596..480715c 100644
--- a/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
+++ b/idp-duo-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/impl/ValidateDuoTokenAuthenticationResult.java
@@ -45,7 +45,6 @@ import net.shibboleth.idp.authn.duo.DuoPrincipal;
import net.shibboleth.idp.plugin.authn.duo.DuoException;
import net.shibboleth.idp.plugin.authn.duo.DuoOIDCAuthAPI;
import net.shibboleth.idp.plugin.authn.duo.context.DuoOIDCAuthenticationContext;
-import net.shibboleth.idp.plugin.authn.duo.model.DuoAuthToken;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
diff --git a/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml b/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
index ab03186..7514a71 100644
--- a/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
+++ b/idp-duo-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/DuoOIDC/duo-oidc-authn-beans.xml
@@ -50,7 +50,8 @@
<!-- Can override one or more of the beans above. Note, the property override is mostly to allow tests
to change the location of the user config file. -->
- <import resource="%{idp.home}%{idp.duo.oidc.user.config.home:/conf/authn/duo-authn-config.xml}" />
+ <!-- FIXME: Add this back in as conditional import
+ <import resource="%{idp.home}%{idp.duo.oidc.user.config.home:/conf/authn/duo-authn-config.xml}" />-->
diff --git a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
index d8715b5..9fc31de 100644
--- a/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
+++ b/idp-duo-impl/src/test/java/net/shibboleth/idp/plugin/authn/duo/impl/AbstractDuoActionTest.java
@@ -48,7 +48,7 @@ import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.plugin.authn.duo.DefaultDuoOIDCIntegration;
import net.shibboleth.idp.plugin.authn.duo.context.DuoOIDCAuthenticationContext;
-import net.shibboleth.idp.profile.RequestContextBuilder;
+import net.shibboleth.idp.profile.testing.RequestContextBuilder;
import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
import net.shibboleth.utilities.java.support.codec.Base64Support;
diff --git a/idp-duo-native-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/sdk/impl/DuoSDKClientAdaptor.java b/idp-duo-native-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/sdk/impl/DuoSDKClientAdaptor.java
index 7dd4086..1de0845 100644
--- a/idp-duo-native-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/sdk/impl/DuoSDKClientAdaptor.java
+++ b/idp-duo-native-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/sdk/impl/DuoSDKClientAdaptor.java
@@ -3,6 +3,7 @@ package net.shibboleth.idp.plugin.authn.duo.sdk.impl;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
+import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -62,6 +63,9 @@ final class DuoSDKClientAdaptor implements DuoOIDCClient{
/** Save off the integration to help generate the JWT.*/
@Nonnull private DuoOIDCIntegration duoIntegration;
+
+ /** The client instance UUID.*/
+ @Nonnull private String clientId;
/**
@@ -78,6 +82,7 @@ final class DuoSDKClientAdaptor implements DuoOIDCClient{
duoIntegration = Constraint.isNotNull(integration,"Duo SDK Client requires a non-null Duo Integration");
healthCheckResponseConverter = new DefaultHealthCheckResponseConverter();
tokenResponseConverter = new DefaultTokenResponseConverter();
+ clientId = UUID.randomUUID().toString();
log.info("Secret has size '{}'",integration.getSecretKey().getBytes().length);
try {
if (caCerts == null) {
@@ -214,6 +219,11 @@ final class DuoSDKClientAdaptor implements DuoOIDCClient{
}
+ @Override
+ public String getClientId() {
+ return clientId;
+ }
+
}
diff --git a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/DuoHttpClientFactoryBean.java b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/DuoHttpClientFactoryBean.java
new file mode 100644
index 0000000..a8d76de
--- /dev/null
+++ b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/DuoHttpClientFactoryBean.java
@@ -0,0 +1,18 @@
+package net.shibboleth.idp.plugin.authn.duo.nimbus;
+
+import net.shibboleth.idp.plugin.authn.duo.Version;
+
+/**
+ * Factory bean customization for the Duo plugin. Uses the plugin product name and version inside the user_agent string.
+ */
+public class DuoHttpClientFactoryBean extends net.shibboleth.ext.spring.factory.HttpClientFactoryBean {
+
+ /** Constructor. */
+ public DuoHttpClientFactoryBean() {
+ final StringBuilder stringBuilder = new StringBuilder("ShibbolethIdPDuoPlugin/");
+ stringBuilder.append(Version.getVersion());
+ System.out.println("User Agent: "+stringBuilder.toString());
+ setUserAgent(stringBuilder.toString());
+ }
+
+}
diff --git a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClient.java b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClient.java
index ca40079..c90522d 100644
--- a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClient.java
+++ b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClient.java
@@ -38,6 +38,7 @@ import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
+import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -95,6 +96,9 @@ final class NimbusClient implements DuoOIDCClient{
/** JSON object mapper. */
@Nonnull private ObjectMapper objectMapper;
+
+ /** The client instance UUID.*/
+ @Nonnull private String clientId;
/**
* Constructor.
@@ -109,6 +113,7 @@ final class NimbusClient implements DuoOIDCClient{
httpClient = Constraint.isNotNull(client,"Nimbus Client requires a non-null http client");
httpClientSecurityParameters = params;
objectMapper = new ObjectMapper();
+ clientId = UUID.randomUUID().toString();
//TODO: should we validate the integration here e.g. secret key length, or when being set etc.
}
@@ -151,7 +156,7 @@ final class NimbusClient implements DuoOIDCClient{
Constraint.isLessThan(1025, state.length(),"State must be at maximum 1024 characters");
try {
- final String request = NimbusUtils.createJWSForAuthEndpoint(duoIntegration,state, username);
+ final String request = NimbusUtils.createJWSRequestObject(duoIntegration,state, username);
final URI uri = new URIBuilder()
.setScheme(HTTPS)
@@ -250,4 +255,9 @@ final class NimbusClient implements DuoOIDCClient{
}
}
+ @Override
+ public String getClientId() {
+ return clientId;
+ }
+
}
diff --git a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClientFactory.java b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClientFactory.java
index 77eb7a4..dd93d91 100644
--- a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClientFactory.java
+++ b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusClientFactory.java
@@ -19,12 +19,13 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
-/** Abstract factory implementation for the {@link DuoSDKClientAdaptor} for creating clients based
- * on the Nimbus library. */
+/**
+ * <p>Abstract factory implementation for the {@link NimbusClient}.</p>
+ *
+ * <p>Each client instance shares the same, thread-safe, http client and object mapper.</p>
+ */
public class NimbusClientFactory extends AbstractInitializableComponent implements DuoOIDCClientFactory {
- //FIXME: check threadsafety here, as shared with all clients.
-
/** HttpClient for contacting Duo. */
@NonnullAfterInit private HttpClient httpClient;
diff --git a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusUtils.java b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusUtils.java
index 759c231..fc90ff3 100644
--- a/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusUtils.java
+++ b/idp-duo-nimbus-client-impl/src/main/java/net/shibboleth/idp/plugin/authn/duo/nimbus/NimbusUtils.java
@@ -1,6 +1,5 @@
package net.shibboleth.idp.plugin.authn.duo.nimbus;
-import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.Collections;
@@ -27,7 +26,7 @@ public final class NimbusUtils {
/**
* Generate a cryptographically strong random JWT identifier.
*
- * @param length the length of the ID.
+ * @param length the length of the ID. Can not be {@code null}.
*
* @return a cryptographically strong random JWT identifier.
*/
@@ -42,7 +41,7 @@ public final class NimbusUtils {
}
/**
- * Create a signed JWT using the given parameters suitable for the token endpoint.
+ * Create a signed JWT Request object using the given parameters suitable for the token endpoint.
*
* @param duoIntegration the integration used to construct the JWT
* @param state the state
@@ -51,7 +50,7 @@ public final class NimbusUtils {
* @return a signed JWT
*/
//TODO this method and the below should be nimbus, inside oidc-commons, and merged into a single API
- static String createJWSForAuthEndpoint(@Nonnull final DuoOIDCIntegration duoIntegration,
+ static String createJWSRequestObject(@Nonnull final DuoOIDCIntegration duoIntegration,
@Nonnull final String state, @Nonnull final String username) {
final Date expiration = new Date();
expiration.setTime(expiration.getTime() + Duration.ofHours(1).toMillis());
@@ -70,7 +69,7 @@ public final class NimbusUtils {
}
/**
- * Create a signed JWT using the aud and duo integration supplied.
+ * Create a signed JWT using the audience and duo integration supplied.
*
* @param aud the audience of the JWT
* @param duoIntegration the integration used to construct the JWT.
diff --git a/idp-duo-nimbus-client-impl/src/main/resources/duo-client-factory-bean.xml b/idp-duo-nimbus-client-impl/src/main/resources/duo-client-factory-bean.xml
index 31e5fc9..1496ca4 100644
--- a/idp-duo-nimbus-client-impl/src/main/resources/duo-client-factory-bean.xml
+++ b/idp-duo-nimbus-client-impl/src/main/resources/duo-client-factory-bean.xml
@@ -9,14 +9,24 @@
default-init-method="initialize" default-destroy-method="destroy">
- <!-- TODO: do not default to the internal HTTP client -->
<bean id="shibboleth.authn.duo.OIDC.nimbus.clientFactory"
class="net.shibboleth.idp.plugin.authn.duo.nimbus.NimbusClientFactory" scope="singleton"
- p:httpClient="#{getObject('shibboleth.authn.Duo.OIDC') ?: getObject('shibboleth.InternalHttpClient')}"
+ p:httpClient="#{getObject('shibboleth.authn.Duo.OIDC.HttpClient') ?: getObject('shibboleth.authn.Duo.OIDC.InternalHttpClient')}"
p:objectMapper-ref="shibboleth.authn.duo.OIDC.JSONObjectMapper">
</bean>
+ <!-- Create a default HTTP Client using the global http settings overrides -->
+ <bean id="shibboleth.authn.Duo.OIDC.InternalHttpClient" class="net.shibboleth.idp.plugin.authn.duo.nimbus.DuoHttpClientFactoryBean" lazy-init="true"
+ p:tLSSocketFactory="#{ %{idp.httpclient.useTrustEngineTLSSocketFactory:false} or %{idp.httpclient.useSecurityEnhancedTLSSocketFactory:false} ? @'shibboleth.SecurityEnhancedTLSSocketFactory' : null }"
+ p:connectionDisregardTLSCertificate="%{idp.httpclient.connectionDisregardTLSCertificate:false}"
+ p:connectionTimeout="%{idp.httpclient.connectionTimeout:PT1M}"
+ p:connectionRequestTimeout="%{idp.httpclient.connectionRequestTimeout:PT1M}"
+ p:socketTimeout="%{idp.httpclient.socketTimeout:PT1M}"
+ p:maxConnectionsTotal="%{idp.httpclient.maxConnectionsTotal:100}"
+ p:maxConnectionsPerRoute="%{idp.httpclient.maxConnectionsPerRoute:100}" />
+
+ <!-- Create a default object mapper. Setup should not change once injected -->
<bean id="shibboleth.authn.duo.OIDC.JSONObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" />
<bean class="org.springframework.beans.factory.config.MethodInvokingBean"
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list