org.zaproxy.zap.authentication.AuthenticationMethod Maven / Gradle / Ivy
Show all versions of zap Show documentation
/*
* 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 java.util.regex.Pattern;
import org.apache.commons.httpclient.URIException;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.api.ApiResponse;
import org.zaproxy.zap.model.Context;
import org.zaproxy.zap.model.SessionStructure;
import org.zaproxy.zap.session.SessionManagementMethod;
import org.zaproxy.zap.session.WebSession;
import org.zaproxy.zap.users.User;
import org.zaproxy.zap.utils.Stats;
/**
* The {@code AuthenticationMethod} represents an authentication method that can be used to authenticate an
* entity in a particular web application.
*/
public abstract class AuthenticationMethod {
public static final String CONTEXT_CONFIG_AUTH = Context.CONTEXT_CONFIG + ".authentication";
public static final String CONTEXT_CONFIG_AUTH_TYPE = CONTEXT_CONFIG_AUTH + ".type";
public static final String CONTEXT_CONFIG_AUTH_LOGGEDIN = CONTEXT_CONFIG_AUTH + ".loggedin";
public static final String CONTEXT_CONFIG_AUTH_LOGGEDOUT = CONTEXT_CONFIG_AUTH + ".loggedout";
public static final String AUTH_STATE_LOGGED_IN_STATS = "stats.auth.state.loggedin";
public static final String AUTH_STATE_LOGGED_OUT_STATS = "stats.auth.state.loggedout";
public static final String AUTH_STATE_NO_INDICATOR_STATS = "stats.auth.state.noindicator";
public static final String AUTH_STATE_UNKNOWN_STATS = "stats.auth.state.unknown";
/**
* Checks if the authentication method is fully configured.
*
* @return true, if is configured
*/
public abstract boolean isConfigured();
/**
* Clones the current authentication method, creating a deep-copy of it.
*
* @return a deep copy of the authentication method
*/
@Override
public AuthenticationMethod clone() {
AuthenticationMethod method = duplicate();
method.loggedInIndicatorPattern = this.loggedInIndicatorPattern;
method.loggedOutIndicatorPattern = this.loggedOutIndicatorPattern;
return method;
}
/**
* Internal method for cloning the current authentication method, creating a deep-copy of it.
*
* @return a deep copy of the authentication method
*/
protected abstract AuthenticationMethod duplicate();
/**
* Validates that the creation of authentication credentials is possible, returning {@code true} if it is, {@code false}
* otherwise.
*
* If view is enabled the user should be informed that it's not possible to create authentication credentials.
*
* Default implementation returns, always, {@code true}.
*
* @return {@code true} if the creation of authentication credentials is possible, {@code false} otherwise
* @see #createAuthenticationCredentials()
* @since 2.4.3
*/
public boolean validateCreationOfAuthenticationCredentials() {
return true;
}
/**
* Creates a new, empty, Authentication Credentials object corresponding to this type of
* Authentication method.
*
* @return the authentication credentials
* @see #validateCreationOfAuthenticationCredentials()
*/
public abstract AuthenticationCredentials createAuthenticationCredentials();
/**
* Gets the {@link AuthenticationMethodType} corresponding to this authentication method.
*
* Implementations may return new instantiations at every call, so performance considerations
* should be taken by users.
*
*
* @return the type
*/
public abstract AuthenticationMethodType getType();
/**
* Performs an authentication in a web application, returning an authenticated.
*
* @param sessionManagementMethod the set up session management method is provided so it can be
* used, if needed, to automatically extract session information from Http Messages.
* @param credentials the credentials
* @param user the user to authenticate
* @return an authenticated web session
* @throws UnsupportedAuthenticationCredentialsException the unsupported authentication
* credentials exception {@link WebSession}.
*/
public abstract WebSession authenticate(SessionManagementMethod sessionManagementMethod,
AuthenticationCredentials credentials, User user)
throws UnsupportedAuthenticationCredentialsException;
/**
* Gets an api response that represents the Authentication Method.
*
* @return the api response representation
*/
public abstract ApiResponse getApiResponseRepresentation();
/**
* Called when the Authentication Method is persisted/saved in a Context. For example, in this
* method, UI elements can be marked accordingly.Description
*/
public void onMethodPersisted() {
}
/**
* Called when the Authentication Method is discarded from/not used in a Context. For example,
* in this method, UI elements can be (un)marked accordingly.
*/
public void onMethodDiscarded() {
}
/** The logged in indicator pattern. */
protected Pattern loggedInIndicatorPattern = null;
/** The logged out indicator pattern. */
protected Pattern loggedOutIndicatorPattern = null;
/**
* Checks if the response received by the Http Message corresponds to an authenticated Web
* Session.
*
* If none of the indicators are set up, the method defaults to returning true, so that no
* authentications are tried when there is no way to check authentication. A message is also
* shown on the output console in this case.
*
*
* @param msg the http message
* @return true, if is authenticated or no indicators have been set, and false otherwise
*/
public boolean isAuthenticated(HttpMessage msg) {
if (msg == null || msg.getResponseBody() == null) {
return false;
}
// Assume logged in if nothing was set up
if (loggedInIndicatorPattern == null && loggedOutIndicatorPattern == null) {
try {
Stats.incCounter(SessionStructure.getHostName(msg), AUTH_STATE_NO_INDICATOR_STATS);
} catch (URIException e) {
// Ignore
}
if (View.isInitialised()) {
// Let the user know this
View.getSingleton()
.getOutputPanel()
.append(Constant.messages.getString("authentication.output.indicatorsNotSet", msg
.getRequestHeader().getURI())
+ "\n");
}
return true;
}
String body = msg.getResponseBody().toString();
String header = msg.getResponseHeader().toString();
if (loggedInIndicatorPattern != null
&& (loggedInIndicatorPattern.matcher(body).find() || loggedInIndicatorPattern.matcher(header)
.find())) {
// Looks like we're authenticated
try {
Stats.incCounter(SessionStructure.getHostName(msg), AUTH_STATE_LOGGED_IN_STATS);
} catch (URIException e) {
// Ignore
}
return true;
}
if (loggedOutIndicatorPattern != null && !loggedOutIndicatorPattern.matcher(body).find()
&& !loggedOutIndicatorPattern.matcher(header).find()) {
// Cant find the unauthenticated indicator, assume we're authenticated but record as unknown
try {
Stats.incCounter(SessionStructure.getHostName(msg), AUTH_STATE_UNKNOWN_STATS);
} catch (URIException e) {
// Ignore
}
return true;
}
// Not looking good...
try {
Stats.incCounter(SessionStructure.getHostName(msg), AUTH_STATE_LOGGED_OUT_STATS);
} catch (URIException e) {
// Ignore
}
return false;
}
/**
* Gets the logged in indicator pattern.
*
* @return the logged in indicator pattern
*/
public Pattern getLoggedInIndicatorPattern() {
return loggedInIndicatorPattern;
}
/**
* Sets the logged in indicator pattern.
*
* @param loggedInIndicatorPattern the new logged in indicator pattern
*/
public void setLoggedInIndicatorPattern(String loggedInIndicatorPattern) {
if (loggedInIndicatorPattern == null || loggedInIndicatorPattern.trim().length() == 0) {
this.loggedInIndicatorPattern = null;
} else {
this.loggedInIndicatorPattern = Pattern.compile(loggedInIndicatorPattern);
}
}
/**
* Gets the logged out indicator pattern.
*
* @return the logged out indicator pattern
*/
public Pattern getLoggedOutIndicatorPattern() {
return loggedOutIndicatorPattern;
}
/**
* Sets the logged out indicator pattern.
*
* @param loggedOutIndicatorPattern the new logged out indicator pattern
*/
public void setLoggedOutIndicatorPattern(String loggedOutIndicatorPattern) {
if (loggedOutIndicatorPattern == null || loggedOutIndicatorPattern.trim().length() == 0) {
this.loggedOutIndicatorPattern = null;
} else {
this.loggedOutIndicatorPattern = Pattern.compile(loggedOutIndicatorPattern);
}
}
/**
* Checks if another method is of the same type.
*
* @param other the other
* @return true, if is same type
*/
public boolean isSameType(AuthenticationMethod other) {
if (other == null)
return false;
return other.getClass().equals(this.getClass());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((loggedInIndicatorPattern == null) ? 0 : loggedInIndicatorPattern.pattern().hashCode());
result = prime * result
+ ((loggedOutIndicatorPattern == null) ? 0 : loggedOutIndicatorPattern.pattern().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AuthenticationMethod other = (AuthenticationMethod) obj;
if (loggedInIndicatorPattern == null) {
if (other.loggedInIndicatorPattern != null)
return false;
} else if (!loggedInIndicatorPattern.pattern().equals(other.loggedInIndicatorPattern.pattern()))
return false;
if (loggedOutIndicatorPattern == null) {
if (other.loggedOutIndicatorPattern != null)
return false;
} else if (!loggedOutIndicatorPattern.pattern().equals(other.loggedOutIndicatorPattern.pattern()))
return false;
return true;
}
/**
* Thrown when an unsupported type of credentials is used with a {@link AuthenticationMethod} .
*/
public static class UnsupportedAuthenticationCredentialsException extends RuntimeException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 4802501809913124766L;
/**
* Instantiates a new unsupported authentication credentials exception.
*
* @param message the message
*/
public UnsupportedAuthenticationCredentialsException(String message) {
super(message);
}
}
}