[java-plugin-shibd] branch main updated: Add inline secrets to Agents, wire in authentication beans.
Scott Cantor
cantor.2 at osu.edu
Thu May 23 16:33:31 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-plugin-shibd.
View the commit online:
http://git.shibboleth.net/view/?p=java-plugin-shibd.git;a=commit;h=6aade001a2a7a6092235c6b2504b961bde360a8b
The following commit(s) were added to refs/heads/main by this push:
new 6aade00 Add inline secrets to Agents, wire in authentication beans.
6aade00 is described below
commit 6aade001a2a7a6092235c6b2504b961bde360a8b
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu May 23 12:33:28 2024 -0400
Add inline secrets to Agents, wire in authentication beans.
---
.../idp/flows/sp/abstract/sp-abstract-beans.xml | 106 +++++++++++++++++-
.../shibboleth/idp/module/conf/sp/sp.properties | 6 +-
.../net/shibboleth/sp/conf/agents-system.xml | 2 +-
.../src/main/java/net/shibboleth/sp/Agent.java | 10 ++
.../authn/impl/AgentSecretCredentialValidator.java | 117 +++++++++++++++++++
.../java/net/shibboleth/sp/impl/BasicAgent.java | 22 +++-
.../impl/AgentSecretCredentialValidatorTest.java | 124 +++++++++++++++++++++
7 files changed, 381 insertions(+), 6 deletions(-)
diff --git a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/abstract/sp-abstract-beans.xml b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/abstract/sp-abstract-beans.xml
index 2ebd014..c32e617 100644
--- a/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/abstract/sp-abstract-beans.xml
+++ b/sp-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/abstract/sp-abstract-beans.xml
@@ -42,7 +42,7 @@
<bean id="ValidateCachedAuthentication"
class="net.shibboleth.sp.authn.impl.ValidateCachedAuthentication" scope="prototype"
p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"
- p:cookieName="%{sp.agent.cachedAuthentication.cookie:__Host-shibsp_agent_token}"
+ p:cookieName="%{sp.agent.authn.cached.cookieName:__Host-shibsp_agent_token}"
p:cookieManager-ref="sp.CookieManager"
p:dataSealer-ref="shibboleth.DataSealer" />
@@ -51,6 +51,108 @@
p:httpOnly="true"
p:cookieDomain=""
p:cookiePath="/"
- p:maxAge="%{sp.agent.cachedAuthentication.maxAge:3600}" />
+ p:maxAge="%{sp.agent.authn.cached.maxAge:3600}" />
+
+ <bean id="ValidateCredentials"
+ class="net.shibboleth.idp.authn.impl.ValidateCredentials" scope="prototype"
+ p:requireAll="%{sp.agent.authn.requireAll:false}"
+ p:validators="#{getObject('shibboleth.AgentValidators') ?: getObject('DefaultAgentValidators')}"
+ p:cleanupHook-ref="DefaultCleanupHook" />
+
+ <bean id="DefaultCleanupHook"
+ class="net.shibboleth.idp.authn.impl.ValidateCredentials.UsernamePasswordCleanupHook" />
+
+ <!-- ======== Beans for agent authentication ======== -->
+
+ <util:list id="DefaultAgentValidators">
+ <ref bean="shibboleth.AgentSecretValidator" />
+ </util:list>
+
+ <!-- Validator parent beans -->
+
+ <bean id="shibboleth.CredentialValidator" abstract="true"
+ p:savePasswordToCredentialSet="%{sp.agent.authn.retainAsPrivateCredential:false}" />
+
+ <bean id="shibboleth.AgentSecretValidator" parent="shibboleth.CredentialValidator"
+ class="net.shibboleth.sp.authn.impl.AgentSecretCredentialValidator"
+ p:id="spagent-internal" />
+
+ <bean id="shibboleth.JAASValidator" parent="shibboleth.CredentialValidator"
+ class="net.shibboleth.idp.authn.impl.JAASCredentialValidator" abstract="true"
+ p:id="spagent-jaas" />
+
+ <bean id="shibboleth.KerberosValidator" parent="shibboleth.CredentialValidator"
+ class="net.shibboleth.idp.authn.impl.KerberosCredentialValidator" abstract="true"
+ p:id="spagent-krb5" />
+
+ <bean id="shibboleth.LDAPValidator" parent="shibboleth.CredentialValidator" lazy-init="true"
+ class="net.shibboleth.idp.authn.impl.LDAPCredentialValidator"
+ p:id="spagent-ldap"
+ p:authenticator-ref="shibboleth.authn.LDAP.authenticator" />
+
+ <bean id="shibboleth.HTPasswdValidator" abstract="true"
+ class="net.shibboleth.idp.authn.impl.HTPasswdCredentialValidator"
+ p:id="spagent-htpasswd" />
+
+ <bean id="shibboleth.X509Validator" abstract="true"
+ class="net.shibboleth.idp.authn.impl.X509CertificateCredentialValidator"
+ p:id="spagent-x509" />
+
+ <!-- Parent beans for custom ldaptive types. -->
+
+ <bean id="shibboleth.authn.LDAP.authenticator" parent="shibboleth.LDAPAuthenticationFactory"
+ lazy-init="true" />
+
+ <bean id="shibboleth.X509ResourceCredentialConfig"
+ class="net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig" abstract="true" />
+ <bean id="shibboleth.KeystoreResourceCredentialConfig"
+ class="net.shibboleth.idp.authn.impl.KeystoreResourceCredentialConfig" abstract="true" />
+
+ <bean id="shibboleth.authn.LDAP.trustCertificates" parent="shibboleth.X509ResourceCredentialConfig"
+ p:trustCertificates="%{sp.agent.authn.LDAP.trustCertificates:undefined}" />
+ <bean id="shibboleth.authn.LDAP.truststore" parent="shibboleth.KeystoreResourceCredentialConfig"
+ p:truststore="%{sp.agent.authn.LDAP.trustStore:undefined}" />
+
+ <bean id="shibboleth.LDAPAuthenticationFactory" abstract="true"
+ class="net.shibboleth.idp.authn.config.LDAPAuthenticationFactoryBean"
+ p:authenticatorType="#{'%{sp.agent.authn.LDAP.authenticator:anonSearchAuthenticator}'.trim()}"
+ p:trustType="#{'%{sp.agent.authn.LDAP.sslConfig:certificateTrust}'.trim()}"
+ p:connectionStrategyType="#{'%{sp.agent.authn.LDAP.connectionStrategy:ACTIVE_PASSIVE}'.trim()}"
+ p:ldapUrl="%{sp.agent.authn.LDAP.ldapURL:ldap://localhost:10389}"
+ p:useStartTLS="%{sp.agent.authn.LDAP.useStartTLS:true}"
+ p:connectTimeout="%{sp.agent.authn.LDAP.connectTimeout:PT3S}"
+ p:responseTimeout="%{sp.agent.authn.LDAP.responseTimeout:PT3S}"
+ p:trustCertificatesCredentialConfig-ref="shibboleth.authn.OAuth2Client.LDAP.trustCertificates"
+ p:truststoreCredentialConfig-ref="shibboleth.authn.OAuth2Client.LDAP.truststore"
+ p:disablePooling="%{sp.agent.authn.LDAP.disablePooling:false}"
+ p:blockWaitTime="%{sp.agent.authn.pool.LDAP.blockWaitTime:PT3S}"
+ p:minPoolSize="%{sp.agent.authn..pool.LDAP.minSize:3}"
+ p:maxPoolSize="%{sp.agent.authn..pool.LDAP.maxSize:10}"
+ p:validateOnCheckout="%{sp.agent.authn..pool.LDAP.validateOnCheckout:false}"
+ p:validatePeriodically="%{sp.agent.authn..pool.LDAP.validatePeriodically:true}"
+ p:validatePeriod="%{sp.agent.authn..pool.LDAP.validatePeriod:PT5M}"
+ p:validateDn="#{'%{sp.agent.authn..pool.LDAP.validateDN:}'.trim()}"
+ p:validateFilter="#{'%{sp.agent.authn..pool.LDAP.validateFilter:(objectClass=*)}'.trim()}"
+ p:bindPoolPassivatorType="#{'%{sp.agent.authn.LDAP.bindPoolPassivator:none}'.trim()}"
+ p:prunePeriod="%{sp.agent.authn..pool.LDAP.prunePeriod:PT5M}"
+ p:idleTime="%{sp.agent.authn..pool.LDAP.idleTime:PT10M}"
+ p:dnFormat="%{sp.agent.authn.LDAP.dnFormat:undefined}"
+ p:baseDn="#{'%{sp.agent.authn.LDAP.baseDN:undefined}'.trim()}"
+ p:userFilter="#{'%{sp.agent.authn.LDAP.userFilter:undefined}'.trim()}"
+ p:subtreeSearch="%{sp.agent.authn.LDAP.subtreeSearch:false}"
+ p:resolveEntryOnFailure="%{sp.agent.authn.LDAP.resolveEntryOnFailure:false}"
+ p:resolveEntryWithBindDn="%{sp.agent.authn.LDAP.resolveEntryWithBindDN:false}"
+ p:velocityEngine-ref="shibboleth.VelocityEngine"
+ p:bindDn="#{'%{sp.agent.authn.LDAP.bindDN:undefined}'.trim()}"
+ p:bindDnCredential="%{sp.agent.authn.LDAP.bindDNCredential:undefined}"
+ p:usePasswordPolicy="%{sp.agent.authn.LDAP.usePasswordPolicy:false}"
+ p:usePasswordExpiration="%{sp.agent.authn.LDAP.usePasswordExpiration:false}"
+ p:activeDirectory="%{sp.agent.authn.LDAP.activeDirectory:false}"
+ p:freeIPA="%{sp.agent.authn.LDAP.freeIPADirectory:false}"
+ p:EDirectory="%{sp.agent.authn.LDAP.eDirectory:false}"
+ p:accountStateExpirationPeriod="%{sp.agent.authn.LDAP.accountStateExpirationPeriod:#{null}}"
+ p:accountStateWarningPeriod="%{sp.agent.authn.LDAP.accountStateWarningPeriod:#{null}}"
+ p:accountStateLoginFailures="%{sp.agent.authn.LDAP.accountStateLoginFailures:0}" />
+
</beans>
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
index 4581ed4..20efc04 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/sp/sp.properties
@@ -22,6 +22,8 @@ sp.encryption.cert = %{idp.home}/credentials/sp/sp-encryption.crt
#sp.encryption.cert.2 = %{idp.home}/credentials/sp/sp-encryption-old.crt
# Set to Basic to require shared secret authentication
-#sp.agent.authentication = None
+#sp.agent.authn.method = None
# Set false to globally disable cookie-based authentication by agents
-#sp.agent.cachedAuhentication = true
\ No newline at end of file
+#sp.agent.authn.cached = true
+#sp.agent.authn.cached.cookieName = __Host-shibsp_agent_token
+#sp.agent.authn.cached.maxAge = 3600
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
index a4ac0e1..35314b8 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/agents-system.xml
@@ -22,7 +22,7 @@
<bean id="shibboleth.Agent" class="net.shibboleth.sp.impl.BasicAgent" abstract="true"
p:allowedAddressRanges="#{{ '127.0.0.1/32', '::1/128' }}"
- p:supportsCachedAuthentication="%{sp.agent.cachedAuhentication:true}" />
+ p:supportsCachedAuthentication="%{sp.agent.authn.cached:true}" />
<bean id="shibboleth.Application" class="net.shibboleth.sp.impl.BasicApplication" abstract="true"
p:metadataResolver-ref="shibboleth.MetadataResolverService"
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/Agent.java b/sp-server-api/src/main/java/net/shibboleth/sp/Agent.java
index 981e94d..d9f71ff 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/Agent.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/Agent.java
@@ -46,6 +46,16 @@ public interface Agent extends IdentifiedComponent {
* @return set of address ranges
*/
@Nonnull Set<IPRange> getAllowedAddressRanges();
+
+ /**
+ * Get the shared secrets configured directly on this agent.
+ *
+ * <p>While it is expected that most secret-based agent authentication will rely on
+ * an external service (e.g., LDAP), direct conifguration can be supported.</p>
+ *
+ * @return set of shared secrets
+ */
+ @Nonnull Set<String> getSharedSecrets();
/**
* Returns true iff the supplied address matches one of the allowed ranges.
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidator.java b/sp-server-impl/src/main/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidator.java
new file mode 100644
index 0000000..8a6f9bb
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidator.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed 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.sp.authn.impl;
+
+import java.util.function.Function;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.opensaml.messaging.context.navigate.ChildContextLookup;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+
+import net.shibboleth.idp.authn.AbstractUsernamePasswordCredentialValidator;
+import net.shibboleth.idp.authn.AuthnEventIds;
+import net.shibboleth.idp.authn.CredentialValidator;
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.UsernamePasswordContext;
+import net.shibboleth.shared.annotation.constraint.NonnullBeforeExec;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
+import net.shibboleth.sp.Agent;
+import net.shibboleth.sp.context.AgentRequestContext;
+
+/**
+ * Simple {@link CredentialValidator} implementation that relies on the shared secrets configured
+ * directly against {@link Agent} instances.
+ */
+public class AgentSecretCredentialValidator extends AbstractUsernamePasswordCredentialValidator {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(AgentSecretCredentialValidator.class);
+
+ /** Lookup strategy for {@link AgentRequestContext}. */
+ @Nonnull private Function<ProfileRequestContext,AgentRequestContext> agentRequestContextLookupStrategy;
+
+ /** Cached agent from context. */
+ @NonnullBeforeExec private Agent agent;
+
+ /** Constructor. */
+ public AgentSecretCredentialValidator() {
+ agentRequestContextLookupStrategy = new ChildContextLookup<>(AgentRequestContext.class);
+ }
+
+ /**
+ * Sets the lookup strategy for the {@link AgentRequestContext}.
+ *
+ * @param strategy lookup strategy
+ */
+ public void setAgentRequestContextLookupStrategy(
+ @Nonnull final Function<ProfileRequestContext,AgentRequestContext> strategy) {
+ checkSetterPreconditions();
+
+ agentRequestContextLookupStrategy = Constraint.isNotNull(strategy,
+ "AgentRequestContext lookup strategy cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nullable protected Subject doValidate(@Nonnull final ProfileRequestContext profileRequestContext,
+ @Nonnull final AuthenticationContext authenticationContext,
+ @Nonnull final UsernamePasswordContext usernamePasswordContext,
+ @Nullable final WarningHandler warningHandler, @Nullable final ErrorHandler errorHandler)
+ throws Exception {
+
+ final AgentRequestContext agentContext = agentRequestContextLookupStrategy.apply(profileRequestContext);
+ final Agent agent = agentContext != null ? agentContext.getAgent() : null;
+ if (agent == null) {
+ log.error("{} Agent missing from request context", getLogPrefix());
+ final LoginException e = new LoginException(EventIds.INVALID_PROFILE_CTX);
+ if (errorHandler != null) {
+ errorHandler.handleError(profileRequestContext, authenticationContext, e,
+ EventIds.INVALID_PROFILE_CTX);
+ }
+ throw e;
+ }
+
+ if (agent.getSharedSecrets().isEmpty()) {
+ log.debug("{} No shared secrets configured for agent '{}', ignoring", getLogPrefix(), agent.getId());
+ return null;
+ }
+
+ log.debug("{} Attempting to authenticate agent '{}' ", getLogPrefix(), agent.getId());
+
+ for (final String candidate : agent.getSharedSecrets()) {
+ if (candidate.equals(usernamePasswordContext.getPassword())) {
+ log.info("{} Authentication of agent '{}' succeeded", getLogPrefix(), agent.getId());
+ return populateSubject(new Subject(), usernamePasswordContext);
+ }
+ }
+
+ log.info("{} Authentication of agent '{}' failed", getLogPrefix(), agent.getId());
+
+ final LoginException e = new LoginException(AuthnEventIds.INVALID_CREDENTIALS);
+ if (errorHandler != null) {
+ errorHandler.handleError(profileRequestContext, authenticationContext, e,
+ AuthnEventIds.INVALID_CREDENTIALS);
+ }
+ throw e;
+ }
+
+}
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicAgent.java b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicAgent.java
index 191ad54..fc72d5f 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicAgent.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicAgent.java
@@ -51,6 +51,9 @@ public class BasicAgent extends DefaultRelyingPartyConfigurationResolver impleme
/** Allowed address ranges. */
@Nonnull private Set<IPRange> allowedAddressRanges;
+ /** Internally configured shared secrets. */
+ @Nonnull private Set<String> sharedSecrets;
+
/** Application map. */
@Nonnull private Map<String,Application> applicationMap;
@@ -61,6 +64,7 @@ public class BasicAgent extends DefaultRelyingPartyConfigurationResolver impleme
public BasicAgent() {
supportsCachedAuthentication = true;
allowedAddressRanges = CollectionSupport.emptySet();
+ sharedSecrets = CollectionSupport.emptySet();
applicationMap = CollectionSupport.emptyMap();
issuerLookupStrategy = FunctionSupport.constant(null);
}
@@ -80,13 +84,29 @@ public class BasicAgent extends DefaultRelyingPartyConfigurationResolver impleme
allowedAddressRanges = ranges != null ? CollectionSupport.copyToSet(ranges) : CollectionSupport.emptySet();
}
-
+
/** {@inheritDoc} */
public boolean isAllowed(@Nonnull final InetAddress address) {
checkComponentActive();
return allowedAddressRanges.stream().anyMatch(r -> r.contains(address));
}
+
+ /** {@inheritDoc} */
+ @Nonnull public Set<String> getSharedSecrets() {
+ return sharedSecrets;
+ }
+
+ /**
+ * Sets the shared secrets to store directly in this agent.
+ *
+ * @param secrets shared secrets for agent authentication
+ */
+ public void setSharedSecrets(@Nullable final Set<String> secrets) {
+ checkSetterPreconditions();
+
+ sharedSecrets = secrets != null ? CollectionSupport.copyToSet(secrets) : CollectionSupport.emptySet();
+ }
/** {@inheritDoc} */
public boolean isSupportsCachedAuthentication() {
diff --git a/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidatorTest.java b/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidatorTest.java
new file mode 100644
index 0000000..94b95d9
--- /dev/null
+++ b/sp-server-impl/src/test/java/net/shibboleth/sp/authn/impl/AgentSecretCredentialValidatorTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed 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.sp.authn.impl;
+
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.opensaml.profile.testing.RequestContextBuilder;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.UsernamePasswordContext;
+import net.shibboleth.idp.authn.principal.UsernamePrincipal;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.sp.context.AgentRequestContext;
+import net.shibboleth.sp.impl.BasicAgent;
+
+/**
+ * Unit test for {@link AgentSecretCredentialValidator}.
+ */
+ at SuppressWarnings("javadoc")
+public class AgentSecretCredentialValidatorTest {
+
+ private ProfileRequestContext prc;
+ private AuthenticationContext ac;
+ private UsernamePasswordContext upc;
+ private MockHttpServletRequest request;
+
+ private BasicAgent agent;
+ private AgentSecretCredentialValidator validator;
+
+ @BeforeMethod
+ public void setUp() throws ComponentInitializationException {
+ prc = new RequestContextBuilder().buildProfileRequestContext();
+ ac = prc.ensureSubcontext(AuthenticationContext.class);
+ upc = ac.ensureSubcontext(UsernamePasswordContext.class);
+ upc.setUsername("foo");
+
+ agent = new BasicAgent();
+ agent.setId("foo");
+ agent.setSharedSecrets(CollectionSupport.setOf("zork", "enchanter"));
+ agent.initialize();
+
+ validator = new AgentSecretCredentialValidator();
+ validator.setId("test");
+ validator.initialize();
+ }
+
+ @Test
+ public void testNoAgent() {
+ try {
+ validator.validate(prc, ac, null, null);
+ Assert.fail("Validator should have thrown");
+ } catch (final Exception e) {
+ Assert.assertTrue(e instanceof LoginException);
+ }
+ }
+
+ @Test
+ public void testSuccess() {
+ prc.ensureSubcontext(AgentRequestContext.class).setAgent(agent);
+ upc.setPassword("enchanter");
+
+ try {
+ final Subject subject = validator.validate(prc, ac, null, null);
+ assert subject != null;
+ final Set<UsernamePrincipal> principals = subject.getPrincipals(UsernamePrincipal.class);
+ Assert.assertTrue(principals.contains(new UsernamePrincipal(agent.getId())));
+ } catch (final Exception e) {
+ Assert.fail("Validator should not have thrown");
+ }
+ }
+
+ @Test
+ public void testFailure() {
+ prc.ensureSubcontext(AgentRequestContext.class).setAgent(agent);
+ upc.setPassword("foo");
+
+ try {
+ validator.validate(prc, ac, null, null);
+ Assert.fail("Validator should have thrown");
+ } catch (final Exception e) {
+ Assert.assertTrue(e instanceof LoginException);
+ }
+ }
+
+ @Test
+ public void testIgnored() throws ComponentInitializationException {
+
+ agent = new BasicAgent();
+ agent.setId("foo");
+ agent.initialize();
+
+ prc.ensureSubcontext(AgentRequestContext.class).setAgent(agent);
+ upc.setPassword("enchanter");
+
+ try {
+ final Subject subject = validator.validate(prc, ac, null, null);
+ Assert.assertNull(subject);
+ } catch (final Exception e) {
+ Assert.fail("Validator should not have thrown");
+ }
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list