/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2013 The ZAP Development Team * * 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 org.zaproxy.zap.authentication; import net.sf.json.JSONObject; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.parosproxy.paros.control.Control; import org.parosproxy.paros.db.DatabaseException; import org.parosproxy.paros.extension.ExtensionHook; import org.parosproxy.paros.model.Session; import org.zaproxy.zap.extension.api.ApiAction; import org.zaproxy.zap.extension.api.ApiDynamicActionImplementor; import org.zaproxy.zap.extension.users.ExtensionUserManagement; import org.zaproxy.zap.model.Context; import org.zaproxy.zap.users.User; /** * A type of authentication method. This class also acts as a factory for creating * {@link AuthenticationMethod} objects and for creating the options panels used for configuring * both the {@link AuthenticationMethod} and the {@link AuthenticationCredentials}. * <p> * The implementors of new authentication methods should also implement a corresponding * {@link AuthenticationMethodType}. The system automatically detects and loads Authentication * Method Types and, through them, the corresponding Authentication methods. * </p> * */ public abstract class AuthenticationMethodType { /** * Builds a new, empty, authentication method. The authentication method should then be * configured through the Options panel. * * @param contextId the ID of the context for which the authentication method is being created * @return the authentication method * @see #buildOptionsPanel(Context) */ public abstract AuthenticationMethod createAuthenticationMethod(int contextId); /** * Gets the name of the authentication method. * * @return the name */ public abstract String getName(); /** * Gets the unique identifier of this Authentication Method Type. It has to be unique among all * Authentication Method Types. * * @return the unique identifier */ public abstract int getUniqueIdentifier(); /** * Builds the options panel that can be used to fully configure an authentication method. * <p> * This method just builds an empty options panel. For binding an existing method to the panel, * {@link AbstractAuthenticationMethodOptionsPanel#bindMethod(AuthenticationMethod)} should be * used. * </p> * * @param uiSharedContext the shared context on which the panel should work * @return the abstract authentication method options panel * @see #hasOptionsPanel() */ public abstract AbstractAuthenticationMethodOptionsPanel buildOptionsPanel(Context uiSharedContext); /** * Checks if the corresponding {@link AuthenticationMethod} has an options panel that can be * used for configuration. * * @return true, if it needs one * @see #buildOptionsPanel(Context) */ public abstract boolean hasOptionsPanel(); /** * Builds the options panel that can be used to fully configure an. * * @param credentials the credentials * @param uiSharedContext the shared context on which the panel should work * @return the abstract credentials options panel {@link AuthenticationCredentials} object. */ public abstract AbstractCredentialsOptionsPanel<? extends AuthenticationCredentials> buildCredentialsOptionsPanel( AuthenticationCredentials credentials, Context uiSharedContext); /** * Checks if the corresponding {@link AuthenticationCredentials} has an options panel that can * be used for its configuration. * * @return true, if it needs one */ public abstract boolean hasCredentialsOptionsPanel(); /** * Checks if is this is a type for the Authentication Method provided as parameter. * * @param method the method * @return true, if is factory for method */ public abstract boolean isTypeForMethod(AuthenticationMethod method); /** * Hooks the Authentication Method Type with other components of ZAP, if needed. This method * should is called only ones, when authentication types are loaded. * <p> * For example, PopupMenus can be registered. * </p> * * @param extensionHook the extension hook */ public abstract void hook(ExtensionHook extensionHook); /** * Loads an authentication method from the Session. The implementation depends on the * Authentication method type. * * @param session the session * @param contextId the ID of the context * @return the authentication method * @throws DatabaseException if an error occurred while loading the authentication method */ public abstract AuthenticationMethod loadMethodFromSession(Session session, int contextId) throws DatabaseException; /** * Persists the authentication method to the session. * * @param session the session * @param contextId the context id * @param authMethod the auth method to persist * @throws UnsupportedAuthenticationMethodException the unsupported authentication method * exception * @throws DatabaseException if an error occurred while persisting the authentication method */ public abstract void persistMethodToSession(Session session, int contextId, AuthenticationMethod authMethod) throws DatabaseException; /** * Export the specified method to the configuration * @param config the {@code Configuration} where to export/save the authentication method * @param authMethod the authentication method to be exported */ public abstract void exportData(Configuration config, AuthenticationMethod authMethod); /** * Import the method from the configuration * @param config the {@code Configuration} from where to import/load the authentication method * @param authMethod where to set the imported authentication method data * @throws ConfigurationException if an error occurred while reading the authentication method data */ public abstract void importData(Configuration config, AuthenticationMethod authMethod) throws ConfigurationException; @Override public String toString() { return getName(); } /** * Creates a new, empty, Authentication Credentials object corresponding to this type of * Authentication method. * * @return the authentication credentials */ public abstract AuthenticationCredentials createAuthenticationCredentials(); /** * Gets the {@link ApiAction} that can be used to set an authentication method of this type for * a context. * <p> * This api action will be handled by executing the * {@link ApiDynamicActionImplementor#handleAction(JSONObject)} method. * </p> * <p> * In the {@link ApiDynamicActionImplementor#handleAction(JSONObject)} method, if the new type * of method differs from the current type of method, a call should be made to * {@link #apiChangedAuthenticationMethodForContext(int)} to make sure changes are propagated. * </p> * * @return the api action, or null if there is no way to set this method type through the API */ public abstract ApiDynamicActionImplementor getSetMethodForContextApiAction(); /** * Gets the {@link ApiDynamicActionImplementor} that can be used to set the authentication * credentials of the corresponding type for an {@link User} of a context. * <p> * This api action will be handled by executing the * {@link ApiDynamicActionImplementor#handleAction(JSONObject)} method. * </p> * * @return the api action, or null if there is no way to set this method type through the API */ public abstract ApiDynamicActionImplementor getSetCredentialsForUserApiAction(); /** * Called when the authentication method for a context is changed through an API call. * <p> * Makes sure the Users are wiped so the authentication credentials for them match the Method. * </p> * * @param contextId the context id */ protected static void apiChangedAuthenticationMethodForContext(int contextId) { // Make sure the Users are wiped so the authentication credentials for them match the // Method. ExtensionUserManagement usersExtension = (ExtensionUserManagement) Control.getSingleton() .getExtensionLoader().getExtension(ExtensionUserManagement.NAME); if (usersExtension != null) { if (usersExtension.getContextUserAuthManager(contextId).getUsers().size() > 0) { usersExtension.removeContextUsers(contextId); } } } @Override public int hashCode() { return getUniqueIdentifier(); } @Override public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; return true; } /** * Thrown when an unsupported type of credentials is used with a {@link AuthenticationMethod} . */ public static class UnsupportedAuthenticationMethodException extends RuntimeException { /** The Constant serialVersionUID. */ private static final long serialVersionUID = -9023988233854612561L; public UnsupportedAuthenticationMethodException(String message) { super(message); } } }