[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