[java-identity-provider] branch master updated: IDP-1252 - Account lockout manager needs documented means of management
Scott Cantor
cantor.2 at osu.edu
Wed Jan 31 16:54:57 EST 2018
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=4bd2251fdbf5a1dfdf0bb4454beffd94493fb20f
The following commit(s) were added to refs/heads/master by this push:
new 4bd2251 IDP-1252 - Account lockout manager needs documented means of management
4bd2251 is described below
commit 4bd2251fdbf5a1dfdf0bb4454beffd94493fb20f
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jan 31 16:54:54 2018 -0500
IDP-1252 - Account lockout manager needs documented means of management
https://issues.shibboleth.net/jira/browse/IDP-1252
---
.../idp/authn/context/LockoutManagerContext.java | 61 +++++
idp-authn-impl/pom.xml | 5 +
.../idp/authn/impl/DoLockoutManagerOperation.java | 290 +++++++++++++++++++++
.../impl/StorageBackedAccountLockoutManager.java | 13 +-
.../main/resources/conf/admin/general-admin.xml | 6 +
idp-conf/src/main/resources/conf/global.xml | 1 -
.../main/resources/system/conf/global-system.xml | 9 +
.../src/main/resources/system/conf/mvc-beans.xml | 1 +
.../main/resources/system/conf/webflow-config.xml | 1 +
.../resources/system/flows/admin/lockout-beans.xml | 43 +++
.../resources/system/flows/admin/lockout-flow.xml | 43 +++
.../system/flows/authn/password-authn-beans.xml | 9 -
12 files changed, 471 insertions(+), 11 deletions(-)
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/LockoutManagerContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/LockoutManagerContext.java
new file mode 100644
index 0000000..e6320a8
--- /dev/null
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/LockoutManagerContext.java
@@ -0,0 +1,61 @@
+/*
+ * 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.authn.context;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.opensaml.messaging.context.BaseContext;
+
+/**
+ * A context that holds information about a management operation on an
+ * {@link net.shibboleth.idp.authn.AccountLockoutManager}.
+ *
+ * @parent {@link org.opensaml.profile.context.ProfileRequestContext}
+ * @added After the initiation of an administrative operation against a lockout manager.
+ *
+ * @since 3.4.0
+ */
+public class LockoutManagerContext extends BaseContext {
+
+ /** Account lockout key. */
+ @Nullable private String key;
+
+ /**
+ * Get the account lockout key to check or modify.
+ *
+ * @return account lockout key
+ */
+ @Nullable public String getKey() {
+ return key;
+ }
+
+ /**
+ * Set the account lockout key to check or modify.
+ *
+ * @param k account lockout key
+ *
+ * @return this context
+ */
+ @Nonnull public LockoutManagerContext setKey(@Nullable final String k) {
+ key = k;
+
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/idp-authn-impl/pom.xml b/idp-authn-impl/pom.xml
index fa55087..e9dac8a 100644
--- a/idp-authn-impl/pom.xml
+++ b/idp-authn-impl/pom.xml
@@ -66,6 +66,11 @@
</dependency>
<dependency>
+ <groupId>com.github.jasminb</groupId>
+ <artifactId>jsonapi-converter</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>${spring-webflow.groupId}</groupId>
<artifactId>spring-webflow</artifactId>
</dependency>
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java
new file mode 100644
index 0000000..f6cee98
--- /dev/null
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/DoLockoutManagerOperation.java
@@ -0,0 +1,290 @@
+/*
+ * 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.authn.impl;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import net.shibboleth.idp.authn.AccountLockoutManager;
+import net.shibboleth.idp.authn.context.LockoutManagerContext;
+import net.shibboleth.idp.profile.AbstractProfileAction;
+import net.shibboleth.idp.profile.context.SpringRequestContext;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+import org.opensaml.profile.action.ActionSupport;
+import org.opensaml.profile.action.EventIds;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.webflow.execution.RequestContext;
+
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.jasminb.jsonapi.models.errors.Error;
+import com.github.jasminb.jsonapi.models.errors.Errors;
+import com.google.common.base.Strings;
+
+/**
+ * Action that implements a JSON REST API for the {@link AccountLockoutManager} interface.
+ *
+ * <p>The API supports GET, POST, and DELETE at the moment, using jsonapi.org conventions.</p>
+ *
+ * <dl>
+ * <dt>GET</dt>
+ * <dd>Check for lockout.</dd>
+ *
+ * <dt>POST</dt>
+ * <dd>Increment lockout.</dd>
+ *
+ * <dt>DELETE</dt>
+ * <dd>Clear lockout count.</dd>
+ * </dl>
+ *
+ * @event {@link EventIds#PROCEED_EVENT_ID}
+ * @event {@link EventIds#INVALID_PROFILE_CTX}
+ * @event {@link EventIds#IO_ERROR}
+ */
+public class DoLockoutManagerOperation extends AbstractProfileAction {
+
+ /** Flow variable indicating ID of manager bean to access. */
+ @Nonnull @NotEmpty public static final String MANAGER_ID = "lockoutManagerId";
+
+ /** Flow variable indicating ID of account key. */
+ @Nonnull @NotEmpty public static final String KEY = "key";
+
+ /** Class logger. */
+ @Nonnull private Logger log = LoggerFactory.getLogger(DoLockoutManagerOperation.class);
+
+ /** JSON object mapper. */
+ @NonnullAfterInit private ObjectMapper objectMapper;
+
+ /** Manager ID to operate on. */
+ @Nullable @NotEmpty private String managerId;
+
+ /** Account key to operate on. */
+ @Nullable @NotEmpty private String key;
+
+ /** {@link AccountLockoutManager} to operate on. */
+ @Nullable private AccountLockoutManager lockoutManager;
+
+ /**
+ * Set the JSON {@link ObjectMapper} to use for serialization.
+ *
+ * @param mapper object mapper
+ */
+ public void setObjectMapper(@Nonnull final ObjectMapper mapper) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ objectMapper = Constraint.isNotNull(mapper, "ObjectMapper cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (objectMapper == null) {
+ throw new ComponentInitializationException("ObjectMapper cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected boolean doPreExecute(final ProfileRequestContext profileRequestContext) {
+
+ if (!super.doPreExecute(profileRequestContext)) {
+ return false;
+ } else if (getHttpServletRequest() == null || getHttpServletResponse() == null) {
+ log.warn("{} No HttpServletRequest or HttpServletResponse available", getLogPrefix());
+ ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ return false;
+ }
+
+ try {
+ final SpringRequestContext springRequestContext =
+ profileRequestContext.getSubcontext(SpringRequestContext.class);
+ if (springRequestContext == null) {
+ log.warn("{} Spring request context not found in profile request context", getLogPrefix());
+ sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Internal Server Error", "System misconfiguration.");
+ return false;
+ }
+
+ final RequestContext requestContext = springRequestContext.getRequestContext();
+ if (requestContext == null) {
+ log.warn("{} Web Flow request context not found in Spring request context", getLogPrefix());
+ sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "Internal Server Error", "System misconfiguration.");
+ return false;
+ }
+
+ lockoutManager = getLockoutManager(requestContext);
+ if (lockoutManager == null) {
+ sendError(HttpServletResponse.SC_NOT_FOUND,
+ "Invalid Lockout Manager", "Invalid lockout manager identifier in path.");
+ return false;
+ }
+
+ key = (String) requestContext.getFlowScope().get(KEY);
+ if (Strings.isNullOrEmpty(key)) {
+ sendError(HttpServletResponse.SC_NOT_FOUND,
+ "Missing Account Key", "No account key specified.");
+ return false;
+ }
+
+ } catch (final IOException e) {
+ log.error("{} I/O error issuing API response", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void doExecute(final ProfileRequestContext profileRequestContext) {
+
+ profileRequestContext.getSubcontext(LockoutManagerContext.class, true).setKey(key);
+
+ try {
+ final HttpServletRequest request = getHttpServletRequest();
+ final HttpServletResponse response = getHttpServletResponse();
+
+ response.setContentType("application/json");
+ response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
+
+ if ("GET".equals(request.getMethod())) {
+ try {
+ final boolean lockout = lockoutManager.check(profileRequestContext);
+ response.setStatus(HttpServletResponse.SC_OK);
+ final JsonFactory jsonFactory = new JsonFactory();
+ final JsonGenerator g = jsonFactory.createGenerator(
+ response.getOutputStream()).useDefaultPrettyPrinter();
+ g.setCodec(objectMapper);
+ g.writeStartObject();
+ g.writeObjectFieldStart("data");
+ g.writeStringField("type", "lockout-statuses");
+ g.writeStringField("id", managerId + '/' + key);
+ g.writeObjectFieldStart("attributes");
+ g.writeBooleanField("lockout", lockout);
+ g.close();
+ } catch (final IOException e) {
+ sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error", "Lockout manager error.");
+ }
+
+ } else if ("POST".equals(request.getMethod())) {
+ try {
+ if (lockoutManager.increment(profileRequestContext)) {
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ } else {
+ throw new IOException();
+ }
+ } catch (final IOException e) {
+ sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error", "Lockout manager error.");
+ }
+
+ } else if ("DELETE".equals(request.getMethod())) {
+ try {
+ if (lockoutManager.clear(profileRequestContext)) {
+ response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+ } else {
+ throw new IOException();
+ }
+ } catch (final IOException e) {
+ sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error", "Lockout manager error.");
+ }
+
+ } else {
+ log.warn("{} Invalid method: {}", getLogPrefix(), request.getMethod());
+ sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
+ "Unknown Operation", "Only GET, POST, and DELETE are supported.");
+ }
+
+ } catch (final IOException e) {
+ log.error("{} I/O error responding to request", getLogPrefix(), e);
+ ActionSupport.buildEvent(profileRequestContext, EventIds.IO_ERROR);
+ }
+ }
+
+ /**
+ * Helper method to get the manager bean to operate on.
+ *
+ * @param requestContext current SWF request context
+ *
+ * @return lockout manager or null
+ */
+ @Nullable private AccountLockoutManager getLockoutManager(@Nonnull final RequestContext requestContext) {
+
+ managerId = (String) requestContext.getFlowScope().get(MANAGER_ID);
+ if (managerId == null) {
+ log.warn("{} No {} flow variable found in request", getLogPrefix(), MANAGER_ID);
+ return null;
+ }
+
+ try {
+ final Object bean = requestContext.getActiveFlow().getApplicationContext().getBean(managerId);
+ if (bean != null && bean instanceof AccountLockoutManager) {
+ return (AccountLockoutManager) bean;
+ }
+ } catch (final BeansException e) {
+
+ }
+
+ log.warn("{} No bean of the correct type found named {}", getLogPrefix(), managerId);
+ return null;
+ }
+
+ /**
+ * Output an error object.
+ *
+ * @param status HTTP status
+ * @param title fixed error description
+ * @param detail human-readable error description
+ *
+ * @throws IOException if unable to output the error
+ */
+ private void sendError(final int status, @Nonnull @NotEmpty final String title,
+ @Nonnull @NotEmpty final String detail) throws IOException {
+
+ final HttpServletResponse response = getHttpServletResponse();
+ response.setContentType("application/json");
+ response.setHeader("Cache-Control", "must-revalidate,no-cache,no-store");
+ response.setStatus(status);
+
+ final Error e = new Error();
+ final Errors errors = new Errors();
+ errors.setErrors(Collections.singletonList(e));
+ e.setStatus(Integer.toString(status));
+ e.setTitle(title);
+ e.setDetail(detail);
+
+ objectMapper.writer().withDefaultPrettyPrinter().writeValue(response.getOutputStream(), errors);
+ }
+
+}
\ No newline at end of file
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
index ef8b63f..d6c3550 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
@@ -36,6 +36,7 @@ import com.google.common.base.Function;
import net.shibboleth.idp.authn.AccountLockoutManager;
import net.shibboleth.idp.authn.context.AuthenticationContext;
+import net.shibboleth.idp.authn.context.LockoutManagerContext;
import net.shibboleth.idp.authn.context.UsernamePasswordContext;
import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
@@ -405,10 +406,20 @@ public class StorageBackedAccountLockoutManager extends AbstractIdentifiableInit
/** {@inheritDoc} */
@Nullable public String apply(@Nullable final ProfileRequestContext profileRequestContext) {
- if (profileRequestContext == null || httpRequest == null) {
+ if (profileRequestContext == null) {
return null;
}
+ final LockoutManagerContext lockoutManagerContext =
+ profileRequestContext.getSubcontext(LockoutManagerContext.class);
+ if (lockoutManagerContext != null) {
+ return lockoutManagerContext.getKey();
+ }
+
+ if (httpRequest == null) {
+ return null;
+ }
+
final AuthenticationContext authenticationContext =
profileRequestContext.getSubcontext(AuthenticationContext.class);
if (authenticationContext == null) {
diff --git a/idp-conf/src/main/resources/conf/admin/general-admin.xml b/idp-conf/src/main/resources/conf/admin/general-admin.xml
index 9b3b180..2a8a0e0 100644
--- a/idp-conf/src/main/resources/conf/admin/general-admin.xml
+++ b/idp-conf/src/main/resources/conf/admin/general-admin.xml
@@ -36,6 +36,12 @@
p:loggingId="%{idp.service.logging.resolvertest:ResolverTest}"
p:policyName="%{idp.resolvertest.accessPolicy:AccessByIPAddress}" />
+ <!-- REST AccountLockoutManager Access -->
+ <bean parent="shibboleth.AdminFlow"
+ c:id="http://shibboleth.net/ns/profiles/lockout-manager"
+ p:loggingId="Lockout"
+ p:policyName="AccessByIPAddress" />
+
<!-- REST StorageService Access -->
<bean parent="shibboleth.AdminFlow"
c:id="http://shibboleth.net/ns/profiles/storage"
diff --git a/idp-conf/src/main/resources/conf/global.xml b/idp-conf/src/main/resources/conf/global.xml
index 60562e3..457a814 100644
--- a/idp-conf/src/main/resources/conf/global.xml
+++ b/idp-conf/src/main/resources/conf/global.xml
@@ -49,5 +49,4 @@
</util:map>
-->
-
</beans>
diff --git a/idp-conf/src/main/resources/system/conf/global-system.xml b/idp-conf/src/main/resources/system/conf/global-system.xml
index 10ca95c..4e6102f 100644
--- a/idp-conf/src/main/resources/system/conf/global-system.xml
+++ b/idp-conf/src/main/resources/system/conf/global-system.xml
@@ -265,6 +265,15 @@
<bean id="shibboleth.DefaultIdentifierGenerationStrategy"
class="net.shibboleth.utilities.java.support.security.SecureRandomIdentifierGenerationStrategy" />
+ <bean id="shibboleth.StorageBackedAccountLockoutManager" abstract="true"
+ class="net.shibboleth.idp.authn.impl.StorageBackedAccountLockoutManager"
+ p:storageService-ref="shibboleth.StorageService">
+ <property name="lockoutKeyStrategy">
+ <bean class="net.shibboleth.idp.authn.impl.StorageBackedAccountLockoutManager.UsernameIPLockoutKeyStrategy"
+ p:httpServletRequest-ref="shibboleth.HttpServletRequest" />
+ </property>
+ </bean>
+
<!-- Parent beans for Signature/Encryption/TLS Configuration objects. -->
<bean id="shibboleth.BasicSignatureValidationConfiguration" abstract="true"
diff --git a/idp-conf/src/main/resources/system/conf/mvc-beans.xml b/idp-conf/src/main/resources/system/conf/mvc-beans.xml
index de9468d..c08fb03 100644
--- a/idp-conf/src/main/resources/system/conf/mvc-beans.xml
+++ b/idp-conf/src/main/resources/system/conf/mvc-beans.xml
@@ -18,6 +18,7 @@
<property name="sourceList">
<list>
<value>admin/metrics</value>
+ <value>admin/lockout</value>
<value>admin/storage</value>
</list>
</property>
diff --git a/idp-conf/src/main/resources/system/conf/webflow-config.xml b/idp-conf/src/main/resources/system/conf/webflow-config.xml
index 38a7ac5..46d99b8 100644
--- a/idp-conf/src/main/resources/system/conf/webflow-config.xml
+++ b/idp-conf/src/main/resources/system/conf/webflow-config.xml
@@ -26,6 +26,7 @@
<entry key="admin/resolvertest" value="../system/flows/admin/resolvertest-flow.xml" />
<entry key="admin/reload-service" value="../system/flows/admin/reload-service-flow.xml" />
<entry key="admin/reload-metadata" value="../system/flows/admin/reload-metadata-flow.xml" />
+ <entry key="admin/lockout" value="../system/flows/admin/lockout-flow.xml" />
<entry key="admin/metrics" value="../system/flows/admin/metrics-flow.xml" />
<entry key="admin/storage" value="../system/flows/admin/storage-flow.xml" />
diff --git a/idp-conf/src/main/resources/system/flows/admin/lockout-beans.xml b/idp-conf/src/main/resources/system/flows/admin/lockout-beans.xml
new file mode 100644
index 0000000..e7ea006
--- /dev/null
+++ b/idp-conf/src/main/resources/system/flows/admin/lockout-beans.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans
+ xmlns="http://www.springframework.org/schema/beans"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"
+ p:placeholderPrefix="%{" p:placeholderSuffix="}" />
+
+ <import resource="admin-abstract-beans.xml" />
+
+ <!-- Profile ID for flow. -->
+ <bean id="shibboleth.AdminProfileId" class="java.lang.String" c:_0="http://shibboleth.net/ns/profiles/lockout-manager" />
+
+ <!-- Default operation/resource suppliers for access checks. -->
+
+ <bean id="shibboleth.AdminOperationLookupStrategy" parent="shibboleth.ContextFunctions.Expression"
+ c:outputType="#{T(java.lang.String)}"
+ c:expression="#custom.getMethod()"
+ p:customObject-ref="shibboleth.HttpServletRequest" />
+
+ <bean id="shibboleth.AdminResourceLookupStrategy" parent="shibboleth.ContextFunctions.Expression"
+ c:outputType="#{T(java.lang.String)}"
+ c:expression="#input.getSubcontext(T(net.shibboleth.idp.profile.context.SpringRequestContext)).getRequestContext().getFlowScope().get('context')" />
+
+ <!-- Work beans. -->
+
+ <bean id="DoLockoutManagerOperation" class="net.shibboleth.idp.authn.impl.DoLockoutManagerOperation" scope="prototype"
+ p:httpServletRequest-ref="shibboleth.HttpServletRequest"
+ p:httpServletResponse-ref="shibboleth.HttpServletResponse"
+ p:objectMapper-ref="shibboleth.JSONObjectMapper" />
+
+ <bean id="RecordResponseComplete" class="net.shibboleth.idp.profile.impl.RecordResponseComplete" scope="prototype" />
+
+</beans>
diff --git a/idp-conf/src/main/resources/system/flows/admin/lockout-flow.xml b/idp-conf/src/main/resources/system/flows/admin/lockout-flow.xml
new file mode 100644
index 0000000..1a3fa33
--- /dev/null
+++ b/idp-conf/src/main/resources/system/flows/admin/lockout-flow.xml
@@ -0,0 +1,43 @@
+<flow xmlns="http://www.springframework.org/schema/webflow"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"
+ parent="admin.abstract">
+
+ <on-start>
+ <!-- Extract PATH_INFO containing lockout manager and key. -->
+ <evaluate expression="flowRequestContext.getActiveFlow().getId()" result="flowScope.flowId" />
+ <evaluate expression="externalContext.getNativeRequest().getPathInfo().length() gt flowId.length() + 2 ? externalContext.getNativeRequest().getPathInfo().substring(flowId.length() + 2) : ''" result="flowScope.pathInfo" />
+ <evaluate expression="pathInfo.split('/')" result="flowScope.pathInfoArray" />
+ <evaluate expression="pathInfoArray.length gt 0 ? T(net.shibboleth.utilities.java.support.net.URISupport).doURLDecode(pathInfoArray[0]) : null" result="flowScope.lockoutManagerId" />
+ <evaluate expression="pathInfoArray.length gt 1 ? T(net.shibboleth.utilities.java.support.net.URISupport).doURLDecode(pathInfoArray[1]) : null" result="flowScope.key" />
+ </on-start>
+
+ <!-- Start action. -->
+
+ <action-state id="InitializeProfileRequestContext">
+ <evaluate expression="InitializeProfileRequestContext" />
+ <evaluate expression="'proceed'" />
+
+ <!-- Branch to determine if authentication is required. -->
+ <transition on="proceed" to="DoAdminPreamble" />
+ </action-state>
+
+ <!-- Resume actual flow processing. -->
+
+ <action-state id="DoProfileWork">
+ <evaluate expression="CheckAccess" />
+ <evaluate expression="WriteAuditLog" />
+ <evaluate expression="DoLockoutManagerOperation" />
+ <evaluate expression="RecordResponseComplete" />
+ <evaluate expression="'proceed'" />
+
+ <transition on="proceed" to="end" />
+ </action-state>
+
+ <!-- Terminus -->
+
+ <end-state id="end" />
+
+ <bean-import resource="lockout-beans.xml" />
+
+</flow>
diff --git a/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml b/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
index 75957af..183ef27 100644
--- a/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
@@ -18,15 +18,6 @@
<bean class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
<bean class="net.shibboleth.idp.profile.impl.ProfileActionBeanPostProcessor" />
- <bean id="shibboleth.StorageBackedAccountLockoutManager" abstract="true"
- class="net.shibboleth.idp.authn.impl.StorageBackedAccountLockoutManager"
- p:storageService-ref="shibboleth.StorageService">
- <property name="lockoutKeyStrategy">
- <bean class="net.shibboleth.idp.authn.impl.StorageBackedAccountLockoutManager.UsernameIPLockoutKeyStrategy"
- p:httpServletRequest-ref="shibboleth.HttpServletRequest" />
- </property>
- </bean>
-
<import resource="../../../conf/authn/password-authn-config.xml" />
<bean id="ExtractUsernamePasswordFromBasicAuth"
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list