From 9ec946e387aa507e8eb8c4876af843ae1c55b6f8 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Fri, 3 Feb 2023 23:55:01 +1100 Subject: [PATCH 001/129] initial work on core security module Signed-off-by: Lachlan Roberts --- jetty-core/jetty-security/pom.xml | 43 + .../src/main/java/module-info.java | 23 + .../jetty/security/AbstractLoginService.java | 157 ++++ .../security/AbstractUserAuthentication.java | 103 ++ .../jetty/security/Authentication.java | 217 +++++ .../eclipse/jetty/security/Authenticator.java | 131 +++ .../ConfigurableSpnegoLoginService.java | 322 +++++++ .../jetty/security/ConstraintAware.java | 68 ++ .../jetty/security/ConstraintMapping.java | 87 ++ .../security/ConstraintSecurityHandler.java | 878 ++++++++++++++++++ .../security/DefaultAuthenticatorFactory.java | 117 +++ .../security/DefaultIdentityService.java | 74 ++ .../jetty/security/DefaultUserIdentity.java | 67 ++ .../jetty/security/EmptyLoginService.java | 56 ++ .../jetty/security/HashLoginService.java | 187 ++++ .../jetty/security/IdentityService.java | 85 ++ .../jetty/security/JDBCLoginService.java | 260 ++++++ .../security/LoggedOutAuthentication.java | 51 + .../eclipse/jetty/security/LoginService.java | 68 ++ .../jetty/security/PropertyUserStore.java | 316 +++++++ .../org/eclipse/jetty/security/RoleInfo.java | 162 ++++ .../eclipse/jetty/security/RolePrincipal.java | 47 + .../jetty/security/RoleRunAsToken.java | 38 + .../eclipse/jetty/security/RunAsToken.java | 23 + .../jetty/security/SecurityHandler.java | 679 ++++++++++++++ .../jetty/security/ServerAuthException.java | 42 + .../jetty/security/SpnegoUserIdentity.java | 54 ++ .../jetty/security/SpnegoUserPrincipal.java | 56 ++ .../jetty/security/UserAuthentication.java | 32 + .../jetty/security/UserDataConstraint.java | 38 + .../eclipse/jetty/security/UserIdentity.java | 79 ++ .../eclipse/jetty/security/UserPrincipal.java | 87 ++ .../org/eclipse/jetty/security/UserStore.java | 87 ++ .../security/WrappedAuthConfiguration.java | 74 ++ .../authentication/AuthorizationService.java | 43 + .../authentication/BasicAuthenticator.java | 104 +++ .../ClientCertAuthenticator.java | 368 ++++++++ .../ConfigurableSpnegoAuthenticator.java | 231 +++++ .../DeferredAuthentication.java | 205 ++++ .../authentication/DigestAuthenticator.java | 383 ++++++++ .../authentication/FormAuthenticator.java | 611 ++++++++++++ .../authentication/LoginAuthenticator.java | 121 +++ .../authentication/LoginCallback.java | 46 + .../authentication/LoginCallbackImpl.java | 112 +++ .../authentication/SessionAuthentication.java | 113 +++ .../SslClientCertAuthenticator.java | 153 +++ .../security/authentication/package-info.java | 18 + .../eclipse/jetty/security/package-info.java | 18 + jetty-core/pom.xml | 1 + 49 files changed, 7335 insertions(+) create mode 100644 jetty-core/jetty-security/pom.xml create mode 100644 jetty-core/jetty-security/src/main/java/module-info.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java diff --git a/jetty-core/jetty-security/pom.xml b/jetty-core/jetty-security/pom.xml new file mode 100644 index 000000000000..fc4ffc2505df --- /dev/null +++ b/jetty-core/jetty-security/pom.xml @@ -0,0 +1,43 @@ + + + org.eclipse.jetty + jetty-core + 12.0.0-SNAPSHOT + + + 4.0.0 + jetty-security + Core :: Security + The common jetty security implementation + + + ${project.groupId}.security + org.eclipse.jetty.security.* + + + + + org.eclipse.jetty + jetty-server + + + org.slf4j + slf4j-api + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + org.eclipse.jetty + jetty-http-tools + test + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + diff --git a/jetty-core/jetty-security/src/main/java/module-info.java b/jetty-core/jetty-security/src/main/java/module-info.java new file mode 100644 index 000000000000..0584ca97a1a5 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/module-info.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +module org.eclipse.jetty.session +{ + requires transitive org.eclipse.jetty.server; + requires transitive org.eclipse.jetty.util; + requires transitive org.slf4j; + requires java.security.jgss; + requires java.sql; + + exports org.eclipse.jetty.security; +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java new file mode 100644 index 000000000000..0e60c3053e15 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java @@ -0,0 +1,157 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.ArrayList; +import java.util.List; +import javax.security.auth.Subject; + +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * AbstractLoginService + * + * Base class for LoginServices that allows subclasses to provide the user authentication and authorization information, + * but provides common behaviour such as handling authentication. + */ +public abstract class AbstractLoginService extends ContainerLifeCycle implements LoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(AbstractLoginService.class); + + protected IdentityService _identityService = new DefaultIdentityService(); + protected String _name; + protected boolean _fullValidate = false; + + protected abstract List loadRoleInfo(UserPrincipal user); + + protected abstract UserPrincipal loadUserInfo(String username); + + protected AbstractLoginService() + { + addBean(_identityService); + } + + @Override + public String getName() + { + return _name; + } + + /** + * Set the identityService. + * + * @param identityService the identityService to set + */ + @Override + public void setIdentityService(IdentityService identityService) + { + if (isRunning()) + throw new IllegalStateException("Running"); + updateBean(_identityService, identityService); + _identityService = identityService; + } + + /** + * Set the name. + * + * @param name the name to set + */ + public void setName(String name) + { + if (isRunning()) + throw new IllegalStateException("Running"); + _name = name; + } + + @Override + public String toString() + { + return String.format("%s@%x[%s]", this.getClass().getSimpleName(), hashCode(), _name); + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + if (username == null) + return null; + + UserPrincipal userPrincipal = loadUserInfo(username); + if (userPrincipal != null && userPrincipal.authenticate(credentials)) + { + //safe to load the roles + List roles = loadRoleInfo(userPrincipal); + + List roleNames = new ArrayList<>(); + Subject subject = new Subject(); + userPrincipal.configureSubject(subject); + if (roles != null) + { + roles.forEach(p -> + { + p.configureForSubject(subject); + roleNames.add(p.getName()); + }); + } + + subject.setReadOnly(); + return _identityService.newUserIdentity(subject, userPrincipal, roleNames.toArray(new String[0])); + } + + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + if (!isFullValidate()) + return true; //if we have a user identity it must be valid + + //Do a full validation back against the user store + UserPrincipal fresh = loadUserInfo(user.getUserPrincipal().getName()); + if (fresh == null) + return false; //user no longer exists + + if (user.getUserPrincipal() instanceof UserPrincipal) + { + return fresh.authenticate(((UserPrincipal)user.getUserPrincipal())); + } + + throw new IllegalStateException("UserPrincipal not known"); //can't validate + } + + @Override + public IdentityService getIdentityService() + { + return _identityService; + } + + @Override + public void logout(UserIdentity user) + { + //Override in subclasses + } + + public boolean isFullValidate() + { + return _fullValidate; + } + + public void setFullValidate(boolean fullValidate) + { + _fullValidate = fullValidate; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java new file mode 100644 index 000000000000..4a0cca6f7667 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -0,0 +1,103 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.Serializable; +import java.util.Set; + +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.server.Request; + +/** + * AbstractUserAuthentication + * + * + * Base class for representing an authenticated user. + */ +public abstract class AbstractUserAuthentication implements User, Serializable +{ + private static final long serialVersionUID = -6290411814232723403L; + protected String _method; + protected transient UserIdentity _userIdentity; + + public AbstractUserAuthentication(String method, UserIdentity userIdentity) + { + _method = method; + _userIdentity = userIdentity; + } + + @Override + public String getAuthMethod() + { + return _method; + } + + @Override + public UserIdentity getUserIdentity() + { + return _userIdentity; + } + + @Override + public boolean isUserInRole(String role) + { + //Servlet Spec 3.1 pg 125 if testing special role ** + if ("**".equals(role.trim())) + { + //if ** is NOT a declared role name, the we return true + //as the user is authenticated. If ** HAS been declared as a + //role name, then we have to check if the user has that role + if (!declaredRolesContains("**")) + return true; + else + return _userIdentity.isUserInRole(role); + } + + return _userIdentity.isUserInRole(role); + } + + public boolean declaredRolesContains(String roleName) + { + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + if (security == null) + return false; + + if (security instanceof ConstraintAware) + { + Set declaredRoles = ((ConstraintAware)security).getRoles(); + return (declaredRoles != null) && declaredRoles.contains(roleName); + } + + return false; + } + + @Override + public Authentication logout(Request request) + { + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + if (security != null) + { + security.logout(this); + Authenticator authenticator = security.getAuthenticator(); + if (authenticator instanceof LoginAuthenticator) + { + ((LoginAuthenticator)authenticator).logout(request); + return new LoggedOutAuthentication((LoginAuthenticator)authenticator); + } + } + + return Authentication.UNAUTHENTICATED; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java new file mode 100644 index 000000000000..a2843c1b75ec --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java @@ -0,0 +1,217 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.io.QuietException; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; + +/** + * The Authentication state of a request. + *

+ * The Authentication state can be one of several sub-types that + * reflects where the request is in the many different authentication + * cycles. Authentication might not yet be checked or it might be checked + * and failed, checked and deferred or succeeded. + */ +public interface Authentication +{ + class Failed extends QuietException.Exception + { + public Failed(String message) + { + super(message); + } + } + + /** + * A successful Authentication with User information. + */ + interface User extends LogoutAuthentication + { + String getAuthMethod(); + + UserIdentity getUserIdentity(); + + boolean isUserInRole(String role); + } + + /** + * An authentication that is capable of performing a programmatic login + * operation. + */ + public interface LoginAuthentication extends Authentication + { + + /** + * Login with the LOGIN authenticator + * + * @param username the username + * @param password the password + * @param request the request + * @return The new Authentication state + */ + Authentication login(String username, Object password, Request request, Response response); + } + + /** + * An authentication that is capable of performing a programmatic + * logout operation. + */ + public interface LogoutAuthentication extends Authentication + { + + /** + * Remove any user information that may be present in the request + * such that a call to getUserPrincipal/getRemoteUser will return null. + * + * @param request the request + * @return NoAuthentication if we successfully logged out + */ + Authentication logout(Request request); + } + + /** + * A deferred authentication with methods to progress + * the authentication process. + */ + public interface Deferred extends LoginAuthentication, LogoutAuthentication + { + + /** + * Authenticate if possible without sending a challenge. + * This is used to check credentials that have been sent for + * non-mandatory authentication. + * + * @param request the request + * @return The new Authentication state. + */ + Authentication authenticate(Request request); + + /** + * Authenticate and possibly send a challenge. + * This is used to initiate authentication for previously + * non-mandatory authentication. + * + * @param request the request + * @param response the response + * @return The new Authentication state. + */ + Authentication authenticate(Request request, Response response, Callback callback); + } + + /** + * Authentication Response sent state. + * Responses are sent by authenticators either to issue an + * authentication challenge or on successful authentication in + * order to redirect the user to the original URL. + */ + public interface ResponseSent extends Authentication + { + } + + /** + * An Authentication Challenge has been sent. + */ + public interface Challenge extends ResponseSent + { + } + + /** + * An Authentication Failure has been sent. + */ + public interface Failure extends ResponseSent + { + } + + public interface SendSuccess extends ResponseSent + { + } + + /** + * After a logout, the authentication reverts to a state + * where it is possible to programmatically log in again. + */ + public interface NonAuthenticated extends LoginAuthentication + { + } + + /** + * Unauthenticated state. + *

+ * This convenience instance is for non mandatory authentication where credentials + * have been presented and checked, but failed authentication. + */ + public static final Authentication UNAUTHENTICATED = + new Authentication() + { + @Override + public String toString() + { + return "UNAUTHENTICATED"; + } + }; + + /** + * Authentication not checked + *

+ * This convenience instance us for non mandatory authentication when no + * credentials are present to be checked. + */ + public static final Authentication NOT_CHECKED = new Authentication() + { + @Override + public String toString() + { + return "NOT CHECKED"; + } + }; + + /** + * Authentication challenge sent. + *

+ * This convenience instance is for when an authentication challenge has been sent. + */ + public static final Authentication SEND_CONTINUE = new Challenge() + { + @Override + public String toString() + { + return "CHALLENGE"; + } + }; + + /** + * Authentication failure sent. + *

+ * This convenience instance is for when an authentication failure has been sent. + */ + public static final Authentication SEND_FAILURE = new Failure() + { + @Override + public String toString() + { + return "FAILURE"; + } + }; + public static final Authentication SEND_SUCCESS = new SendSuccess() + { + @Override + public String toString() + { + return "SEND_SUCCESS"; + } + }; +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java new file mode 100644 index 000000000000..11fb3fe3f746 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -0,0 +1,131 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Set; + +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.server.Context; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.Callback; + +/** + * Authenticator Interface + *

+ * An Authenticator is responsible for checking requests and sending + * response challenges in order to authenticate a request. + * Various types of {@link Authentication} are returned in order to + * signal the next step in authentication. + * + * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ + */ +public interface Authenticator +{ + + /** + * Configure the Authenticator + * + * @param configuration the configuration + */ + void setConfiguration(AuthConfiguration configuration); + + /** + * @return The name of the authentication method + */ + String getAuthMethod(); + + /** + * Called prior to validateRequest. The authenticator can + * manipulate the request to update it with information that + * can be inspected prior to validateRequest being called. + * The primary purpose of this method is to satisfy the Servlet + * Spec 3.1 section 13.6.3 on handling Form authentication + * where the http method of the original request causing authentication + * is not the same as the http method resulting from the redirect + * after authentication. + * @param request the request to prepare for authentication + */ + void prepareRequest(Request request); + + /** + * Validate a request + * + * @param request The request + * @param response The response + * @param callback the callback to use for writing a response + * @param mandatory True if authentication is mandatory. + * @return An Authentication. If Authentication is successful, this will be a {@link User}. If a response has + * been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will + * implement {@link Authentication.ResponseSent}. If Authentication is not mandatory, then a + * {@link Authentication.Deferred} may be returned. + * @throws ServerAuthException if unable to validate request + */ + Authentication validateRequest(Request request, Response response, Callback callback, boolean mandatory) throws ServerAuthException; + + /** + * is response secure + * + * @param request the request + * @param response the response + * @param callback the callback to write a response + * @param mandatory if security is mandatory + * @param validatedUser the user that was validated + * @return true if response is secure + * @throws ServerAuthException if unable to test response + */ + boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException; + + /** + * Authenticator Configuration + */ + interface AuthConfiguration + { + String getAuthMethod(); + + String getRealmName(); + + /** + * Get a SecurityHandler init parameter + * + * @param param parameter name + * @return Parameter value or null + * @see SecurityHandler#getInitParameter(String) + */ + String getInitParameter(String param); + + /** + * Get a SecurityHandler init parameter names + * + * @return Set of parameter names + * @see SecurityHandler#getInitParameterNames() + */ + Set getInitParameterNames(); + + LoginService getLoginService(); + + IdentityService getIdentityService(); + + boolean isSessionRenewedOnAuthentication(); + } + + /** + * Authenticator Factory + */ + interface Factory + { + Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java new file mode 100644 index 000000000000..23daf2833150 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java @@ -0,0 +1,322 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.Serializable; +import java.net.InetAddress; +import java.nio.file.Path; +import java.security.PrivilegedAction; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.Configuration; +import javax.security.auth.login.LoginContext; + +import org.eclipse.jetty.security.authentication.AuthorizationService; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.ietf.jgss.GSSContext; +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSException; +import org.ietf.jgss.GSSManager; +import org.ietf.jgss.GSSName; +import org.ietf.jgss.Oid; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

A configurable (as opposed to using system properties) SPNEGO LoginService.

+ *

At startup, this LoginService will login via JAAS the service principal, composed + * of the {@link #getServiceName() service name} and the {@link #getHostName() host name}, + * for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal + * credentials.

+ *

Upon receiving an HTTP request, the server tries to authenticate the client + * calling {@link #login(String, Object, Request)} where the GSS APIs are used to + * verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is + * established.

+ */ +public class ConfigurableSpnegoLoginService extends ContainerLifeCycle implements LoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(ConfigurableSpnegoLoginService.class); + + private final GSSManager _gssManager = GSSManager.getInstance(); + private final String _realm; + private final AuthorizationService _authorizationService; + private IdentityService _identityService = new DefaultIdentityService(); + private String _serviceName; + private Path _keyTabPath; + private String _hostName; + private SpnegoContext _context; + + public ConfigurableSpnegoLoginService(String realm, AuthorizationService authorizationService) + { + _realm = realm; + _authorizationService = authorizationService; + } + + /** + * @return the realm name + */ + @Override + public String getName() + { + return _realm; + } + + /** + * @return the path of the keyTab file containing service credentials + */ + public Path getKeyTabPath() + { + return _keyTabPath; + } + + /** + * @param keyTabFile the path of the keyTab file containing service credentials + */ + public void setKeyTabPath(Path keyTabFile) + { + _keyTabPath = keyTabFile; + } + + /** + * @return the service name, typically "HTTP" + * @see #getHostName() + */ + public String getServiceName() + { + return _serviceName; + } + + /** + * @param serviceName the service name + * @see #setHostName(String) + */ + public void setServiceName(String serviceName) + { + _serviceName = serviceName; + } + + /** + * @return the host name of the service + * @see #setServiceName(String) + */ + public String getHostName() + { + return _hostName; + } + + /** + * @param hostName the host name of the service + */ + public void setHostName(String hostName) + { + _hostName = hostName; + } + + @Override + protected void doStart() throws Exception + { + if (_hostName == null) + _hostName = InetAddress.getLocalHost().getCanonicalHostName(); + if (LOG.isDebugEnabled()) + LOG.debug("Retrieving credentials for service {}/{}", getServiceName(), getHostName()); + LoginContext loginContext = new LoginContext("", null, null, new SpnegoConfiguration()); + loginContext.login(); + Subject subject = loginContext.getSubject(); + _context = Subject.doAs(subject, newSpnegoContext(subject)); + super.doStart(); + } + + private PrivilegedAction newSpnegoContext(Subject subject) + { + return () -> + { + try + { + GSSName serviceName = _gssManager.createName(getServiceName() + "@" + getHostName(), GSSName.NT_HOSTBASED_SERVICE); + Oid kerberosOid = new Oid("1.2.840.113554.1.2.2"); + Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); + Oid[] mechanisms = new Oid[]{kerberosOid, spnegoOid}; + GSSCredential serviceCredential = _gssManager.createCredential(serviceName, GSSCredential.DEFAULT_LIFETIME, mechanisms, GSSCredential.ACCEPT_ONLY); + SpnegoContext context = new SpnegoContext(); + context._subject = subject; + context._serviceCredential = serviceCredential; + return context; + } + catch (GSSException x) + { + throw new RuntimeException(x); + } + }; + } + + @Override + public UserIdentity login(String username, Object credentials, Request req) + { + Subject subject = _context._subject; + Session httpSession = req.getSession(false); + GSSContext gssContext = null; + if (httpSession != null) + { + GSSContextHolder holder = (GSSContextHolder)httpSession.getAttribute(GSSContextHolder.ATTRIBUTE); + gssContext = holder == null ? null : holder.gssContext; + } + if (gssContext == null) + gssContext = Subject.doAs(subject, newGSSContext()); + + byte[] input = Base64.getDecoder().decode((String)credentials); + byte[] output = Subject.doAs(_context._subject, acceptGSSContext(gssContext, input)); + String token = Base64.getEncoder().encodeToString(output); + + String userName = toUserName(gssContext); + // Save the token in the principal so it can be sent in the response. + SpnegoUserPrincipal principal = new SpnegoUserPrincipal(userName, token); + if (gssContext.isEstablished()) + { + if (httpSession != null) + httpSession.removeAttribute(GSSContextHolder.ATTRIBUTE); + + UserIdentity roles = _authorizationService.getUserIdentity(req, userName); + return new SpnegoUserIdentity(subject, principal, roles); + } + else + { + // The GSS context is not established yet, save it into the HTTP session. + if (httpSession == null) + httpSession = req.getSession(true); + GSSContextHolder holder = new GSSContextHolder(gssContext); + httpSession.setAttribute(GSSContextHolder.ATTRIBUTE, holder); + + // Return an unestablished UserIdentity. + return new SpnegoUserIdentity(subject, principal, null); + } + } + + private PrivilegedAction newGSSContext() + { + return () -> + { + try + { + return _gssManager.createContext(_context._serviceCredential); + } + catch (GSSException x) + { + throw new RuntimeException(x); + } + }; + } + + private PrivilegedAction acceptGSSContext(GSSContext gssContext, byte[] token) + { + return () -> + { + try + { + return gssContext.acceptSecContext(token, 0, token.length); + } + catch (GSSException x) + { + throw new RuntimeException(x); + } + }; + } + + private String toUserName(GSSContext gssContext) + { + try + { + String name = gssContext.getSrcName().toString(); + int at = name.indexOf('@'); + if (at < 0) + return name; + return name.substring(0, at); + } + catch (GSSException x) + { + throw new RuntimeException(x); + } + } + + @Override + public boolean validate(UserIdentity user) + { + return false; + } + + @Override + public IdentityService getIdentityService() + { + return _identityService; + } + + @Override + public void setIdentityService(IdentityService identityService) + { + _identityService = identityService; + } + + @Override + public void logout(UserIdentity user) + { + } + + private class SpnegoConfiguration extends Configuration + { + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) + { + final String principal = getServiceName() + "/" + getHostName(); + Map options = new HashMap<>(); + if (LOG.isDebugEnabled()) + options.put("debug", "true"); + options.put("doNotPrompt", "true"); + options.put("refreshKrb5Config", "true"); + options.put("principal", principal); + options.put("useKeyTab", "true"); + Path keyTabPath = getKeyTabPath(); + if (keyTabPath != null) + options.put("keyTab", keyTabPath.toAbsolutePath().toString()); + // This option is required to store the service credentials in + // the Subject, so that it can be later used by acceptSecContext(). + options.put("storeKey", "true"); + options.put("isInitiator", "false"); + String moduleClass = "com.sun.security.auth.module.Krb5LoginModule"; + AppConfigurationEntry config = new AppConfigurationEntry(moduleClass, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); + return new AppConfigurationEntry[]{config}; + } + } + + private static class SpnegoContext + { + private Subject _subject; + private GSSCredential _serviceCredential; + } + + private static class GSSContextHolder implements Serializable + { + public static final String ATTRIBUTE = GSSContextHolder.class.getName(); + + private final transient GSSContext gssContext; + + private GSSContextHolder(GSSContext gssContext) + { + this.gssContext = gssContext; + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java new file mode 100644 index 000000000000..9396db56e975 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.List; +import java.util.Set; + +public interface ConstraintAware +{ + List getConstraintMappings(); + + Set getRoles(); + + /** + * Set Constraint Mappings and roles. + * Can only be called during initialization. + * + * @param constraintMappings the mappings + * @param roles the roles + */ + void setConstraintMappings(List constraintMappings, Set roles); + + /** + * Add a Constraint Mapping. + * May be called for running webapplication as an annotated servlet is instantiated. + * + * @param mapping the mapping + */ + void addConstraintMapping(ConstraintMapping mapping); + + /** + * Add a Role definition. + * May be called on running webapplication as an annotated servlet is instantiated. + * + * @param role the role + */ + void addRole(String role); + + /** + * See Servlet Spec 31, sec 13.8.4, pg 145 + * When true, requests with http methods not explicitly covered either by inclusion or omissions + * in constraints, will have access denied. + * + * @param deny true for denied method access + */ + void setDenyUncoveredHttpMethods(boolean deny); + + boolean isDenyUncoveredHttpMethods(); + + /** + * See Servlet Spec 31, sec 13.8.4, pg 145 + * Container must check if there are urls with uncovered http methods + * + * @return true if urls with uncovered http methods + */ + boolean checkPathsWithUncoveredHttpMethods(); +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java new file mode 100644 index 000000000000..432fc1029d1c --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java @@ -0,0 +1,87 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.util.security.Constraint; + +public class ConstraintMapping +{ + String _method; + String[] _methodOmissions; + + String _pathSpec; + + Constraint _constraint; + + /** + * @return Returns the constraint. + */ + public Constraint getConstraint() + { + return _constraint; + } + + /** + * @param constraint The constraint to set. + */ + public void setConstraint(Constraint constraint) + { + this._constraint = constraint; + } + + /** + * @return Returns the method. + */ + public String getMethod() + { + return _method; + } + + /** + * @param method The method to set. + */ + public void setMethod(String method) + { + this._method = method; + } + + /** + * @return Returns the pathSpec. + */ + public String getPathSpec() + { + return _pathSpec; + } + + /** + * @param pathSpec The pathSpec to set. + */ + public void setPathSpec(String pathSpec) + { + this._pathSpec = pathSpec; + } + + /** + * @param omissions The http-method-omission + */ + public void setMethodOmissions(String[] omissions) + { + _methodOmissions = omissions; + } + + public String[] getMethodOmissions() + { + return _methodOmissions; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java new file mode 100644 index 000000000000..94f750926fcb --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java @@ -0,0 +1,878 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; + +import jakarta.servlet.HttpConstraintElement; +import jakarta.servlet.HttpMethodConstraintElement; +import jakarta.servlet.ServletSecurityElement; +import jakarta.servlet.annotation.ServletSecurity.EmptyRoleSemantic; +import jakarta.servlet.annotation.ServletSecurity.TransportGuarantee; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.ee10.servlet.ServletApiRequest; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletContextRequest; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.pathmap.MappedResource; +import org.eclipse.jetty.http.pathmap.MatchedResource; +import org.eclipse.jetty.http.pathmap.PathMappings; +import org.eclipse.jetty.http.pathmap.PathSpec; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.component.DumpableCollection; +import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * ConstraintSecurityHandler + *

+ * Handler to enforce SecurityConstraints. This implementation is servlet spec + * 3.1 compliant and pre-computes the constraint combinations for runtime + * efficiency. + */ +public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware +{ + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); //use same as SecurityHandler + + private static final String OMISSION_SUFFIX = ".omission"; + private static final String ALL_METHODS = "*"; + private final List _constraintMappings = new CopyOnWriteArrayList<>(); + private final List _durableConstraintMappings = new CopyOnWriteArrayList<>(); + private final Set _roles = new CopyOnWriteArraySet<>(); + private final PathMappings> _constraintRoles = new PathMappings<>(); + private boolean _denyUncoveredMethods = false; + + public static Constraint createConstraint() + { + return new Constraint(); + } + + public static Constraint createConstraint(Constraint constraint) + { + try + { + return (Constraint)constraint.clone(); + } + catch (CloneNotSupportedException e) + { + throw new IllegalStateException(e); + } + } + + /** + * Create a security constraint + * + * @param name the name of the constraint + * @param authenticate true to authenticate + * @param roles list of roles + * @param dataConstraint the data constraint + * @return the constraint + */ + public static Constraint createConstraint(String name, boolean authenticate, String[] roles, int dataConstraint) + { + Constraint constraint = createConstraint(); + if (name != null) + constraint.setName(name); + constraint.setAuthenticate(authenticate); + constraint.setRoles(roles); + constraint.setDataConstraint(dataConstraint); + return constraint; + } + + /** + * Create a Constraint + * + * @param name the name + * @param element the http constraint element + * @return the created constraint + */ + public static Constraint createConstraint(String name, HttpConstraintElement element) + { + return createConstraint(name, element.getRolesAllowed(), element.getEmptyRoleSemantic(), element.getTransportGuarantee()); + } + + /** + * Create Constraint + * + * @param name the name + * @param rolesAllowed the list of allowed roles + * @param permitOrDeny the permission semantic + * @param transport the transport guarantee + * @return the created constraint + */ + public static Constraint createConstraint(String name, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport) + { + Constraint constraint = createConstraint(); + + if (rolesAllowed == null || rolesAllowed.length == 0) + { + if (permitOrDeny.equals(EmptyRoleSemantic.DENY)) + { + //Equivalent to with no roles + constraint.setName(name + "-Deny"); + constraint.setAuthenticate(true); + } + else + { + //Equivalent to no + constraint.setName(name + "-Permit"); + constraint.setAuthenticate(false); + } + } + else + { + //Equivalent to with list of s + constraint.setAuthenticate(true); + constraint.setRoles(rolesAllowed); + constraint.setName(name + "-RolesAllowed"); + } + + //Equivalent to //CONFIDENTIAL + constraint.setDataConstraint((transport.equals(TransportGuarantee.CONFIDENTIAL) ? Constraint.DC_CONFIDENTIAL : Constraint.DC_NONE)); + return constraint; + } + + public static List getConstraintMappingsForPath(String pathSpec, List constraintMappings) + { + if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0) + return Collections.emptyList(); + + List mappings = new ArrayList<>(); + for (ConstraintMapping mapping : constraintMappings) + { + if (pathSpec.equals(mapping.getPathSpec())) + { + mappings.add(mapping); + } + } + return mappings; + } + + /** + * Take out of the constraint mappings those that match the + * given path. + * + * @param pathSpec the path spec + * @param constraintMappings a new list minus the matching constraints + * @return the list of constraint mappings + */ + public static List removeConstraintMappingsForPath(String pathSpec, List constraintMappings) + { + if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0) + return Collections.emptyList(); + + List mappings = new ArrayList<>(); + for (ConstraintMapping mapping : constraintMappings) + { + //Remove the matching mappings by only copying in non-matching mappings + if (!pathSpec.equals(mapping.getPathSpec())) + { + mappings.add(mapping); + } + } + return mappings; + } + + /** + * Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement + * + * @param name the name + * @param pathSpec the path spec + * @param securityElement the servlet security element + * @return the list of constraint mappings + */ + public static List createConstraintsWithMappingsForPath(String name, String pathSpec, ServletSecurityElement securityElement) + { + List mappings = new ArrayList<>(); + + //Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints) + Constraint httpConstraint; + ConstraintMapping httpConstraintMapping = null; + + if (securityElement.getEmptyRoleSemantic() != EmptyRoleSemantic.PERMIT || + securityElement.getRolesAllowed().length != 0 || + securityElement.getTransportGuarantee() != TransportGuarantee.NONE) + { + httpConstraint = ConstraintSecurityHandler.createConstraint(name, securityElement); + + //Create a mapping for the pathSpec for the default case + httpConstraintMapping = new ConstraintMapping(); + httpConstraintMapping.setPathSpec(pathSpec); + httpConstraintMapping.setConstraint(httpConstraint); + mappings.add(httpConstraintMapping); + } + + //See Spec 13.4.1.2 p127 + List methodOmissions = new ArrayList<>(); + + //make constraint mappings for this url for each of the HttpMethodConstraintElements + java.util.Collection methodConstraintElements = securityElement.getHttpMethodConstraints(); + if (methodConstraintElements != null) + { + for (HttpMethodConstraintElement methodConstraintElement : methodConstraintElements) + { + //Make a Constraint that captures the and elements supplied for the HttpMethodConstraintElement + Constraint methodConstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraintElement); + ConstraintMapping mapping = new ConstraintMapping(); + mapping.setConstraint(methodConstraint); + mapping.setPathSpec(pathSpec); + if (methodConstraintElement.getMethodName() != null) + { + mapping.setMethod(methodConstraintElement.getMethodName()); + //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint + methodOmissions.add(methodConstraintElement.getMethodName()); + } + mappings.add(mapping); + } + } + //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint + //UNLESS the default constraint contains all default values. In that case, we won't add it. See Servlet Spec 3.1 pg 129 + if (methodOmissions.size() > 0 && httpConstraintMapping != null) + httpConstraintMapping.setMethodOmissions(methodOmissions.toArray(new String[0])); + + return mappings; + } + + @Override + public List getConstraintMappings() + { + return _constraintMappings; + } + + @Override + public Set getRoles() + { + return _roles; + } + + /** + * Process the constraints following the combining rules in Servlet 3.0 EA + * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. + * + * @param constraintMappings The constraintMappings to set, from which the set of known roles + * is determined. + */ + public void setConstraintMappings(List constraintMappings) + { + setConstraintMappings(constraintMappings, null); + } + + /** + * Process the constraints following the combining rules in Servlet 3.0 EA + * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. + * + * @param constraintMappings The constraintMappings to set as array, from which the set of known roles + * is determined. Needed to retain API compatibility for 7.x + */ + public void setConstraintMappings(ConstraintMapping[] constraintMappings) + { + setConstraintMappings(Arrays.asList(constraintMappings), null); + } + + /** + * Process the constraints following the combining rules in Servlet 3.0 EA + * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. + * + * @param constraintMappings The constraintMappings to set. + * @param roles The known roles (or null to determine them from the mappings) + */ + @Override + public void setConstraintMappings(List constraintMappings, Set roles) + { + + _constraintMappings.clear(); + _constraintMappings.addAll(constraintMappings); + + _durableConstraintMappings.clear(); + if (isInDurableState()) + { + _durableConstraintMappings.addAll(constraintMappings); + } + + if (roles == null) + { + roles = new HashSet<>(); + for (ConstraintMapping cm : constraintMappings) + { + String[] cmr = cm.getConstraint().getRoles(); + if (cmr != null) + { + for (String r : cmr) + { + if (!ALL_METHODS.equals(r)) + roles.add(r); + } + } + } + } + setRoles(roles); + + if (isStarted()) + { + _constraintMappings.stream().forEach(m -> processConstraintMapping(m)); + } + } + + /** + * Set the known roles. + * This may be overridden by a subsequent call to {@link #setConstraintMappings(ConstraintMapping[])} or + * {@link #setConstraintMappings(List, Set)}. + * + * @param roles The known roles (or null to determine them from the mappings) + */ + public void setRoles(Set roles) + { + _roles.clear(); + _roles.addAll(roles); + } + + @Override + public void addConstraintMapping(ConstraintMapping mapping) + { + _constraintMappings.add(mapping); + + if (isInDurableState()) + _durableConstraintMappings.add(mapping); + + if (mapping.getConstraint() != null && mapping.getConstraint().getRoles() != null) + { + //allow for lazy role naming: if a role is named in a security constraint, try and + //add it to the list of declared roles (ie as if it was declared with a security-role + for (String role : mapping.getConstraint().getRoles()) + { + if ("*".equals(role) || "**".equals(role)) + continue; + addRole(role); + } + } + + if (isStarted()) + processConstraintMapping(mapping); + } + + @Override + public void addRole(String role) + { + //add to list of declared roles + boolean modified = _roles.add(role); + if (isStarted() && modified) + { + // Add the new role to currently defined any role role infos + for (MappedResource> map : _constraintRoles) + { + for (RoleInfo info : map.getResource().values()) + { + if (info.isAnyRole()) + info.addRole(role); + } + } + } + } + + @Override + protected void doStart() throws Exception + { + _constraintRoles.reset(); + _constraintMappings.forEach(this::processConstraintMapping); + + //Servlet Spec 3.1 pg 147 sec 13.8.4.2 log paths for which there are uncovered http methods + checkPathsWithUncoveredHttpMethods(); + + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + super.doStop(); + _constraintRoles.reset(); + _constraintMappings.clear(); + _constraintMappings.addAll(_durableConstraintMappings); + } + + /** + * Create and combine the constraint with the existing processed + * constraints. + * + * @param mapping the constraint mapping + */ + protected void processConstraintMapping(ConstraintMapping mapping) + { + Map mappings = _constraintRoles.get(PathSpec.from(mapping.getPathSpec())); + if (mappings == null) + { + mappings = new HashMap<>(); + _constraintRoles.put(mapping.getPathSpec(), mappings); + } + RoleInfo allMethodsRoleInfo = mappings.get(ALL_METHODS); + if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden()) + return; + + if (mapping.getMethodOmissions() != null && mapping.getMethodOmissions().length > 0) + { + processConstraintMappingWithMethodOmissions(mapping, mappings); + return; + } + + String httpMethod = mapping.getMethod(); + if (httpMethod == null) + httpMethod = ALL_METHODS; + RoleInfo roleInfo = mappings.get(httpMethod); + if (roleInfo == null) + { + roleInfo = new RoleInfo(); + mappings.put(httpMethod, roleInfo); + if (allMethodsRoleInfo != null) + { + roleInfo.combine(allMethodsRoleInfo); + } + } + if (roleInfo.isForbidden()) + return; + + //add in info from the constraint + configureRoleInfo(roleInfo, mapping); + + if (roleInfo.isForbidden()) + { + if (httpMethod.equals(ALL_METHODS)) + { + mappings.clear(); + mappings.put(ALL_METHODS, roleInfo); + } + } + } + + /** + * Constraints that name method omissions are dealt with differently. + * We create an entry in the mappings with key "<method>.omission". This entry + * is only ever combined with other omissions for the same method to produce a + * consolidated RoleInfo. Then, when we wish to find the relevant constraints for + * a given Request (in prepareConstraintInfo()), we consult 3 types of entries in + * the mappings: an entry that names the method of the Request specifically, an + * entry that names constraints that apply to all methods, entries of the form + * <method>.omission, where the method of the Request is not named in the omission. + * + * @param mapping the constraint mapping + * @param mappings the mappings of roles + */ + protected void processConstraintMappingWithMethodOmissions(ConstraintMapping mapping, Map mappings) + { + String[] omissions = mapping.getMethodOmissions(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < omissions.length; i++) + { + if (i > 0) + sb.append("."); + sb.append(omissions[i]); + } + sb.append(OMISSION_SUFFIX); + RoleInfo ri = new RoleInfo(); + mappings.put(sb.toString(), ri); + configureRoleInfo(ri, mapping); + } + + /** + * Initialize or update the RoleInfo from the constraint + * + * @param ri the role info + * @param mapping the constraint mapping + */ + protected void configureRoleInfo(RoleInfo ri, ConstraintMapping mapping) + { + Constraint constraint = mapping.getConstraint(); + boolean forbidden = constraint.isForbidden(); + ri.setForbidden(forbidden); + + //set up the data constraint (NOTE: must be done after setForbidden, as it nulls out the data constraint + //which we need in order to do combining of omissions in prepareConstraintInfo + UserDataConstraint userDataConstraint = UserDataConstraint.get(mapping.getConstraint().getDataConstraint()); + ri.setUserDataConstraint(userDataConstraint); + + //if forbidden, no point setting up roles + if (!ri.isForbidden()) + { + //add in the roles + boolean checked = mapping.getConstraint().getAuthenticate(); + ri.setChecked(checked); + + if (ri.isChecked()) + { + if (mapping.getConstraint().isAnyRole()) + { + // * means matches any defined role + for (String role : _roles) + { + ri.addRole(role); + } + ri.setAnyRole(true); + } + else if (mapping.getConstraint().isAnyAuth()) + { + //being authenticated is sufficient, not necessary to check roles + ri.setAnyAuth(true); + } + else + { + //user must be in one of the named roles + String[] newRoles = mapping.getConstraint().getRoles(); + for (String role : newRoles) + { + //check role has been defined + if (!_roles.contains(role)) + throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles); + ri.addRole(role); + } + } + } + } + } + + /** + * Find constraints that apply to the given path. + * In order to do this, we consult 3 different types of information stored in the mappings for each path - each mapping + * represents a merged set of user data constraints, roles etc -: + *

    + *
  1. A mapping of an exact method name
  2. + *
  3. A mapping with key * that matches every method name
  4. + *
  5. Mappings with keys of the form "<method>.<method>.<method>.omission" that indicates it will match every method name EXCEPT those given
  6. + *
+ * + * @see SecurityHandler#prepareConstraintInfo(String, HttpServletRequest) + */ + @Override + protected RoleInfo prepareConstraintInfo(String pathInContext, HttpServletRequest request) + { + MatchedResource> resource = _constraintRoles.getMatched(pathInContext); + if (resource == null) + return null; + + Map mappings = resource.getResource(); + if (mappings == null) + return null; + + String httpMethod = request.getMethod(); + RoleInfo roleInfo = mappings.get(httpMethod); + if (roleInfo == null) + { + //No specific http-method names matched + List applicableConstraints = new ArrayList<>(); + + //Get info for constraint that matches all methods if it exists + RoleInfo all = mappings.get(ALL_METHODS); + if (all != null) + applicableConstraints.add(all); + + //Get info for constraints that name method omissions where target method name is not omitted + //(ie matches because target method is not omitted, hence considered covered by the constraint) + for (Entry entry : mappings.entrySet()) + { + if (entry.getKey() != null && entry.getKey().endsWith(OMISSION_SUFFIX) && !entry.getKey().contains(httpMethod)) + applicableConstraints.add(entry.getValue()); + } + + if (applicableConstraints.size() == 0 && isDenyUncoveredHttpMethods()) + { + roleInfo = new RoleInfo(); + roleInfo.setForbidden(true); + } + else if (applicableConstraints.size() == 1) + roleInfo = applicableConstraints.get(0); + else + { + roleInfo = new RoleInfo(); + roleInfo.setUserDataConstraint(UserDataConstraint.None); + + for (RoleInfo r : applicableConstraints) + { + roleInfo.combine(r); + } + } + } + + return roleInfo; + } + + /** + * Return true if ok to proceed, false otherwise. + */ + @Override + protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Callback callback, RoleInfo roleInfo) throws IOException + { + if (roleInfo == null) + return true; + + if (roleInfo.isForbidden()) + { + Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN); + return false; + } + + UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint(); + if (dataConstraint == null || dataConstraint == UserDataConstraint.None) + return true; + + HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); + + if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) + { + if (request.isSecure()) + return true; + + if (httpConfig.getSecurePort() > 0) + { + //Redirect to secure port + String scheme = httpConfig.getSecureScheme(); + int port = httpConfig.getSecurePort(); + + String url = URIUtil.newURI(scheme, Request.getServerName(request), port, request.getHttpURI().getPath(), request.getHttpURI().getQuery()); + response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); + + Response.sendRedirect(request, response, callback, HttpStatus.MOVED_TEMPORARILY_302, url, true); + } + else + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); + return false; + } + else + { + throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint); + } + } + + @Override + protected boolean isAuthMandatory(Request request, Response response, Object constraintInfo) + { + return constraintInfo != null && ((RoleInfo)constraintInfo).isChecked(); + } + + @Override + protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity) + throws IOException + { + ServletContextRequest screquest = Request.as(request, ServletContextRequest.class); + ServletApiRequest sarequest = (screquest == null ? null : screquest.getServletApiRequest()); + + if (constraintInfo == null) + { + return true; + } + RoleInfo roleInfo = (RoleInfo)constraintInfo; + + if (!roleInfo.isChecked()) + { + return true; + } + + //handle ** role constraint + if (roleInfo.isAnyAuth() && sarequest.getUserPrincipal() != null) + { + return true; + } + + //check if user is any of the allowed roles + boolean isUserInRole = false; + for (String role : roleInfo.getRoles()) + { + if (userIdentity.isUserInRole(role)) + { + isUserInRole = true; + break; + } + } + + //handle * role constraint + if (roleInfo.isAnyRole() && sarequest.getUserPrincipal() != null && isUserInRole) + { + return true; + } + + //normal role check + if (isUserInRole) + { + return true; + } + + return false; + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + dumpObjects(out, indent, + DumpableCollection.from("roles", _roles), + DumpableCollection.from("constraints", _constraintMappings)); + } + + @Override + public void setDenyUncoveredHttpMethods(boolean deny) + { + _denyUncoveredMethods = deny; + } + + @Override + public boolean isDenyUncoveredHttpMethods() + { + return _denyUncoveredMethods; + } + + /** + * Servlet spec 3.1 pg. 147. + */ + @Override + public boolean checkPathsWithUncoveredHttpMethods() + { + Set paths = getPathsWithUncoveredHttpMethods(); + if (paths != null && !paths.isEmpty()) + { + LOG.warn("{} has uncovered HTTP methods for the following paths: {}", + ContextHandler.getCurrentContext(), paths); + return true; + } + return false; + } + + /** + * Servlet spec 3.1 pg. 147. + * The container must check all the combined security constraint + * information and log any methods that are not protected and the + * urls at which they are not protected + * + * @return list of paths for which there are uncovered methods + */ + public Set getPathsWithUncoveredHttpMethods() + { + //if automatically denying uncovered methods, there are no uncovered methods + if (_denyUncoveredMethods) + return Collections.emptySet(); + + Set uncoveredPaths = new HashSet<>(); + + for (MappedResource> resource : _constraintRoles) + { + String path = resource.getPathSpec().getDeclaration(); + Map methodMappings = resource.getResource(); + //Each key is either: + // : an exact method name + // : * which means that the constraint applies to every method + // : a name of the form ...omission, which means it applies to every method EXCEPT those named + if (methodMappings.get(ALL_METHODS) != null) + continue; //can't be any uncovered methods for this url path + + boolean hasOmissions = omissionsExist(path, methodMappings); + + for (String method : methodMappings.keySet()) + { + if (method.endsWith(OMISSION_SUFFIX)) + { + Set omittedMethods = getOmittedMethods(method); + for (String m : omittedMethods) + { + if (!methodMappings.containsKey(m)) + uncoveredPaths.add(path); + } + } + else + { + //an exact method name + if (!hasOmissions) + //an http-method does not have http-method-omission to cover the other method names + uncoveredPaths.add(path); + } + } + } + return uncoveredPaths; + } + + /** + * Check if any http method omissions exist in the list of method + * to auth info mappings. + * + * @param path the path + * @param methodMappings the method mappings + * @return true if omission exist + */ + protected boolean omissionsExist(String path, Map methodMappings) + { + if (methodMappings == null) + return false; + boolean hasOmissions = false; + for (String m : methodMappings.keySet()) + { + if (m.endsWith(OMISSION_SUFFIX)) + hasOmissions = true; + } + return hasOmissions; + } + + /** + * Given a string of the form <method>.<method>.omission + * split out the individual method names. + * + * @param omission the method + * @return the list of strings + */ + protected Set getOmittedMethods(String omission) + { + if (omission == null || !omission.endsWith(OMISSION_SUFFIX)) + return Collections.emptySet(); + + String[] strings = omission.split("\\."); + Set methods = new HashSet<>(); + for (int i = 0; i < strings.length - 1; i++) + { + methods.add(strings[i]); + } + return methods; + } + + /** + * Constraints can be added to the ConstraintSecurityHandler before the + * associated context is started. These constraints should persist across + * a stop/start. Others can be added after the associated context is starting + * (eg by a web.xml/web-fragment.xml, annotation or jakarta.servlet api call) - + * these should not be persisted across a stop/start as they will be re-added on + * the restart. + * + * @return true if the context with which this ConstraintSecurityHandler + * has not yet started, or if there is no context, the server has not yet started. + */ + private boolean isInDurableState() + { + ServletContextHandler contextHandler = ServletContextHandler.getCurrentServletContextHandler(); + Server server = getServer(); + + return (contextHandler == null && server == null) || (contextHandler != null && !contextHandler.isRunning()) || (contextHandler == null && server != null && !server.isRunning()); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java new file mode 100644 index 000000000000..ca8af2fee3f5 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java @@ -0,0 +1,117 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Collection; + +import org.eclipse.jetty.security.Authenticator.AuthConfiguration; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.security.authentication.ClientCertAuthenticator; +import org.eclipse.jetty.security.authentication.ConfigurableSpnegoAuthenticator; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.authentication.DigestAuthenticator; +import org.eclipse.jetty.security.authentication.FormAuthenticator; +import org.eclipse.jetty.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.security.authentication.SessionAuthentication; +import org.eclipse.jetty.security.authentication.SslClientCertAuthenticator; +import org.eclipse.jetty.server.Context; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The Default Authenticator Factory. + * Uses the {@link AuthConfiguration#getAuthMethod()} to select an {@link Authenticator} from:
    + *
  • {@link BasicAuthenticator}
  • + *
  • {@link DigestAuthenticator}
  • + *
  • {@link FormAuthenticator}
  • + *
  • {@link ClientCertAuthenticator}
  • + *
  • {@link SslClientCertAuthenticator}
  • + *
+ * All authenticators derived from {@link LoginAuthenticator} are + * wrapped with a {@link DeferredAuthentication} + * instance, which is used if authentication is not mandatory. + * + * The Authentications from the {@link FormAuthenticator} are always wrapped in a + * {@link SessionAuthentication} + *

+ * If a {@link LoginService} has not been set on this factory, then + * the service is selected by searching the {@link Server#getBeans(Class)} results for + * a service that matches the realm name, else the first LoginService found is used. + */ +public class DefaultAuthenticatorFactory implements Authenticator.Factory +{ + + private static final Logger LOG = LoggerFactory.getLogger(DefaultAuthenticatorFactory.class); + + LoginService _loginService; + + @Override + public Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService) + { + String auth = configuration.getAuthMethod(); + Authenticator authenticator = null; + + if (Constraint.__BASIC_AUTH.equalsIgnoreCase(auth)) + authenticator = new BasicAuthenticator(); + else if (Constraint.__DIGEST_AUTH.equalsIgnoreCase(auth)) + authenticator = new DigestAuthenticator(); + else if (Constraint.__FORM_AUTH.equalsIgnoreCase(auth)) + authenticator = new FormAuthenticator(); + else if (Constraint.__SPNEGO_AUTH.equalsIgnoreCase(auth)) + authenticator = new ConfigurableSpnegoAuthenticator(); + else if (Constraint.__NEGOTIATE_AUTH.equalsIgnoreCase(auth)) // see Bug #377076 + authenticator = new ConfigurableSpnegoAuthenticator(Constraint.__NEGOTIATE_AUTH); + if (Constraint.__CERT_AUTH.equalsIgnoreCase(auth) || Constraint.__CERT_AUTH2.equalsIgnoreCase(auth)) + { + Collection sslContextFactories = server.getBeans(SslContextFactory.class); + if (sslContextFactories.size() != 1) + { + if (sslContextFactories.size() > 1) + { + LOG.info("Multiple SslContextFactory instances discovered. Directly configure a SslClientCertAuthenticator to use one."); + } + else + { + LOG.debug("No SslContextFactory instances discovered. Directly configure a SslClientCertAuthenticator to use one."); + } + authenticator = new ClientCertAuthenticator(); + } + else + { + authenticator = new SslClientCertAuthenticator(sslContextFactories.iterator().next()); + } + } + + return authenticator; + } + + /** + * @return the loginService + */ + public LoginService getLoginService() + { + return _loginService; + } + + /** + * @param loginService the loginService to set + */ + public void setLoginService(LoginService loginService) + { + _loginService = loginService; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java new file mode 100644 index 000000000000..3a682de15077 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -0,0 +1,74 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import javax.security.auth.Subject; + +/** + * Default Identity Service implementation. + * This service handles only role reference maps passed in an + * associated {@link UserIdentity}. If there are roles + * refs present, then associate will wrap the UserIdentity with one + * that uses the role references in the + * {@link UserIdentity#isUserInRole(String)} + * implementation. All other operations are effectively noops. + * TODO associate on demand and write callbacks? + */ +public class DefaultIdentityService implements IdentityService +{ + /** + * If there are roles refs present in the scope, then wrap the UserIdentity + * with one that uses the role references in the {@link UserIdentity#isUserInRole(String)} + */ + @Override + public Object associate(UserIdentity user) + { + return null; + } + + @Override + public void disassociate(Object previous) + { + } + + @Override + public Object setRunAs(UserIdentity user, RunAsToken token) + { + return token; + } + + @Override + public void unsetRunAs(Object lastToken) + { + } + + @Override + public RunAsToken newRunAsToken(String runAsName) + { + return new RoleRunAsToken(runAsName); + } + + @Override + public UserIdentity getSystemUserIdentity() + { + return null; + } + + @Override + public UserIdentity newUserIdentity(final Subject subject, final Principal userPrincipal, final String[] roles) + { + return new DefaultUserIdentity(subject, userPrincipal, roles); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java new file mode 100644 index 000000000000..b6e3d06e2802 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import javax.security.auth.Subject; + +/** + * The default implementation of UserIdentity. + */ +public class DefaultUserIdentity implements UserIdentity +{ + private final Subject _subject; + private final Principal _userPrincipal; + private final String[] _roles; + + public DefaultUserIdentity(Subject subject, Principal userPrincipal, String[] roles) + { + _subject = subject; + _userPrincipal = userPrincipal; + _roles = roles; + } + + @Override + public Subject getSubject() + { + return _subject; + } + + @Override + public Principal getUserPrincipal() + { + return _userPrincipal; + } + + @Override + public boolean isUserInRole(String role) + { + //Servlet Spec 3.1, pg 125 + if ("*".equals(role)) + return false; + + for (String r : _roles) + { + if (r.equals(role)) + return true; + } + return false; + } + + @Override + public String toString() + { + return DefaultUserIdentity.class.getSimpleName() + "('" + _userPrincipal + "')"; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java new file mode 100644 index 000000000000..e0be900baf14 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.server.Request; + +/** + * LoginService implementation which always denies any attempt to login. + */ +public class EmptyLoginService implements LoginService +{ + @Override + public String getName() + { + return null; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + return false; + } + + @Override + public IdentityService getIdentityService() + { + return null; + } + + @Override + public void setIdentityService(IdentityService service) + { + } + + @Override + public void logout(UserIdentity user) + { + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java new file mode 100644 index 000000000000..b0984027ae8d --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java @@ -0,0 +1,187 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.List; + +import org.eclipse.jetty.util.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An implementation of a LoginService that stores users and roles in-memory in HashMaps. + * The source of the users and roles information is a properties file formatted like so: + *

+ *  username: password [,rolename ...]
+ * 
+ * + * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password + * checksums. + *

+ * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:. + */ +public class HashLoginService extends AbstractLoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(HashLoginService.class); + + private Resource _config; + private int refreshInterval; // default is not to reload + private UserStore _userStore; + private boolean _userStoreAutoCreate = false; + + public HashLoginService() + { + } + + public HashLoginService(String name) + { + setName(name); + } + + public HashLoginService(String name, Resource config) + { + setName(name); + setConfig(config); + } + + public Resource getConfig() + { + return _config; + } + + /** + * Load users from properties file. + *

+ * The property file maps usernames to password specs followed by an optional comma separated list of role names. + *

+ * + * @param config uri or url or path to realm properties file + */ + public void setConfig(Resource config) + { + _config = config; + } + + /** + * Is hot reload enabled on this user store + * + * @return true if hot reload was enabled before startup + * @deprecated use {@link #getRefreshInterval()} + */ + @Deprecated + public boolean isHotReload() + { + return refreshInterval > 0; + } + + /** + * Enable Hot Reload of the Property File + * + * @param enable true to enable 1s refresh interval, false to disable + * @deprecated use {@link #setRefreshInterval(int)} + */ + @Deprecated + public void setHotReload(boolean enable) + { + setRefreshInterval(enable ? 1 : 0); + } + + /** + * @return the scan interval in seconds for reloading the property file. + */ + public int getRefreshInterval() + { + return refreshInterval; + } + + /** + * @param refreshIntervalSeconds Set the scan interval in seconds for reloading the property file. + */ + public void setRefreshInterval(int refreshIntervalSeconds) + { + if (isRunning()) + throw new IllegalStateException("Cannot set while user store is running"); + this.refreshInterval = refreshIntervalSeconds; + } + + /** + * Configure the {@link UserStore} implementation to use. + * If none, for backward compat if none the {@link PropertyUserStore} will be used + * + * @param userStore the {@link UserStore} implementation to use + */ + public void setUserStore(UserStore userStore) + { + updateBean(_userStore, userStore); + _userStore = userStore; + } + + @Override + protected List loadRoleInfo(UserPrincipal user) + { + return _userStore.getRolePrincipals(user.getName()); + } + + @Override + protected UserPrincipal loadUserInfo(String userName) + { + return _userStore.getUserPrincipal(userName); + } + + @Override + protected void doStart() throws Exception + { + super.doStart(); + if (_userStore == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: {} refresh: {}s", _config, refreshInterval); + PropertyUserStore propertyUserStore = new PropertyUserStore(); + propertyUserStore.setRefreshInterval(refreshInterval); + propertyUserStore.setConfig(_config); + setUserStore(propertyUserStore); + _userStoreAutoCreate = true; + } + } + + /** + * To facilitate testing. + * + * @return the UserStore + */ + UserStore getUserStore() + { + return _userStore; + } + + /** + * + * @return true if a UserStore has been created from a config, false if a UserStore was provided. + */ + boolean isUserStoreAutoCreate() + { + return _userStoreAutoCreate; + } + + @Override + protected void doStop() throws Exception + { + super.doStop(); + if (_userStoreAutoCreate) + { + setUserStore(null); + _userStoreAutoCreate = false; + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java new file mode 100644 index 000000000000..9725f36abad8 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -0,0 +1,85 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import javax.security.auth.Subject; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; + +/** + * Associates UserIdentities from with threads and UserIdentity.Contexts. + */ +public interface IdentityService +{ + static final String[] NO_ROLES = new String[]{}; + + /** + * Associate a user identity with the current thread. + * This is called with as a thread enters the + * {@link Handler#process(Request, org.eclipse.jetty.server.Response, org.eclipse.jetty.util.Callback)} + * method and then again with a null argument as that call exits. + * + * @param user The current user or null for no user to associated. + * @return an object representing the previous associated state + */ + Object associate(UserIdentity user); + + /** + * Disassociate the user identity from the current thread + * and restore previous identity. + * + * @param previous The opaque object returned from a call to {@link IdentityService#associate(UserIdentity)} + */ + void disassociate(Object previous); + + /** + * Associate a runas Token with the current user and thread. + * + * @param user The UserIdentity + * @param token The runAsToken to associate. + * @return The previous runAsToken or null. + */ + Object setRunAs(UserIdentity user, RunAsToken token); + + /** + * Disassociate the current runAsToken from the thread + * and reassociate the previous token. + * + * @param token RUNAS returned from previous associateRunAs call + */ + void unsetRunAs(Object token); + + /** + * Create a new UserIdentity for use with this identity service. + * The UserIdentity should be immutable and able to be cached. + * + * @param subject Subject to include in UserIdentity + * @param userPrincipal Principal to include in UserIdentity. This will be returned from getUserPrincipal calls + * @param roles set of roles to include in UserIdentity. + * @return A new immutable UserIdententity + */ + UserIdentity newUserIdentity(Subject subject, Principal userPrincipal, String[] roles); + + /** + * Create a new RunAsToken from a runAsName (normally a role). + * + * @param runAsName Normally a role name + * @return A new immutable RunAsToken + */ + RunAsToken newRunAsToken(String runAsName); + + UserIdentity getSystemUserIdentity(); +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java new file mode 100644 index 000000000000..ea977943ecab --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java @@ -0,0 +1,260 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.InputStream; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.stream.Collectors; + +import org.eclipse.jetty.util.Loader; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JDBC as a source of user authentication and authorization information. + * Uses one database connection that is lazily initialized. Reconnect on failures. + */ +public class JDBCLoginService extends AbstractLoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginService.class); + + protected String _config; + protected String _jdbcDriver; + protected String _url; + protected String _userName; + protected String _password; + protected String _userTableKey; + protected String _userTablePasswordField; + protected String _roleTableRoleField; + protected String _userSql; + protected String _roleSql; + protected Connection _con; + + /** + * JDBCUserPrincipal + * + * A UserPrincipal with extra jdbc key info. + */ + public class JDBCUserPrincipal extends UserPrincipal + { + final int _userKey; + + public JDBCUserPrincipal(String name, Credential credential, int key) + { + super(name, credential); + _userKey = key; + } + + public int getUserKey() + { + return _userKey; + } + } + + public JDBCLoginService() + { + } + + public JDBCLoginService(String name) + { + setName(name); + } + + public JDBCLoginService(String name, String config) + { + setName(name); + setConfig(config); + } + + public JDBCLoginService(String name, IdentityService identityService, String config) + { + setName(name); + setIdentityService(identityService); + setConfig(config); + } + + @Override + protected void doStart() throws Exception + { + Properties properties = new Properties(); + try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable(); + InputStream in = resourceFactory.newResource(_config).newInputStream()) + { + properties.load(in); + } + _jdbcDriver = properties.getProperty("jdbcdriver"); + _url = properties.getProperty("url"); + _userName = properties.getProperty("username"); + _password = properties.getProperty("password"); + _userTableKey = properties.getProperty("usertablekey"); + _userTablePasswordField = properties.getProperty("usertablepasswordfield"); + _roleTableRoleField = properties.getProperty("roletablerolefield"); + + final String userTable = properties.getProperty("usertable"); + final String userTableUserField = properties.getProperty("usertableuserfield"); + final String roleTable = properties.getProperty("roletable"); + final String roleTableKey = properties.getProperty("roletablekey"); + final String userRoleTable = properties.getProperty("userroletable"); + final String userRoleTableUserKey = properties.getProperty("userroletableuserkey"); + final String userRoleTableRoleKey = properties.getProperty("userroletablerolekey"); + + if (_jdbcDriver == null || _jdbcDriver.equals("") || + _url == null || _url.equals("") || + _userName == null || _userName.equals("") || + _password == null) + { + LOG.warn("UserRealm {} has not been properly configured", getName()); + } + + _userSql = "select " + _userTableKey + "," + _userTablePasswordField + " from " + userTable + " where " + userTableUserField + " = ?"; + _roleSql = "select r." + _roleTableRoleField + + " from " + roleTable + " r, " + userRoleTable + + " u where u." + userRoleTableUserKey + " = ?" + + " and r." + roleTableKey + " = u." + userRoleTableRoleKey; + + Loader.loadClass(_jdbcDriver).getDeclaredConstructor().newInstance(); + super.doStart(); + } + + public String getConfig() + { + return _config; + } + + /** + * Load JDBC connection configuration from properties file. + * + * @param config Filename or url of user properties file. + */ + public void setConfig(String config) + { + if (isRunning()) + throw new IllegalStateException("Running"); + _config = config; + } + + /** + * Connect to database with parameters setup by loadConfig() + */ + public Connection connectDatabase() + throws SQLException + { + return DriverManager.getConnection(_url, _userName, _password); + } + + @Override + public UserPrincipal loadUserInfo(String username) + { + try + { + if (null == _con) + _con = connectDatabase(); + + try (PreparedStatement stat1 = _con.prepareStatement(_userSql)) + { + stat1.setObject(1, username); + try (ResultSet rs1 = stat1.executeQuery()) + { + if (rs1.next()) + { + int key = rs1.getInt(_userTableKey); + String credentials = rs1.getString(_userTablePasswordField); + + return new JDBCUserPrincipal(username, Credential.getCredential(credentials), key); + } + } + } + } + catch (SQLException e) + { + LOG.warn("LoginService {} could not load user {}", getName(), username, e); + closeConnection(); + } + + return null; + } + + @Override + public List loadRoleInfo(UserPrincipal user) + { + if (user == null) + return null; + + JDBCUserPrincipal jdbcUser = (JDBCUserPrincipal)user; + + try + { + if (null == _con) + _con = connectDatabase(); + + List roles = new ArrayList(); + + try (PreparedStatement stat2 = _con.prepareStatement(_roleSql)) + { + stat2.setInt(1, jdbcUser.getUserKey()); + try (ResultSet rs2 = stat2.executeQuery()) + { + while (rs2.next()) + roles.add(rs2.getString(_roleTableRoleField)); + + return roles.stream().map(RolePrincipal::new).collect(Collectors.toList()); + } + } + } + catch (SQLException e) + { + LOG.warn("LoginService {} could not load roles for user {}", getName(), user.getName(), e); + closeConnection(); + } + + return null; + } + + @Override + protected void doStop() throws Exception + { + closeConnection(); + super.doStop(); + } + + /** + * Close an existing connection + */ + private void closeConnection() + { + if (_con != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Closing db connection for JDBCLoginService"); + try + { + _con.close(); + } + catch (Exception e) + { + LOG.trace("IGNORED", e); + } + } + _con = null; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java new file mode 100644 index 000000000000..ac3bada8d130 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.server.Request; + +/** + * LoggedOutAuthentication + * + * An Authentication indicating that a user has been previously, but is not currently logged in, + * but may be capable of logging in after a call to Request.login(String,String) + */ +public class LoggedOutAuthentication implements Authentication.NonAuthenticated +{ + private LoginAuthenticator _authenticator; + + public LoggedOutAuthentication(LoginAuthenticator authenticator) + { + _authenticator = authenticator; + } + + @Override + public Authentication login(String username, Object password, Request request, Response response) + { + if (username == null) + return null; + + UserIdentity identity = _authenticator.login(username, password, request, res); + if (identity != null) + { + IdentityService identityService = _authenticator.getLoginService().getIdentityService(); + UserAuthentication authentication = new UserAuthentication("API", identity); + if (identityService != null) + identityService.associate(identity); + return authentication; + } + return null; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java new file mode 100644 index 000000000000..3fbb37d2f378 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.server.Request; + +/** + * Login Service Interface. + *

+ * The Login service provides an abstract mechanism for an {@link Authenticator} + * to check credentials and to create a {@link UserIdentity} using the + * set {@link IdentityService}. + */ +public interface LoginService +{ + + /** + * @return Get the name of the login service (aka Realm name) + */ + String getName(); + + /** + * Login a user. + * + * @param username The username. + * @param credentials The users credentials. + * @param request The request. + * @return A UserIdentity if the credentials matched, otherwise null + */ + UserIdentity login(String username, Object credentials, Request request); + + /** + * Validate a user identity. + * Validate that a UserIdentity previously created by a call + * to {@link #login(String, Object, Request)} is still valid. + * + * @param user The user to validate + * @return true if authentication has not been revoked for the user. + */ + boolean validate(UserIdentity user); + + /** + * Get the IdentityService associated with this Login Service. + * + * @return the IdentityService associated with this Login Service. + */ + IdentityService getIdentityService(); + + /** + * Set the IdentityService associated with this Login Service. + * + * @param service the IdentityService associated with this Login Service. + */ + void setIdentityService(IdentityService service); + + void logout(UserIdentity user); +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java new file mode 100644 index 000000000000..e9a959f982ba --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -0,0 +1,316 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.Resources; +import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

This class monitors a property file of the format mentioned below + * and notifies registered listeners of the changes to the the given file.

+ * + *
+ *  username: password [,rolename ...]
+ * 
+ * + *

Passwords may be clear text, obfuscated or checksummed. + * The class {@link org.eclipse.jetty.util.security.Password} should be used + * to generate obfuscated passwords or password checksums.

+ * + *

If DIGEST Authentication is used, the password must be in a recoverable + * format, either plain text or obfuscated.

+ */ +public class PropertyUserStore extends UserStore implements Scanner.DiscreteListener +{ + private static final Logger LOG = LoggerFactory.getLogger(PropertyUserStore.class); + + protected Resource _configResource; + protected Scanner _scanner; + protected int _refreshInterval = 0; + protected boolean _firstLoad = true; // true if first load, false from that point on + protected List _listeners; + + /** + * Get the config (as a string) + * + * @return the config path as a string + */ + public Resource getConfig() + { + return _configResource; + } + + /** + * Set the Config Path from a String reference to a file + * + * @param config the config file + * TODO: reintroduce setConfig(String) and internal ResourceFactory usage + */ + public void setConfig(Resource config) + { + _configResource = config; + } + + /** + * @return the resource associated with the configured properties file, creating it if necessary + * @deprecated + */ + @Deprecated(forRemoval = true) + public Resource getConfigResource() + { + return getConfig(); + } + + /** + * Is hot reload enabled on this user store + * + * @return true if hot reload was enabled before startup + * @deprecated use {@link #getRefreshInterval()} + */ + @Deprecated + public boolean isHotReload() + { + return getRefreshInterval() > 0; + } + + /** + * Enable Hot Reload of the Property File + * + * @param enable true to enable to a 1 second scan, false to disable + * @deprecated use {@link #setRefreshInterval(int)} + */ + @Deprecated + public void setHotReload(boolean enable) + { + setRefreshInterval(enable ? 1 : 0); + } + + /** + * Enable Hot Reload of the Property File + * + * @param scanSeconds the period in seconds to scan for property file changes, or 0 for no scanning + */ + public void setRefreshInterval(int scanSeconds) + { + if (isRunning()) + { + throw new IllegalStateException("Cannot set scan period while user store is running"); + } + this._refreshInterval = scanSeconds; + } + + /** + * @return the period in seconds to scan for property file changes, or 0 for no scanning + */ + public int getRefreshInterval() + { + return _refreshInterval; + } + + @Override + public String toString() + { + return String.format("%s[cfg=%s]", super.toString(), _configResource); + } + + /** + * Load the user data from the property file. + * @throws IOException If the users cannot be loaded + */ + protected void loadUsers() throws IOException + { + Resource config = getConfig(); + + if (config == null) + throw new IllegalStateException("No config path set"); + + if (LOG.isDebugEnabled()) + LOG.debug("Loading {} from {}", this, config); + + if (Resources.missing(config)) + throw new IllegalStateException("Config does not exist: " + config); + + Properties properties = new Properties(); + try (InputStream inputStream = config.newInputStream()) + { + if (inputStream == null) + throw new IllegalStateException("Config does have properties: " + config); + properties.load(inputStream); + } + + Set known = new HashSet<>(); + + for (Map.Entry entry : properties.entrySet()) + { + String username = ((String)entry.getKey()).trim(); + String credentials = ((String)entry.getValue()).trim(); + String roles = null; + int c = credentials.indexOf(','); + if (c >= 0) + { + roles = credentials.substring(c + 1).trim(); + credentials = credentials.substring(0, c).trim(); + } + + if (username.length() > 0) + { + String[] roleArray = IdentityService.NO_ROLES; + if (roles != null && roles.length() > 0) + roleArray = StringUtil.csvSplit(roles); + known.add(username); + Credential credential = Credential.getCredential(credentials); + addUser(username, credential, roleArray); + notifyUpdate(username, credential, roleArray); + } + } + + List currentlyKnownUsers = new ArrayList<>(_users.keySet()); + // if its not the initial load then we want to process removed users + if (!_firstLoad) + { + for (String user : currentlyKnownUsers) + { + if (!known.contains(user)) + { + removeUser(user); + notifyRemove(user); + } + } + } + + // set initial load to false as there should be no more initial loads + _firstLoad = false; + + if (LOG.isDebugEnabled()) + LOG.debug("Loaded {} from {}", this, config); + } + + /** + * Depending on the value of the refresh interval, this method will either start + * up a scanner thread that will monitor the properties file for changes after + * it has initially loaded it. Otherwise the users will be loaded and there will + * be no active monitoring thread so changes will not be detected. + */ + @Override + protected void doStart() throws Exception + { + Resource config = getConfig(); + if (getRefreshInterval() > 0 && (config != null)) + { + _scanner = new Scanner(null, false); + _scanner.addFile(config.getPath()); + _scanner.setScanInterval(_refreshInterval); + _scanner.setReportExistingFilesOnStartup(false); + _scanner.addListener(this); + addBean(_scanner); + } + + loadUsers(); + super.doStart(); + } + + @Override + public void pathChanged(Path path) throws Exception + { + loadUsers(); + } + + @Override + public void pathAdded(Path path) throws Exception + { + loadUsers(); + } + + @Override + public void pathRemoved(Path path) throws Exception + { + loadUsers(); + } + + @Override + protected void doStop() throws Exception + { + super.doStop(); + removeBean(_scanner); + _scanner = null; + } + + /** + * Notifies the registered listeners of potential updates to a user + * + * @param username the user that was updated + * @param credential the updated credentials + * @param roleArray the updated roles + */ + private void notifyUpdate(String username, Credential credential, String[] roleArray) + { + if (_listeners != null) + { + for (UserListener listener : _listeners) + { + listener.update(username, credential, roleArray); + } + } + } + + /** + * Notifies the registered listeners that a user has been removed. + * + * @param username the user that was removed + */ + private void notifyRemove(String username) + { + if (_listeners != null) + { + for (UserListener listener : _listeners) + { + listener.remove(username); + } + } + } + + /** + * Registers a listener to be notified of the contents of the property file + * + * @param listener the user listener + */ + public void registerUserListener(UserListener listener) + { + if (_listeners == null) + _listeners = new ArrayList<>(); + _listeners.add(listener); + } + + public interface UserListener + { + void update(String username, Credential credential, String[] roleArray); + + void remove(String username); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java new file mode 100644 index 000000000000..026b27319f5f --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java @@ -0,0 +1,162 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * RoleInfo + * + * Badly named class that holds the role and user data constraint info for a + * path/http method combination, extracted and combined from security + * constraints. + * + * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ + */ +public class RoleInfo +{ + private boolean _isAnyAuth; + private boolean _isAnyRole; + private boolean _checked; + private boolean _forbidden; + private UserDataConstraint _userDataConstraint; + + /** + * List of permitted roles + */ + private final Set _roles = new CopyOnWriteArraySet<>(); + + public RoleInfo() + { + } + + public boolean isChecked() + { + return _checked; + } + + public void setChecked(boolean checked) + { + this._checked = checked; + if (!checked) + { + _forbidden = false; + _roles.clear(); + _isAnyRole = false; + _isAnyAuth = false; + } + } + + public boolean isForbidden() + { + return _forbidden; + } + + public void setForbidden(boolean forbidden) + { + this._forbidden = forbidden; + if (forbidden) + { + _checked = true; + _userDataConstraint = null; + _isAnyRole = false; + _isAnyAuth = false; + _roles.clear(); + } + } + + public boolean isAnyRole() + { + return _isAnyRole; + } + + public void setAnyRole(boolean anyRole) + { + this._isAnyRole = anyRole; + if (anyRole) + _checked = true; + } + + public boolean isAnyAuth() + { + return _isAnyAuth; + } + + public void setAnyAuth(boolean anyAuth) + { + this._isAnyAuth = anyAuth; + if (anyAuth) + _checked = true; + } + + public UserDataConstraint getUserDataConstraint() + { + return _userDataConstraint; + } + + public void setUserDataConstraint(UserDataConstraint userDataConstraint) + { + if (userDataConstraint == null) + throw new NullPointerException("Null UserDataConstraint"); + if (this._userDataConstraint == null) + { + + this._userDataConstraint = userDataConstraint; + } + else + { + this._userDataConstraint = this._userDataConstraint.combine(userDataConstraint); + } + } + + public Set getRoles() + { + return _roles; + } + + public void addRole(String role) + { + _roles.add(role); + } + + public void combine(RoleInfo other) + { + if (other._forbidden) + setForbidden(true); + else if (other._checked) + { + setChecked(true); + if (other._isAnyAuth) + setAnyAuth(true); + if (other._isAnyRole) + setAnyRole(true); + + _roles.addAll(other._roles); + } + setUserDataConstraint(other._userDataConstraint); + } + + @Override + public String toString() + { + return String.format("RoleInfo@%x{%s%s%s%s,%s}", + hashCode(), + (_forbidden ? "Forbidden," : ""), + (_checked ? "Checked," : ""), + (_isAnyAuth ? "AnyAuth," : ""), + (_isAnyRole ? "*" : _roles), + _userDataConstraint); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java new file mode 100644 index 000000000000..fd34e91800a5 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java @@ -0,0 +1,47 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.Serializable; +import java.security.Principal; +import javax.security.auth.Subject; + +/** + * RolePrincipal + * + * Represents a role. This class can be added to a Subject to represent a role that the + * Subject has. + * + */ +public class RolePrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = 2998397924051854402L; + private final String _roleName; + + public RolePrincipal(String name) + { + _roleName = name; + } + + @Override + public String getName() + { + return _roleName; + } + + public void configureForSubject(Subject subject) + { + subject.getPrincipals().add(this); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java new file mode 100644 index 000000000000..ecb4423497ee --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +/** + * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ + */ +public class RoleRunAsToken implements RunAsToken +{ + private final String _runAsRole; + + public RoleRunAsToken(String runAsRole) + { + this._runAsRole = runAsRole; + } + + public String getRunAsRole() + { + return _runAsRole; + } + + @Override + public String toString() + { + return "RoleRunAsToken(" + _runAsRole + ")"; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java new file mode 100644 index 000000000000..d0c2a530fce1 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +/** + * marker interface for run-as-role tokens + * + * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ + */ +public interface RunAsToken +{ +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java new file mode 100644 index 000000000000..180fec8dea96 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -0,0 +1,679 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.ee10.servlet.ServletApiRequest; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletContextRequest; +import org.eclipse.jetty.ee10.servlet.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.server.Context; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.component.DumpableCollection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract SecurityHandler. + *

+ * Select and apply an {@link Authenticator} to a request. + *

+ * The Authenticator may either be directly set on the handler + * or will be create during {@link #start()} with a call to + * either the default or set AuthenticatorFactory. + *

+ * SecurityHandler has a set of initparameters that are used by the + * Authentication.Configuration. At startup, any context init parameters + * that start with "org.eclipse.jetty.security." that do not have + * values in the SecurityHandler init parameters, are copied. + */ +public abstract class SecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration +{ + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); + private static final List __knownAuthenticatorFactories = new ArrayList<>(); + + private boolean _checkWelcomeFiles = false; + private Authenticator _authenticator; + private Authenticator.Factory _authenticatorFactory; + private String _realmName; + private String _authMethod; + private final Map _initParameters = new HashMap<>(); + private LoginService _loginService; + private IdentityService _identityService; + private boolean _renewSession = true; + + static + { + TypeUtil.serviceStream(ServiceLoader.load(Authenticator.Factory.class)) + .forEach(__knownAuthenticatorFactories::add); + __knownAuthenticatorFactories.add(new DefaultAuthenticatorFactory()); + } + + protected SecurityHandler() + { + addBean(new DumpableCollection("knownAuthenticatorFactories", __knownAuthenticatorFactories)); + } + + /** + * Get the identityService. + * + * @return the identityService + */ + @Override + public IdentityService getIdentityService() + { + return _identityService; + } + + /** + * Set the identityService. + * + * @param identityService the identityService to set + */ + public void setIdentityService(IdentityService identityService) + { + if (isStarted()) + throw new IllegalStateException("Started"); + updateBean(_identityService, identityService); + _identityService = identityService; + } + + /** + * Get the loginService. + * + * @return the loginService + */ + @Override + public LoginService getLoginService() + { + return _loginService; + } + + /** + * Set the loginService. + * + * @param loginService the loginService to set + */ + public void setLoginService(LoginService loginService) + { + if (isStarted()) + throw new IllegalStateException("Started"); + updateBean(_loginService, loginService); + _loginService = loginService; + } + + public Authenticator getAuthenticator() + { + return _authenticator; + } + + /** + * Set the authenticator. + * + * @param authenticator the authenticator + * @throws IllegalStateException if the SecurityHandler is running + */ + public void setAuthenticator(Authenticator authenticator) + { + if (isStarted()) + throw new IllegalStateException("Started"); + updateBean(_authenticator, authenticator); + _authenticator = authenticator; + if (_authenticator != null) + _authMethod = _authenticator.getAuthMethod(); + } + + /** + * @return the authenticatorFactory + */ + public Authenticator.Factory getAuthenticatorFactory() + { + return _authenticatorFactory; + } + + /** + * @param authenticatorFactory the authenticatorFactory to set + * @throws IllegalStateException if the SecurityHandler is running + */ + public void setAuthenticatorFactory(Authenticator.Factory authenticatorFactory) + { + if (isRunning()) + throw new IllegalStateException("running"); + updateBean(_authenticatorFactory, authenticatorFactory); + _authenticatorFactory = authenticatorFactory; + } + + /** + * @return the list of discovered authenticatorFactories + */ + public List getKnownAuthenticatorFactories() + { + return __knownAuthenticatorFactories; + } + + /** + * @return the realmName + */ + @Override + public String getRealmName() + { + return _realmName; + } + + /** + * @param realmName the realmName to set + * @throws IllegalStateException if the SecurityHandler is running + */ + public void setRealmName(String realmName) + { + if (isRunning()) + throw new IllegalStateException("running"); + _realmName = realmName; + } + + /** + * @return the authMethod + */ + @Override + public String getAuthMethod() + { + return _authMethod; + } + + /** + * @param authMethod the authMethod to set + * @throws IllegalStateException if the SecurityHandler is running + */ + public void setAuthMethod(String authMethod) + { + if (isRunning()) + throw new IllegalStateException("running"); + _authMethod = authMethod; + } + + /** + * @return True if forwards to welcome files are authenticated + */ + public boolean isCheckWelcomeFiles() + { + return _checkWelcomeFiles; + } + + /** + * @param authenticateWelcomeFiles True if forwards to welcome files are + * authenticated + * @throws IllegalStateException if the SecurityHandler is running + */ + public void setCheckWelcomeFiles(boolean authenticateWelcomeFiles) + { + if (isRunning()) + throw new IllegalStateException("running"); + _checkWelcomeFiles = authenticateWelcomeFiles; + } + + @Override + public String getInitParameter(String key) + { + return _initParameters.get(key); + } + + @Override + public Set getInitParameterNames() + { + return _initParameters.keySet(); + } + + /** + * Set an initialization parameter. + * + * @param key the init key + * @param value the init value + * @return previous value + * @throws IllegalStateException if the SecurityHandler is started + */ + public String setInitParameter(String key, String value) + { + if (isStarted()) + throw new IllegalStateException("started"); + return _initParameters.put(key, value); + } + + protected LoginService findLoginService() throws Exception + { + java.util.Collection list = getServer().getBeans(LoginService.class); + LoginService service = null; + String realm = getRealmName(); + if (realm != null) + { + for (LoginService s : list) + { + if (s.getName() != null && s.getName().equals(realm)) + { + service = s; + break; + } + } + } + else if (list.size() == 1) + service = list.iterator().next(); + + return service; + } + + protected IdentityService findIdentityService() + { + return getServer().getBean(IdentityService.class); + } + + @Override + protected void doStart() + throws Exception + { + // copy security init parameters + Context context = ContextHandler.getCurrentContext(); + if (context != null) + { + Enumeration names = context.getInitParameterNames(); + while (names != null && names.hasMoreElements()) + { + String name = names.nextElement(); + if (name.startsWith("org.eclipse.jetty.security.") && + getInitParameter(name) == null) + setInitParameter(name, context.getInitParameter(name)); + } + } + + // complicated resolution of login and identity service to handle + // many different ways these can be constructed and injected. + + if (_loginService == null) + { + setLoginService(findLoginService()); + if (_loginService != null) + unmanage(_loginService); + } + + if (_identityService == null) + { + if (_loginService != null) + setIdentityService(_loginService.getIdentityService()); + + if (_identityService == null) + setIdentityService(findIdentityService()); + + if (_identityService == null) + { + setIdentityService(new DefaultIdentityService()); + manage(_identityService); + } + else + unmanage(_identityService); + } + + if (_loginService != null) + { + if (_loginService.getIdentityService() == null) + _loginService.setIdentityService(_identityService); + else if (_loginService.getIdentityService() != _identityService) + throw new IllegalStateException("LoginService has different IdentityService to " + this); + } + + if (_authenticator == null) + { + // If someone has set an authenticator factory only use that, otherwise try the list of discovered factories. + if (_authenticatorFactory != null) + { + Authenticator authenticator = _authenticatorFactory.getAuthenticator(getServer(), context, + this, _identityService, _loginService); + + if (authenticator != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Created authenticator {} with {}", authenticator, _authenticatorFactory); + + setAuthenticator(authenticator); + } + } + else + { + for (Authenticator.Factory factory : getKnownAuthenticatorFactories()) + { + Authenticator authenticator = factory.getAuthenticator(getServer(), context, + this, _identityService, _loginService); + + if (authenticator != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Created authenticator {} with {}", authenticator, factory); + + setAuthenticator(authenticator); + break; + } + } + } + } + + if (_authenticator != null) + _authenticator.setConfiguration(this); + else if (_realmName != null) + { + LOG.warn("No Authenticator for {}", this); + throw new IllegalStateException("No Authenticator"); + } + + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + //if we discovered the services (rather than had them explicitly configured), remove them. + if (!isManaged(_identityService)) + { + removeBean(_identityService); + _identityService = null; + } + + if (!isManaged(_loginService)) + { + removeBean(_loginService); + _loginService = null; + } + + super.doStop(); + } + + protected boolean checkSecurity(Request request) + { + switch (request.getDispatcherType()) + { + case REQUEST: + case ASYNC: + return true; + case FORWARD: + if (isCheckWelcomeFiles() && request.getAttribute("org.eclipse.jetty.server.welcome") != null) + { + request.removeAttribute("org.eclipse.jetty.server.welcome"); + return true; + } + return false; + default: + return false; + } + } + + @Override + public boolean isSessionRenewedOnAuthentication() + { + return _renewSession; + } + + /** + * Set renew the session on Authentication. + *

+ * If set to true, then on authentication, the session associated with a reqeuest is invalidated and replaced with a new session. + * + * @param renew true to renew the authentication on session + * @see Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication() + */ + public void setSessionRenewedOnAuthentication(boolean renew) + { + _renewSession = renew; + } + + @Override + public boolean process(Request request, Response response, Callback callback) throws Exception + { + Handler next = getHandler(); + if (next == null) + return false; + + ServletContextRequest servletContextRequest = Request.as(request, ServletContextRequest.class); + if (servletContextRequest == null) + return false; + ServletApiRequest servletApiRequest = servletContextRequest.getServletApiRequest(); + Authenticator authenticator = _authenticator; + + if (!checkSecurity(servletApiRequest)) + { + //don't need to do any security work, let other handlers do the processing + return next.process(request, response, callback); + } + + //See Servlet Spec 3.1 sec 13.6.3 + if (authenticator != null) + authenticator.prepareRequest(request); + + RoleInfo roleInfo = prepareConstraintInfo(servletContextRequest.getPathInContext(), servletApiRequest); + + // Check data constraints + if (!checkUserDataPermissions(servletContextRequest.getPathInContext(), servletContextRequest, response, callback, roleInfo)) + return true; + + // is Auth mandatory? + boolean isAuthMandatory = + isAuthMandatory(request, response, roleInfo); + + if (isAuthMandatory && authenticator == null) + { + LOG.warn("No authenticator for: {}", roleInfo); + Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN); + return true; + } + + // check authentication + Object previousIdentity = null; + try + { + Authentication authentication = servletApiRequest.getAuthentication(); + if (authentication == null || authentication == Authentication.NOT_CHECKED) + authentication = authenticator == null ? Authentication.UNAUTHENTICATED : authenticator.validateRequest(request, response, callback, isAuthMandatory); + + if (authentication instanceof Authentication.ResponseSent) + return true; + + if (authentication instanceof Authentication.User userAuth) + { + servletApiRequest.setAuthentication(authentication); + if (_identityService != null) + previousIdentity = _identityService.associate(userAuth.getUserIdentity()); + + if (isAuthMandatory) + { + boolean authorized = checkWebResourcePermissions(Request.getPathInContext(request), request, response, roleInfo, userAuth.getUserIdentity()); + if (!authorized) + { + Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN, "!role"); + return true; + } + } + + //process the request by other handlers + boolean processed = next.process(request, response, callback); + // TODO this looks wrong + if (processed && authenticator != null) + authenticator.secureResponse(request, response, callback, isAuthMandatory, userAuth); + return processed; + } + + if (authentication instanceof Authentication.Deferred) + { + DeferredAuthentication deferred = (DeferredAuthentication)authentication; + servletApiRequest.setAuthentication(authentication); + + boolean processed = false; + try + { + //process the request by other handlers + processed = next.process(request, response, callback); + } + finally + { + previousIdentity = deferred.getPreviousAssociation(); + } + + if (processed && authenticator != null) + { + Authentication auth = servletApiRequest.getAuthentication(); + if (auth instanceof Authentication.User userAuth) + authenticator.secureResponse(request, response, callback, isAuthMandatory, userAuth); + else + authenticator.secureResponse(request, response, callback, isAuthMandatory, null); + } + return processed; + } + + if (isAuthMandatory) + { + Response.writeError(request, response, callback, HttpServletResponse.SC_UNAUTHORIZED, "unauthenticated"); + return true; + } + + servletApiRequest.setAuthentication(authentication); + if (_identityService != null) + previousIdentity = _identityService.associate(null); + + //process the request by other handlers + boolean processed = next.process(request, response, callback); + + if (processed && authenticator != null) + authenticator.secureResponse(request, response, callback, isAuthMandatory, null); + return processed; + } + catch (ServerAuthException e) + { + // jaspi 3.8.3 send HTTP 500 internal server error, with message from AuthException + Response.writeError(request, response, callback, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + return true; + } + finally + { + if (_identityService != null) + _identityService.disassociate(previousIdentity); + } + } + + public static SecurityHandler getCurrentSecurityHandler() + { + ServletContextHandler contextHandler = ServletContextHandler.getCurrentServletContextHandler(); + if (contextHandler == null) + return null; + + return contextHandler.getDescendant(SecurityHandler.class); + } + + public void logout(Authentication.User user) + { + LOG.debug("logout {}", user); + if (user == null) + return; + + LoginService loginService = getLoginService(); + if (loginService != null) + { + loginService.logout(user.getUserIdentity()); + } + + IdentityService identityService = getIdentityService(); + if (identityService != null) + { + // TODO recover previous from threadlocal (or similar) + Object previous = null; + identityService.disassociate(previous); + } + } + + protected abstract RoleInfo prepareConstraintInfo(String pathInContext, HttpServletRequest request); + + protected abstract boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Callback callback, RoleInfo constraintInfo) throws IOException; + + protected abstract boolean isAuthMandatory(Request baseRequest, Response baseResponse, Object constraintInfo); + + protected abstract boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, + UserIdentity userIdentity) throws IOException; + + public class NotChecked implements Principal + { + @Override + public String getName() + { + return null; + } + + @Override + public String toString() + { + return "NOT CHECKED"; + } + + public SecurityHandler getSecurityHandler() + { + return SecurityHandler.this; + } + } + + public static final Principal __NO_USER = new Principal() + { + @Override + public String getName() + { + return null; + } + + @Override + public String toString() + { + return "No User"; + } + }; + + /** + * Nobody user. The Nobody UserPrincipal is used to indicate a partial state + * of authentication. A request with a Nobody UserPrincipal will be allowed + * past all authentication constraints - but will not be considered an + * authenticated request. It can be used by Authenticators such as + * FormAuthenticator to allow access to logon and error pages within an + * authenticated URI tree. + */ + public static final Principal __NOBODY = new Principal() + { + @Override + public String getName() + { + return "Nobody"; + } + + @Override + public String toString() + { + return getName(); + } + }; +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java new file mode 100644 index 000000000000..e503667313b0 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.GeneralSecurityException; + +/** + * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $ + */ +public class ServerAuthException extends GeneralSecurityException +{ + + public ServerAuthException() + { + } + + public ServerAuthException(String s) + { + super(s); + } + + public ServerAuthException(String s, Throwable throwable) + { + super(s, throwable); + } + + public ServerAuthException(Throwable throwable) + { + super(throwable); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java new file mode 100644 index 000000000000..d38dd24d3667 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java @@ -0,0 +1,54 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import javax.security.auth.Subject; + +public class SpnegoUserIdentity implements UserIdentity +{ + private final Subject _subject; + private final Principal _principal; + private final UserIdentity _roleDelegate; + + public SpnegoUserIdentity(Subject subject, Principal principal, UserIdentity roleDelegate) + { + _subject = subject; + _principal = principal; + _roleDelegate = roleDelegate; + } + + @Override + public Subject getSubject() + { + return _subject; + } + + @Override + public Principal getUserPrincipal() + { + return _principal; + } + + @Override + public boolean isUserInRole(String role) + { + return _roleDelegate != null && _roleDelegate.isUserInRole(role); + } + + public boolean isEstablished() + { + return _roleDelegate != null; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java new file mode 100644 index 000000000000..c7514b1ea073 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import java.util.Base64; + +public class SpnegoUserPrincipal implements Principal +{ + private final String _name; + private byte[] _token; + private String _encodedToken; + + public SpnegoUserPrincipal(String name, String encodedToken) + { + _name = name; + _encodedToken = encodedToken; + } + + public SpnegoUserPrincipal(String name, byte[] token) + { + _name = name; + _token = token; + } + + @Override + public String getName() + { + return _name; + } + + public byte[] getToken() + { + if (_token == null) + _token = Base64.getDecoder().decode(_encodedToken); + return _token; + } + + public String getEncodedToken() + { + if (_encodedToken == null) + _encodedToken = new String(Base64.getEncoder().encode(_token)); + return _encodedToken; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java new file mode 100644 index 000000000000..95abc4752bc7 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java @@ -0,0 +1,32 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +/** + * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ + */ +public class UserAuthentication extends AbstractUserAuthentication +{ + + public UserAuthentication(String method, UserIdentity userIdentity) + { + super(method, userIdentity); + } + + @Override + public String toString() + { + return "{User," + getAuthMethod() + "," + _userIdentity + "}"; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java new file mode 100644 index 000000000000..17d4c96c7fe8 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +/** + * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $ + */ +public enum UserDataConstraint +{ + None, Integral, Confidential; + + public static UserDataConstraint get(int dataConstraint) + { + if (dataConstraint < -1 || dataConstraint > 2) + throw new IllegalArgumentException("Expected -1, 0, 1, or 2, not: " + dataConstraint); + if (dataConstraint == -1) + return None; + return values()[dataConstraint]; + } + + public UserDataConstraint combine(UserDataConstraint other) + { + if (this.compareTo(other) < 0) + return this; + return other; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java new file mode 100644 index 000000000000..5ffae273d99f --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java @@ -0,0 +1,79 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.security.Principal; +import javax.security.auth.Subject; + +/** + * User object that encapsulates user identity and operations such as run-as-role actions, + * checking isUserInRole and getUserPrincipal. + *

+ * Implementations of UserIdentity should be immutable so that they may be + * cached by Authenticators and LoginServices. + */ +public interface UserIdentity +{ + + /** + * @return The user subject + */ + Subject getSubject(); + + /** + * @return The user principal + */ + Principal getUserPrincipal(); + + /** + * Check if the user is in a role. + * This call is used to satisfy authorization calls from + * container code which will be using translated role names. + * + * @param role A role name. + * @return True if the user can act in that role. + */ + boolean isUserInRole(String role); + + public interface UnauthenticatedUserIdentity extends UserIdentity + { + } + + public static final UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity() + { + @Override + public Subject getSubject() + { + return null; + } + + @Override + public Principal getUserPrincipal() + { + return null; + } + + @Override + public boolean isUserInRole(String role) + { + return false; + } + + @Override + public String toString() + { + return "UNAUTHENTICATED"; + } + }; +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java new file mode 100644 index 000000000000..069f6616e8ac --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java @@ -0,0 +1,87 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.Serializable; +import java.security.Principal; +import javax.security.auth.Subject; + +import org.eclipse.jetty.util.security.Credential; + +/** + * UserPrincipal + * + * Represents a user with a credential. + * Instances of this class can be added to a Subject to + * present the user, while the credentials can be added + * directly to the Subject. + */ +public class UserPrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = -6226920753748399662L; + private final String _name; + protected final Credential _credential; + + public UserPrincipal(String name, Credential credential) + { + _name = name; + _credential = credential; + } + + public boolean authenticate(Object credentials) + { + return _credential != null && _credential.check(credentials); + } + + public boolean authenticate(Credential c) + { + return (_credential != null && c != null && _credential.equals(c)); + } + + public boolean authenticate(UserPrincipal u) + { + return (u != null && authenticate(u._credential)); + } + + public void configureSubject(Subject subject) + { + if (subject == null) + return; + + subject.getPrincipals().add(this); + if (_credential != null) + subject.getPrivateCredentials().add(_credential); + } + + public void deconfigureSubject(Subject subject) + { + if (subject == null) + return; + subject.getPrincipals().remove(this); + if (_credential != null) + subject.getPrivateCredentials().remove(_credential); + } + + @Override + public String getName() + { + return _name; + } + + @Override + public String toString() + { + return _name; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java new file mode 100644 index 000000000000..0e9341539249 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java @@ -0,0 +1,87 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.security.Credential; + +/** + * Store of user authentication and authorization information. + * + */ +public class UserStore extends ContainerLifeCycle +{ + protected final Map _users = new ConcurrentHashMap<>(); + + protected class User + { + protected UserPrincipal _userPrincipal; + protected List _rolePrincipals = Collections.emptyList(); + + protected User(String username, Credential credential, String[] roles) + { + _userPrincipal = new UserPrincipal(username, credential); + + _rolePrincipals = Collections.emptyList(); + + if (roles != null) + _rolePrincipals = Arrays.stream(roles).map(RolePrincipal::new).collect(Collectors.toList()); + } + + protected UserPrincipal getUserPrincipal() + { + return _userPrincipal; + } + + protected List getRolePrincipals() + { + return _rolePrincipals; + } + } + + public void addUser(String username, Credential credential, String[] roles) + { + _users.put(username, new User(username, credential, roles)); + } + + public void removeUser(String username) + { + _users.remove(username); + } + + public UserPrincipal getUserPrincipal(String username) + { + User user = _users.get(username); + return (user == null ? null : user.getUserPrincipal()); + } + + public List getRolePrincipals(String username) + { + User user = _users.get(username); + return (user == null ? null : user.getRolePrincipals()); + } + + @Override + public String toString() + { + return String.format("%s@%x[users.count=%d]", getClass().getSimpleName(), hashCode(), _users.size()); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java new file mode 100644 index 000000000000..ff0ca3de4e85 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java @@ -0,0 +1,74 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Set; + +import org.eclipse.jetty.security.Authenticator.AuthConfiguration; + +/** + * A wrapper for {@link AuthConfiguration}. This allows you create a new AuthConfiguration which can + * override a method to change a value from an another instance of AuthConfiguration. + */ +public class WrappedAuthConfiguration implements AuthConfiguration +{ + private final AuthConfiguration _configuration; + + public WrappedAuthConfiguration(AuthConfiguration configuration) + { + _configuration = configuration; + } + + @Override + public String getAuthMethod() + { + return _configuration.getAuthMethod(); + } + + @Override + public String getRealmName() + { + return _configuration.getRealmName(); + } + + @Override + public String getInitParameter(String param) + { + return _configuration.getInitParameter(param); + } + + @Override + public Set getInitParameterNames() + { + return _configuration.getInitParameterNames(); + } + + @Override + public LoginService getLoginService() + { + return _configuration.getLoginService(); + } + + @Override + public IdentityService getIdentityService() + { + return _configuration.getIdentityService(); + } + + @Override + public boolean isSessionRenewedOnAuthentication() + { + return _configuration.isSessionRenewedOnAuthentication(); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java new file mode 100644 index 000000000000..a05ede0af0f1 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; + +/** + *

A service to query for user roles.

+ */ +@FunctionalInterface +public interface AuthorizationService +{ + /** + * @param request the current HTTP request + * @param name the user name + * @return a {@link UserIdentity} to query for roles of the given user + */ + UserIdentity getUserIdentity(Request request, String name); + + /** + *

Wraps a {@link LoginService} as an AuthorizationService

+ * + * @param loginService the {@link LoginService} to wrap + * @return an AuthorizationService that delegates the query for roles to the given {@link LoginService} + */ + public static AuthorizationService from(LoginService loginService, Object credentials) + { + return (request, name) -> loginService.login(name, credentials, request); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java new file mode 100644 index 000000000000..1290d24436ad --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -0,0 +1,104 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.security.Constraint; + +public class BasicAuthenticator extends LoginAuthenticator +{ + private Charset _charset; + + public Charset getCharset() + { + return _charset; + } + + public void setCharset(Charset charset) + { + this._charset = charset; + } + + @Override + public String getAuthMethod() + { + return Constraint.__BASIC_AUTH; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + String credentials = req.getHeaders().get(HttpHeader.AUTHORIZATION); + + if (!mandatory) + return new DeferredAuthentication(this); + + if (credentials != null) + { + int space = credentials.indexOf(' '); + if (space > 0) + { + String method = credentials.substring(0, space); + if ("basic".equalsIgnoreCase(method)) + { + credentials = credentials.substring(space + 1); + Charset charset = getCharset(); + if (charset == null) + charset = StandardCharsets.ISO_8859_1; + credentials = new String(Base64.getDecoder().decode(credentials), charset); + int i = credentials.indexOf(':'); + if (i > 0) + { + String username = credentials.substring(0, i); + String password = credentials.substring(i + 1); + + UserIdentity user = login(username, password, req, res); + if (user != null) + return new UserAuthentication(getAuthMethod(), user); + } + } + } + } + + if (DeferredAuthentication.isDeferred(res)) + return Authentication.UNAUTHENTICATED; + + String value = "basic realm=\"" + _loginService.getName() + "\""; + Charset charset = getCharset(); + if (charset != null) + value += ", charset=\"" + charset.name() + "\""; + res.getHeaders().put(HttpHeader.WWW_AUTHENTICATE.asString(), value); + Response.writeError(req, res, callback, HttpStatus.UNAUTHORIZED_401); + return Authentication.SEND_CONTINUE; + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java new file mode 100644 index 000000000000..79cb2a75920b --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -0,0 +1,368 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.security.KeyStore; +import java.security.Principal; +import java.security.cert.CRL; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Collection; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.security.CertificateUtils; +import org.eclipse.jetty.util.security.CertificateValidator; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Password; + +/** + * @deprecated Prefer using {@link SslClientCertAuthenticator} + */ +@Deprecated +public class ClientCertAuthenticator extends LoginAuthenticator +{ + /** + * String name of keystore password property. + */ + private static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password"; + + /** + * Truststore path + */ + private String _trustStorePath; + /** + * Truststore provider name + */ + private String _trustStoreProvider; + /** + * Truststore type + */ + private String _trustStoreType = "PKCS12"; + /** + * Truststore password + */ + private transient Password _trustStorePassword; + + /** + * Set to true if SSL certificate validation is required + */ + private boolean _validateCerts; + /** + * Path to file that contains Certificate Revocation List + */ + private String _crlPath; + /** + * Maximum certification path length (n - number of intermediate certs, -1 for unlimited) + */ + private int _maxCertPathLength = -1; + /** + * CRL Distribution Points (CRLDP) support + */ + private boolean _enableCRLDP = false; + /** + * On-Line Certificate Status Protocol (OCSP) support + */ + private boolean _enableOCSP = false; + /** + * Location of OCSP Responder + */ + private String _ocspResponderURL; + + public ClientCertAuthenticator() + { + super(); + } + + @Override + public String getAuthMethod() + { + return Constraint.__CERT_AUTH; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + if (!mandatory) + return new DeferredAuthentication(this); + + X509Certificate[] certs = (X509Certificate[])req.getAttribute("jakarta.servlet.request.X509Certificate"); + + try + { + // Need certificates. + if (certs != null && certs.length > 0) + { + + if (_validateCerts) + { + KeyStore trustStore = getKeyStore( + _trustStorePath, _trustStoreType, _trustStoreProvider, + _trustStorePassword == null ? null : _trustStorePassword.toString()); + Collection crls = loadCRL(_crlPath); + CertificateValidator validator = new CertificateValidator(trustStore, crls); + validator.validate(certs); + } + + for (X509Certificate cert : certs) + { + if (cert == null) + continue; + + Principal principal = cert.getSubjectDN(); + if (principal == null) + principal = cert.getIssuerDN(); + final String username = principal == null ? "clientcert" : principal.getName(); + + // TODO: investigate if using a raw byte[] is better vs older char[] + final char[] credential = Base64.getEncoder().encodeToString(cert.getSignature()).toCharArray(); + + UserIdentity user = login(username, credential, req, res); + if (user != null) + { + return new UserAuthentication(getAuthMethod(), user); + } + } + } + + if (!DeferredAuthentication.isDeferred(res)) + { + Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); + return Authentication.SEND_FAILURE; + } + + return Authentication.UNAUTHENTICATED; + } + catch (Exception e) + { + throw new ServerAuthException(e.getMessage()); + } + } + + /** + * Loads keystore using an input stream or a file path in the same + * order of precedence. + * + * Required for integrations to be able to override the mechanism + * used to load a keystore in order to provide their own implementation. + * + * @param storePath path of keystore file + * @param storeType keystore type + * @param storeProvider keystore provider + * @param storePassword keystore password + * @return created keystore + * @throws Exception if unable to get keystore + */ + protected KeyStore getKeyStore(String storePath, String storeType, String storeProvider, String storePassword) throws Exception + { + try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) + { + return CertificateUtils.getKeyStore(resourceFactory.newResource(storePath), storeType, storeProvider, storePassword); + } + } + + /** + * Loads certificate revocation list (CRL) from a file. + * + * Required for integrations to be able to override the mechanism used to + * load CRL in order to provide their own implementation. + * + * @param crlPath path of certificate revocation list file + * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the + * input stream. + * @throws Exception if unable to load CRL + */ + protected Collection loadCRL(String crlPath) throws Exception + { + return CertificateUtils.loadCRL(crlPath); + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } + + /** + * @return true if SSL certificate has to be validated + */ + public boolean isValidateCerts() + { + return _validateCerts; + } + + /** + * @param validateCerts true if SSL certificates have to be validated + */ + public void setValidateCerts(boolean validateCerts) + { + _validateCerts = validateCerts; + } + + /** + * @return The file name or URL of the trust store location + */ + public String getTrustStore() + { + return _trustStorePath; + } + + /** + * @param trustStorePath The file name or URL of the trust store location + */ + public void setTrustStore(String trustStorePath) + { + _trustStorePath = trustStorePath; + } + + /** + * @return The provider of the trust store + */ + public String getTrustStoreProvider() + { + return _trustStoreProvider; + } + + /** + * @param trustStoreProvider The provider of the trust store + */ + public void setTrustStoreProvider(String trustStoreProvider) + { + _trustStoreProvider = trustStoreProvider; + } + + /** + * @return The type of the trust store (default "PKCS12") + */ + public String getTrustStoreType() + { + return _trustStoreType; + } + + /** + * @param trustStoreType The type of the trust store + */ + public void setTrustStoreType(String trustStoreType) + { + _trustStoreType = trustStoreType; + } + + /** + * @param password The password for the trust store + */ + public void setTrustStorePassword(String password) + { + _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY, password, null); + } + + /** + * Get the crlPath. + * + * @return the crlPath + */ + public String getCrlPath() + { + return _crlPath; + } + + /** + * Set the crlPath. + * + * @param crlPath the crlPath to set + */ + public void setCrlPath(String crlPath) + { + _crlPath = crlPath; + } + + /** + * @return Maximum number of intermediate certificates in + * the certification path (-1 for unlimited) + */ + public int getMaxCertPathLength() + { + return _maxCertPathLength; + } + + /** + * @param maxCertPathLength maximum number of intermediate certificates in + * the certification path (-1 for unlimited) + */ + public void setMaxCertPathLength(int maxCertPathLength) + { + _maxCertPathLength = maxCertPathLength; + } + + /** + * @return true if CRL Distribution Points support is enabled + */ + public boolean isEnableCRLDP() + { + return _enableCRLDP; + } + + /** + * Enables CRL Distribution Points Support + * + * @param enableCRLDP true - turn on, false - turns off + */ + public void setEnableCRLDP(boolean enableCRLDP) + { + _enableCRLDP = enableCRLDP; + } + + /** + * @return true if On-Line Certificate Status Protocol support is enabled + */ + public boolean isEnableOCSP() + { + return _enableOCSP; + } + + /** + * Enables On-Line Certificate Status Protocol support + * + * @param enableOCSP true - turn on, false - turn off + */ + public void setEnableOCSP(boolean enableOCSP) + { + _enableOCSP = enableOCSP; + } + + /** + * @return Location of the OCSP Responder + */ + public String getOcspResponderURL() + { + return _ocspResponderURL; + } + + /** + * Set the location of the OCSP Responder. + * + * @param ocspResponderURL location of the OCSP Responder + */ + public void setOcspResponderURL(String ocspResponderURL) + { + _ocspResponderURL = ocspResponderURL; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java new file mode 100644 index 000000000000..cde8950a0048 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -0,0 +1,231 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.io.Serializable; +import java.time.Duration; +import java.time.Instant; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.ConfigurableSpnegoLoginService; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.SpnegoUserIdentity; +import org.eclipse.jetty.security.SpnegoUserPrincipal; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Session; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

A LoginAuthenticator that uses SPNEGO and the GSS API to authenticate requests.

+ *

A successful authentication from a client is cached for a configurable + * {@link #getAuthenticationDuration() duration} using the HTTP session; this avoids + * that the client is asked to authenticate for every request.

+ * + * @see ConfigurableSpnegoLoginService + */ +public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(ConfigurableSpnegoAuthenticator.class); + + private final String _authMethod; + private Duration _authenticationDuration = Duration.ofNanos(-1); + + public ConfigurableSpnegoAuthenticator() + { + this(Constraint.__SPNEGO_AUTH); + } + + /** + * Allow for a custom authMethod value to be set for instances where SPNEGO may not be appropriate + * + * @param authMethod the auth method + */ + public ConfigurableSpnegoAuthenticator(String authMethod) + { + _authMethod = authMethod; + } + + @Override + public String getAuthMethod() + { + return _authMethod; + } + + /** + * @return the authentication duration + */ + public Duration getAuthenticationDuration() + { + return _authenticationDuration; + } + + /** + *

Sets the duration of the authentication.

+ *

A negative duration means that the authentication is only valid for the current request.

+ *

A zero duration means that the authentication is valid forever.

+ *

A positive value means that the authentication is valid for the specified duration.

+ * + * @param authenticationDuration the authentication duration + */ + public void setAuthenticationDuration(Duration authenticationDuration) + { + _authenticationDuration = authenticationDuration; + } + + /** + * Only renew the session id if the user has been fully authenticated, don't + * renew the session for any of the intermediate request/response handshakes. + */ + @Override + public UserIdentity login(String username, Object password, Request request, Response response) + { + SpnegoUserIdentity user = (SpnegoUserIdentity)_loginService.login(username, password, request); + if (user != null && user.isEstablished()) + { + renewSession(request, response); + } + return user; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + if (!mandatory) + return new DeferredAuthentication(this); + + String header = req.getHeaders().get(HttpHeader.AUTHORIZATION); + String spnegoToken = getSpnegoToken(header); + Session httpSession = req.getSession(false); + + // We have a token from the client, so run the login. + if (header != null && spnegoToken != null) + { + SpnegoUserIdentity identity = (SpnegoUserIdentity)login(null, spnegoToken, req, res); + if (identity.isEstablished()) + { + if (!DeferredAuthentication.isDeferred(res)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Sending final token"); + // Send to the client the final token so that the + // client can establish the GSS context with the server. + SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal(); + setSpnegoToken(res, principal.getEncodedToken()); + } + + Duration authnDuration = getAuthenticationDuration(); + if (!authnDuration.isNegative()) + { + if (httpSession == null) + httpSession = req.getSession(true); + httpSession.setAttribute(UserIdentityHolder.ATTRIBUTE, new UserIdentityHolder(identity)); + } + return new UserAuthentication(getAuthMethod(), identity); + } + else + { + if (DeferredAuthentication.isDeferred(res)) + return Authentication.UNAUTHENTICATED; + if (LOG.isDebugEnabled()) + LOG.debug("Sending intermediate challenge"); + SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal(); + sendChallenge(req, res, callback, principal.getEncodedToken()); + return Authentication.SEND_CONTINUE; + } + } + // No token from the client; check if the client has logged in + // successfully before and the authentication has not expired. + else if (httpSession != null) + { + UserIdentityHolder holder = (UserIdentityHolder)httpSession.getAttribute(UserIdentityHolder.ATTRIBUTE); + if (holder != null) + { + UserIdentity identity = holder._userIdentity; + if (identity != null) + { + Duration authnDuration = getAuthenticationDuration(); + if (!authnDuration.isNegative()) + { + boolean expired = !authnDuration.isZero() && Instant.now().isAfter(holder._validFrom.plus(authnDuration)); + // Allow non-GET requests even if they're expired, so that + // the client does not need to send the request content again. + if (!expired || !HttpMethod.GET.is(req.getMethod())) + return new UserAuthentication(getAuthMethod(), identity); + } + } + } + } + + if (DeferredAuthentication.isDeferred(res)) + return Authentication.UNAUTHENTICATED; + + if (LOG.isDebugEnabled()) + LOG.debug("Sending initial challenge"); + sendChallenge(req, res, callback, null); + return Authentication.SEND_CONTINUE; + } + + private void sendChallenge(Request req, Response res, Callback callback, String token) throws ServerAuthException + { + setSpnegoToken(res, token); + Response.writeError(req, res, callback, HttpStatus.UNAUTHORIZED_401); + } + + private void setSpnegoToken(Response response, String token) + { + String value = HttpHeader.NEGOTIATE.asString(); + if (token != null) + value += " " + token; + response.getHeaders().put(HttpHeader.WWW_AUTHENTICATE.asString(), value); + } + + private String getSpnegoToken(String header) + { + if (header == null) + return null; + String scheme = HttpHeader.NEGOTIATE.asString() + " "; + if (header.regionMatches(true, 0, scheme, 0, scheme.length())) + return header.substring(scheme.length()).trim(); + return null; + } + + @Override + public boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) + { + return true; + } + + private static class UserIdentityHolder implements Serializable + { + private static final String ATTRIBUTE = UserIdentityHolder.class.getName(); + + private final transient Instant _validFrom = Instant.now(); + private final transient UserIdentity _userIdentity; + + private UserIdentityHolder(UserIdentity userIdentity) + { + _userIdentity = userIdentity; + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java new file mode 100644 index 000000000000..8dcae87f8113 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -0,0 +1,205 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.nio.ByteBuffer; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +import org.eclipse.jetty.http.HttpFields; +import org.eclipse.jetty.http.HttpFields.Mutable; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoggedOutAuthentication; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DeferredAuthentication implements Authentication.Deferred +{ + private static final Logger LOG = LoggerFactory.getLogger(DeferredAuthentication.class); + protected final LoginAuthenticator _authenticator; + private Object _previousAssociation; + + public DeferredAuthentication(LoginAuthenticator authenticator) + { + if (authenticator == null) + throw new NullPointerException("No Authenticator"); + this._authenticator = authenticator; + } + + @Override + public Authentication authenticate(Request request) + { + try + { + Authentication authentication = _authenticator.validateRequest(request, __deferredResponse, null, true); + if (authentication != null && (authentication instanceof Authentication.User) && !(authentication instanceof Authentication.ResponseSent)) + { + LoginService loginService = _authenticator.getLoginService(); + IdentityService identityService = loginService.getIdentityService(); + + if (identityService != null) + _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + + return authentication; + } + } + catch (ServerAuthException e) + { + LOG.debug("Unable to authenticate {}", request, e); + } + + return this; + } + + @Override + public Authentication authenticate(Request request, Response response, Callback callback) + { + try + { + LoginService loginService = _authenticator.getLoginService(); + IdentityService identityService = loginService.getIdentityService(); + + Authentication authentication = _authenticator.validateRequest(request, response, callback, true); + if (authentication instanceof Authentication.User && identityService != null) + _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + return authentication; + } + catch (ServerAuthException e) + { + LOG.debug("Unable to authenticate {}", request, e); + } + return this; + } + + @Override + public Authentication login(String username, Object password, Request request, Response response) + { + if (username == null) + return null; + + UserIdentity identity = _authenticator.login(username, password, request, response); + if (identity != null) + { + IdentityService identityService = _authenticator.getLoginService().getIdentityService(); + UserAuthentication authentication = new UserAuthentication("API", identity); + if (identityService != null) + _previousAssociation = identityService.associate(identity); + return authentication; + } + return null; + } + + @Override + public Authentication logout(Request request) + { + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + if (security != null) + { + security.logout(null); + _authenticator.logout(request); + return new LoggedOutAuthentication(_authenticator); + } + + return Authentication.UNAUTHENTICATED; + } + + public Object getPreviousAssociation() + { + return _previousAssociation; + } + + /** + * @param response the response + * @return true if this response is from a deferred call to {@link #authenticate(Request)} + */ + public static boolean isDeferred(Response response) + { + return response == __deferredResponse; + } + + private static final Response __deferredResponse = new Response() + { + @Override + public Request getRequest() + { + return null; + } + + @Override + public int getStatus() + { + return 0; + } + + @Override + public void setStatus(int code) + { + } + + @Override + public Mutable getHeaders() + { + return null; + } + + @Override + public Supplier getTrailersSupplier() + { + return null; + } + + @Override + public void setTrailersSupplier(Supplier trailers) + { + } + + @Override + public void write(boolean last, ByteBuffer content, Callback callback) + { + callback.succeeded(); + } + + @Override + public boolean isCommitted() + { + return false; + } + + @Override + public boolean isCompletedSuccessfully() + { + return false; + } + + @Override + public void reset() + { + } + + @Override + public CompletableFuture writeInterim(int status, HttpFields headers) + { + return null; + } + }; +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java new file mode 100644 index 000000000000..79ee6a5aa494 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -0,0 +1,383 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.SecureRandom; +import java.util.Base64; +import java.util.BitSet; +import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentMap; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.QuotedStringTokenizer; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.security.Credential; +import org.eclipse.jetty.util.thread.AutoLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} + * using the name "maxNonceAge". The nonce max count can be set with {@link SecurityHandler#setInitParameter(String, String)} + * using the name "maxNonceCount". When the age or count is exceeded, the nonce is considered stale. + */ +public class DigestAuthenticator extends LoginAuthenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(DigestAuthenticator.class); + + private final SecureRandom _random = new SecureRandom(); + private long _maxNonceAgeMs = 60 * 1000; + private int _maxNC = 1024; + private ConcurrentMap _nonceMap = new ConcurrentHashMap<>(); + private Queue _nonceQueue = new ConcurrentLinkedQueue<>(); + + @Override + public void setConfiguration(AuthConfiguration configuration) + { + super.setConfiguration(configuration); + + String mna = configuration.getInitParameter("maxNonceAge"); + if (mna != null) + setMaxNonceAge(Long.parseLong(mna)); + String mnc = configuration.getInitParameter("maxNonceCount"); + if (mnc != null) + setMaxNonceCount(Integer.parseInt(mnc)); + } + + public int getMaxNonceCount() + { + return _maxNC; + } + + public void setMaxNonceCount(int maxNC) + { + _maxNC = maxNC; + } + + public long getMaxNonceAge() + { + return _maxNonceAgeMs; + } + + public void setMaxNonceAge(long maxNonceAgeInMillis) + { + _maxNonceAgeMs = maxNonceAgeInMillis; + } + + @Override + public String getAuthMethod() + { + return Constraint.__DIGEST_AUTH; + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + if (!mandatory) + return new DeferredAuthentication(this); + + String credentials = req.getHeaders().get(HttpHeader.AUTHORIZATION); + + boolean stale = false; + if (credentials != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("Credentials: {}", credentials); + QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(credentials, "=, ", true, false); + final Digest digest = new Digest(req.getMethod()); + String last = null; + String name = null; + + while (tokenizer.hasMoreTokens()) + { + String tok = tokenizer.nextToken(); + char c = (tok.length() == 1) ? tok.charAt(0) : '\0'; + + switch (c) + { + case '=': + name = last; + last = tok; + break; + case ',': + name = null; + break; + case ' ': + break; + + default: + last = tok; + if (name != null) + { + if ("username".equalsIgnoreCase(name)) + digest.username = tok; + else if ("realm".equalsIgnoreCase(name)) + digest.realm = tok; + else if ("nonce".equalsIgnoreCase(name)) + digest.nonce = tok; + else if ("nc".equalsIgnoreCase(name)) + digest.nc = tok; + else if ("cnonce".equalsIgnoreCase(name)) + digest.cnonce = tok; + else if ("qop".equalsIgnoreCase(name)) + digest.qop = tok; + else if ("uri".equalsIgnoreCase(name)) + digest.uri = tok; + else if ("response".equalsIgnoreCase(name)) + digest.response = tok; + name = null; + } + } + } + + int n = checkNonce(digest, req); + + if (n > 0) + { + //UserIdentity user = _loginService.login(digest.username,digest); + UserIdentity user = login(digest.username, digest, req, res); + if (user != null) + { + return new UserAuthentication(getAuthMethod(), user); + } + } + else if (n == 0) + stale = true; + } + + if (!DeferredAuthentication.isDeferred(res)) + { + String domain = req.getContext().getContextPath(); + if (domain == null) + domain = "/"; + res.getHeaders().put(HttpHeader.WWW_AUTHENTICATE.asString(), "Digest realm=\"" + _loginService.getName() + + "\", domain=\"" + domain + + "\", nonce=\"" + newNonce(req) + + "\", algorithm=MD5" + + ", qop=\"auth\"" + + ", stale=" + stale); + Response.writeError(req, res, callback, HttpStatus.UNAUTHORIZED_401); + + return Authentication.SEND_CONTINUE; + } + + return Authentication.UNAUTHENTICATED; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request, Response response) + { + Digest digest = (Digest)credentials; + if (!Objects.equals(digest.realm, _loginService.getName())) + return null; + return super.login(username, credentials, request, response); + } + + public String newNonce(Request request) + { + Nonce nonce; + + do + { + byte[] nounce = new byte[24]; + _random.nextBytes(nounce); + + nonce = new Nonce(Base64.getEncoder().encodeToString(nounce), request.getTimeStamp(), getMaxNonceCount()); + } + while (_nonceMap.putIfAbsent(nonce._nonce, nonce) != null); + _nonceQueue.add(nonce); + + return nonce._nonce; + } + + /** + * @param digest the digest data to check + * @param request the request object + * @return -1 for a bad nonce, 0 for a stale none, 1 for a good nonce + */ + private int checkNonce(Digest digest, Request request) + { + // firstly let's expire old nonces + long expired = request.getTimeStamp() - getMaxNonceAge(); + Nonce nonce = _nonceQueue.peek(); + while (nonce != null && nonce._ts < expired) + { + _nonceQueue.remove(nonce); + _nonceMap.remove(nonce._nonce); + nonce = _nonceQueue.peek(); + } + + // Now check the requested nonce + try + { + nonce = _nonceMap.get(digest.nonce); + if (nonce == null) + return 0; + + long count = Long.parseLong(digest.nc, 16); + if (count >= _maxNC) + return 0; + + if (nonce.seen((int)count)) + return -1; + + return 1; + } + catch (Exception e) + { + LOG.trace("IGNORED", e); + } + return -1; + } + + private static class Nonce + { + private final AutoLock _lock = new AutoLock(); + final String _nonce; + final long _ts; + final BitSet _seen; + + public Nonce(String nonce, long ts, int size) + { + _nonce = nonce; + _ts = ts; + _seen = new BitSet(size); + } + + public boolean seen(int count) + { + try (AutoLock l = _lock.lock()) + { + if (count >= _seen.size()) + return true; + boolean s = _seen.get(count); + _seen.set(count); + return s; + } + } + } + + private static class Digest extends Credential + { + private static final long serialVersionUID = -2484639019549527724L; + final String method; + String username = ""; + String realm = ""; + String nonce = ""; + String nc = ""; + String cnonce = ""; + String qop = ""; + String uri = ""; + String response = ""; + + Digest(String m) + { + method = m; + } + + @Override + public boolean check(Object credentials) + { + if (credentials instanceof char[]) + credentials = new String((char[])credentials); + String password = (credentials instanceof String) ? (String)credentials : credentials.toString(); + + try + { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] ha1; + if (credentials instanceof MD5) + { + // Credentials are already a MD5 digest - assume it's in + // form user:realm:password (we have no way to know since + // it's a digest, alright?) + ha1 = ((MD5)credentials).getDigest(); + } + else + { + // calc A1 digest + md.update(username.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(realm.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(password.getBytes(StandardCharsets.ISO_8859_1)); + ha1 = md.digest(); + } + // calc A2 digest + md.reset(); + md.update(method.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(uri.getBytes(StandardCharsets.ISO_8859_1)); + byte[] ha2 = md.digest(); + + // calc digest + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" + // nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" H(A2) ) + // <"> + // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) + // ) > <"> + + md.update(TypeUtil.toString(ha1, 16).getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(nonce.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(nc.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(cnonce.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(qop.getBytes(StandardCharsets.ISO_8859_1)); + md.update((byte)':'); + md.update(TypeUtil.toString(ha2, 16).getBytes(StandardCharsets.ISO_8859_1)); + byte[] digest = md.digest(); + + // check digest + return stringEquals(TypeUtil.toString(digest, 16).toLowerCase(), response == null ? null : response.toLowerCase()); + } + catch (Exception e) + { + LOG.warn("Unable to process digest", e); + } + + return false; + } + + @Override + public String toString() + { + return username + "," + response; + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java new file mode 100644 index 000000000000..8ca147dcc454 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -0,0 +1,611 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Session; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Fields; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * FORM Authenticator. + * + *

This authenticator implements form authentication will use dispatchers to + * the login page if the {@link #__FORM_DISPATCH} init parameter is set to true. + * Otherwise it will redirect.

+ * + *

The form authenticator redirects unauthenticated requests to a log page + * which should use a form to gather username/password from the user and send them + * to the /j_security_check URI within the context. FormAuthentication uses + * {@link SessionAuthentication} to wrap Authentication results so that they + * are associated with the session.

+ */ +public class FormAuthenticator extends LoginAuthenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(FormAuthenticator.class); + + public static final String __FORM_LOGIN_PAGE = "org.eclipse.jetty.security.form_login_page"; + public static final String __FORM_ERROR_PAGE = "org.eclipse.jetty.security.form_error_page"; + public static final String __FORM_DISPATCH = "org.eclipse.jetty.security.dispatch"; + public static final String __J_URI = "org.eclipse.jetty.security.form_URI"; + public static final String __J_POST = "org.eclipse.jetty.security.form_POST"; + public static final String __J_METHOD = "org.eclipse.jetty.security.form_METHOD"; + public static final String __J_SECURITY_CHECK = "/j_security_check"; + public static final String __J_USERNAME = "j_username"; + public static final String __J_PASSWORD = "j_password"; + + private String _formErrorPage; + private String _formErrorPath; + private String _formLoginPage; + private String _formLoginPath; + private boolean _dispatch; + private boolean _alwaysSaveUri; + + public FormAuthenticator() + { + } + + public FormAuthenticator(String login, String error, boolean dispatch) + { + this(); + if (login != null) + setLoginPage(login); + if (error != null) + setErrorPage(error); + _dispatch = dispatch; + } + + /** + * If true, uris that cause a redirect to a login page will always + * be remembered. If false, only the first uri that leads to a login + * page redirect is remembered. + * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=379909 + * + * @param alwaysSave true to always save the uri + */ + public void setAlwaysSaveUri(boolean alwaysSave) + { + _alwaysSaveUri = alwaysSave; + } + + public boolean getAlwaysSaveUri() + { + return _alwaysSaveUri; + } + + @Override + public void setConfiguration(AuthConfiguration configuration) + { + super.setConfiguration(configuration); + String login = configuration.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE); + if (login != null) + setLoginPage(login); + String error = configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE); + if (error != null) + setErrorPage(error); + String dispatch = configuration.getInitParameter(FormAuthenticator.__FORM_DISPATCH); + _dispatch = dispatch == null ? _dispatch : Boolean.parseBoolean(dispatch); + } + + @Override + public String getAuthMethod() + { + return Constraint.__FORM_AUTH; + } + + private void setLoginPage(String path) + { + if (!path.startsWith("/")) + { + LOG.warn("form-login-page must start with /"); + path = "/" + path; + } + _formLoginPage = path; + _formLoginPath = path; + if (_formLoginPath.indexOf('?') > 0) + _formLoginPath = _formLoginPath.substring(0, _formLoginPath.indexOf('?')); + } + + private void setErrorPage(String path) + { + if (path == null || path.trim().length() == 0) + { + _formErrorPath = null; + _formErrorPage = null; + } + else + { + if (!path.startsWith("/")) + { + LOG.warn("form-error-page must start with /"); + path = "/" + path; + } + _formErrorPage = path; + _formErrorPath = path; + + if (_formErrorPath.indexOf('?') > 0) + _formErrorPath = _formErrorPath.substring(0, _formErrorPath.indexOf('?')); + } + } + + @Override + public UserIdentity login(String username, Object password, Request request, Response response) + { + UserIdentity user = super.login(username, password, request, response); + if (user != null) + { + Session session = request.getSession(true); + Authentication cached = new SessionAuthentication(getAuthMethod(), user, password); + session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, cached); + } + return user; + } + + @Override + public void logout(Request request) + { + super.logout(request); + Session session = request.getSession(false); + if (session == null) + return; + + //clean up session + session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + } + + @Override + public void prepareRequest(Request request) + { + //if this is a request resulting from a redirect after auth is complete + //(ie its from a redirect to the original request uri) then due to + //browser handling of 302 redirects, the method may not be the same as + //that of the original request. Replace the method and original post + //params (if it was a post). + // + //See Servlet Spec 3.1 sec 13.6.3 + Session session = request.getSession(false); + if (session == null || session.getAttribute(SessionAuthentication.__J_AUTHENTICATED) == null) + return; //not authenticated yet + + HttpURI juri = (HttpURI)session.getAttribute(__J_URI); + if (juri == null) + return; //no original uri saved + + String method = (String)session.getAttribute(__J_METHOD); + if (method == null || method.length() == 0) + return; //didn't save original request method + + if (!juri.equals(request.getHttpURI())) + return; //this request is not for the same url as the original + + //restore the original request's method on this request + if (LOG.isDebugEnabled()) + LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); + + // TODO: Set method. + // servletContextRequest.getServletApiRequest().setMethod(method); + } + + protected Fields getParameters(Request request) + { + // TODO: Content parameters? + // TODO: override for servlet so we don't lose content parameters when we read them? + return Request.extractQueryParameters(request); + } + + protected String encodeURL(String url) + { + SessionManager sessionManager = _response.getServletContextRequest().getServletChannel().getContextHandler().getSessionHandler(); + if (sessionManager == null) + return url; + + HttpURI uri = null; + if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) + { + uri = HttpURI.from(url); + String path = uri.getPath(); + path = (path == null ? "" : path); + int port = uri.getPort(); + if (port < 0) + port = HttpScheme.getDefaultPort(uri.getScheme()); + + // Is it the same server? + if (!Request.getServerName(request).equalsIgnoreCase(uri.getHost())) + return url; + if (Request.getServerPort(request) != port) + return url; + if (request.getContext() != null && !path.startsWith(request.getContext().getContextPath())) + return url; + } + + String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix(); + if (sessionURLPrefix == null) + return url; + + if (url == null) + return null; + + // should not encode if cookies in evidence + if ((sessionManager.isUsingCookies() && httpServletRequest.isRequestedSessionIdFromCookie()) || !sessionManager.isUsingURLs()) + { + int prefix = url.indexOf(sessionURLPrefix); + if (prefix != -1) + { + int suffix = url.indexOf("?", prefix); + if (suffix < 0) + suffix = url.indexOf("#", prefix); + + if (suffix <= prefix) + return url.substring(0, prefix); + return url.substring(0, prefix) + url.substring(suffix); + } + return url; + } + + // get session; + Session session = request.getSession(false); + + // no session + if (session == null || !(session instanceof Session.API)) + return url; + + // invalid session + Session.API api = (Session.API)session; + + if (!api.getSession().isValid()) + return url; + + String id = api.getSession().getExtendedId(); + + if (uri == null) + uri = HttpURI.from(url); + + // Already encoded + int prefix = url.indexOf(sessionURLPrefix); + if (prefix != -1) + { + int suffix = url.indexOf("?", prefix); + if (suffix < 0) + suffix = url.indexOf("#", prefix); + + if (suffix <= prefix) + return url.substring(0, prefix + sessionURLPrefix.length()) + id; + return url.substring(0, prefix + sessionURLPrefix.length()) + id + + url.substring(suffix); + } + + // edit the session + int suffix = url.indexOf('?'); + if (suffix < 0) + suffix = url.indexOf('#'); + if (suffix < 0) + { + return url + + ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + //if no path, insert the root path + sessionURLPrefix + id; + } + + return url.substring(0, suffix) + + ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + //if no path so insert the root path + sessionURLPrefix + id + url.substring(suffix); + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + String pathInContext = Request.getPathInContext(req); + boolean jSecurityCheck = isJSecurityCheck(pathInContext); + mandatory |= jSecurityCheck; + if (!mandatory) + return new DeferredAuthentication(this); + + if (isLoginOrErrorPage(pathInContext) && !DeferredAuthentication.isDeferred(res)) + return new DeferredAuthentication(this); + + // Handle a request for authentication. + if (jSecurityCheck) + { + Fields parameters = getParameters(req); + final String username = parameters.getValue(__J_USERNAME); + final String password = parameters.getValue(__J_PASSWORD); + + UserIdentity user = login(username, password, req, res); + LOG.debug("jsecuritycheck {} {}", username, user); + Session session = req.getSession(false); + if (user != null) + { + // Redirect to original request + String nuri; + FormAuthentication formAuth; + synchronized (session) + { + HttpURI savedURI = (HttpURI)session.getAttribute(__J_URI); + if (savedURI == null) + { + nuri = Request.getContextPath(req); + if (nuri.length() == 0) + nuri = "/"; + } + else + nuri = savedURI.asString(); + formAuth = new FormAuthentication(getAuthMethod(), user); + } + LOG.debug("authenticated {}->{}", formAuth, nuri); + + res.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); + //TODO yuck - should use Response the whole way + Response.sendRedirect(req, res, callback, encodeURL(nuri)); + return formAuth; + } + + // not authenticated + if (LOG.isDebugEnabled()) + LOG.debug("Form authentication FAILED for {}", StringUtil.printable(username)); + if (_formErrorPage == null) + { + LOG.debug("auth failed {}->403", username); + Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); + } + //TODO need to reinstate forward + /* else if (_dispatch) + { + LOG.debug("auth failed {}=={}", username, _formErrorPage); + RequestDispatcher dispatcher = servletApiRequest.getRequestDispatcher(_formErrorPage); + res.setHeader(HttpHeader.CACHE_CONTROL.asString(), HttpHeaderValue.NO_CACHE.asString()); + res.getHeaders().addDateField(HttpHeader.EXPIRES.asString(), 1); + dispatcher.forward(new FormRequest(req), new FormResponse(res)); + }*/ + else + { + LOG.debug("auth failed {}->{}", username, _formErrorPage); + Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formErrorPage))); + } + + return Authentication.SEND_FAILURE; + } + + // Look for cached authentication + Session session = req.getSession(false); + Authentication authentication = session == null ? null : (Authentication)session.getAttribute(SessionAuthentication.__J_AUTHENTICATED); + if (authentication != null) + { + // Has authentication been revoked? + if (authentication instanceof User && + _loginService != null && + !_loginService.validate(((User)authentication).getUserIdentity())) + { + LOG.debug("auth revoked {}", authentication); + session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + } + else + { + synchronized (session) + { + HttpURI jUri = (HttpURI)session.getAttribute(__J_URI); + if (jUri != null) + { + //check if the request is for the same url as the original and restore + //params if it was a post + LOG.debug("auth retry {}->{}", authentication, jUri); + + if (jUri.equals(req.getHttpURI())) + { + Fields jPost = (Fields)session.getAttribute(__J_POST); + if (jPost != null) + { + // TODO: how to do this + LOG.debug("auth rePOST {}->{}", authentication, jUri); + // servletApiRequest.setContentParameters(jPost); + } + session.removeAttribute(__J_URI); + session.removeAttribute(__J_METHOD); + session.removeAttribute(__J_POST); + } + } + } + LOG.debug("auth {}", authentication); + return authentication; + } + } + + // if we can't send challenge + if (DeferredAuthentication.isDeferred(res)) + { + LOG.debug("auth deferred {}", session == null ? null : session.getId()); + return Authentication.UNAUTHENTICATED; + } + + // remember the current URI + session = (session != null ? session : req.getSession(true)); + synchronized (session) + { + // But only if it is not set already, or we save every uri that leads to a login form redirect + if (session.getAttribute(__J_URI) == null || _alwaysSaveUri) + { + session.setAttribute(__J_URI, req.getHttpURI()); + session.setAttribute(__J_METHOD, req.getMethod()); + + if (MimeTypes.Type.FORM_ENCODED.is(req.getContentType()) && HttpMethod.POST.is(req.getMethod())) + { + session.setAttribute(__J_POST, servletApiRequest.getContentParameters()); + } + } + } + + // send the the challenge + //TODO reinstate use of dispatch + /* if (_dispatch) + { + LOG.debug("challenge {}=={}", session.getId(), _formLoginPage); + RequestDispatcher dispatcher = servletApiRequest.getRequestDispatcher(_formLoginPage); + res.setHeader(HttpHeader.CACHE_CONTROL.asString(), HttpHeaderValue.NO_CACHE.asString()); + res.setDateHeader(HttpHeader.EXPIRES.asString(), 1); + dispatcher.forward(new FormRequest(req), new FormResponse(res)); + } + else + {*/ + LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); + Response.sendRedirect(req, res, callback, servletContextRequest.getHttpServletResponse().encodeRedirectURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); + //} + return Authentication.SEND_CONTINUE; + } + + public boolean isJSecurityCheck(String uri) + { + int jsc = uri.indexOf(__J_SECURITY_CHECK); + + if (jsc < 0) + return false; + int e = jsc + __J_SECURITY_CHECK.length(); + if (e == uri.length()) + return true; + char c = uri.charAt(e); + return c == ';' || c == '#' || c == '/' || c == '?'; + } + + public boolean isLoginOrErrorPage(String pathInContext) + { + return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath)); + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } + + //TODO reinstate use of forward dispatch + /* + protected static class FormRequest extends HttpServletRequestWrapper + { + public FormRequest(HttpServletRequest request) + { + super(request); + } + + @Override + public long getDateHeader(String name) + { + if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) + return -1; + return super.getDateHeader(name); + } + + @Override + public String getHeader(String name) + { + if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) + return null; + return super.getHeader(name); + } + + @Override + public Enumeration getHeaderNames() + { + return Collections.enumeration(Collections.list(super.getHeaderNames())); + } + + @Override + public Enumeration getHeaders(String name) + { + if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) + return Collections.enumeration(Collections.emptyList()); + return super.getHeaders(name); + } + } + + protected static class FormResponse extends HttpServletResponseWrapper + { + public FormResponse(HttpServletResponse response) + { + super(response); + } + + @Override + public void addDateHeader(String name, long date) + { + if (notIgnored(name)) + super.addDateHeader(name, date); + } + + @Override + public void addHeader(String name, String value) + { + if (notIgnored(name)) + super.addHeader(name, value); + } + + @Override + public void setDateHeader(String name, long date) + { + if (notIgnored(name)) + super.setDateHeader(name, date); + } + + @Override + public void setHeader(String name, String value) + { + if (notIgnored(name)) + super.setHeader(name, value); + } + + private boolean notIgnored(String name) + { + if (HttpHeader.CACHE_CONTROL.is(name) || + HttpHeader.PRAGMA.is(name) || + HttpHeader.ETAG.is(name) || + HttpHeader.EXPIRES.is(name) || + HttpHeader.LAST_MODIFIED.is(name) || + HttpHeader.AGE.is(name)) + return false; + return true; + } + }*/ + + /** + * This Authentication represents a just completed Form authentication. + * Subsequent requests from the same user are authenticated by the presence + * of a {@link SessionAuthentication} instance in their session. + */ + public static class FormAuthentication extends UserAuthentication implements Authentication.ResponseSent + { + public FormAuthentication(String method, UserIdentity userIdentity) + { + super(method, userIdentity); + } + + @Override + public String toString() + { + return "Form" + super.toString(); + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java new file mode 100644 index 000000000000..ebc3cebdf7e6 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -0,0 +1,121 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Session; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class LoginAuthenticator implements Authenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(LoginAuthenticator.class); + + protected LoginService _loginService; + protected IdentityService _identityService; + private boolean _renewSession; + + protected LoginAuthenticator() + { + } + + @Override + public void prepareRequest(Request request) + { + //empty implementation as the default + } + + /** + * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, Request)}, it + * is assumed that the user is fully authenticated and we need to change the session id to prevent + * session fixation vulnerability. If the UserIdentity is not necessarily fully + * authenticated, then subclasses must override this method and + * determine when the UserIdentity IS fully authenticated and renew the session id. + * + * @param username the username of the client to be authenticated + * @param password the user's credential + * @param request the inbound request that needs authentication + */ + public UserIdentity login(String username, Object password, Request request, Response response) + { + UserIdentity user = _loginService.login(username, password, request); + if (user != null) + { + renewSession(request, response); + return user; + } + return null; + } + + public void logout(Request request) + { + if (session == null) + return; + session.removeAttribute(ManagedSession.SESSION_CREATED_SECURE); + } + + @Override + public void setConfiguration(AuthConfiguration configuration) + { + _loginService = configuration.getLoginService(); + if (_loginService == null) + throw new IllegalStateException("No LoginService for " + this + " in " + configuration); + _identityService = configuration.getIdentityService(); + if (_identityService == null) + throw new IllegalStateException("No IdentityService for " + this + " in " + configuration); + _renewSession = configuration.isSessionRenewedOnAuthentication(); + } + + public LoginService getLoginService() + { + return _loginService; + } + + /** + * Change the session id. + * The session is changed to a new instance with a new ID if and only if:
    + *
  • A session exists. + *
  • The {@link Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication()} returns true. + *
  • The session ID has been given to unauthenticated responses + *
+ * + * @param httpRequest the request + * @param httpResponse the response + * @return The new session. + */ + protected Session renewSession(Request httpRequest, Response httpResponse) + { + Session session = httpRequest.getSession(false); + if (_renewSession && session != null) + { + synchronized (session) + { + //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users + //(indicated by SESSION_SECURED not being set on the session) then we should change id + if (session.getAttribute(ManagedSession.SESSION_CREATED_SECURE) != Boolean.TRUE) + { + session.setAttribute(ManagedSession.SESSION_CREATED_SECURE, Boolean.TRUE); + session.renewId(httpRequest, httpResponse); + return session; + } + } + } + return session; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java new file mode 100644 index 000000000000..fc30dbf88170 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.security.Principal; +import javax.security.auth.Subject; + +/** + * This is similar to the jaspi PasswordValidationCallback but includes user + * principal and group info as well. + * + * @version $Rev: 4792 $ $Date: 2009-03-18 22:55:52 +0100 (Wed, 18 Mar 2009) $ + */ +public interface LoginCallback +{ + public Subject getSubject(); + + public String getUserName(); + + public Object getCredential(); + + public boolean isSuccess(); + + public void setSuccess(boolean success); + + public Principal getUserPrincipal(); + + public void setUserPrincipal(Principal userPrincipal); + + public String[] getRoles(); + + public void setRoles(String[] roles); + + public void clearPassword(); +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java new file mode 100644 index 000000000000..1c5813fe1e87 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java @@ -0,0 +1,112 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.security.Principal; +import javax.security.auth.Subject; + +import org.eclipse.jetty.security.IdentityService; + +/** + * This is similar to the jaspi PasswordValidationCallback but includes user + * principal and group info as well. + * + * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ + */ +public class LoginCallbackImpl implements LoginCallback +{ + // initial data + private final Subject subject; + + private final String userName; + + private Object credential; + + private boolean success; + + private Principal userPrincipal; + + private String[] roles = IdentityService.NO_ROLES; + + //TODO could use Credential instance instead of Object if Basic/Form create a Password object + public LoginCallbackImpl(Subject subject, String userName, Object credential) + { + this.subject = subject; + this.userName = userName; + this.credential = credential; + } + + @Override + public Subject getSubject() + { + return subject; + } + + @Override + public String getUserName() + { + return userName; + } + + @Override + public Object getCredential() + { + return credential; + } + + @Override + public boolean isSuccess() + { + return success; + } + + @Override + public void setSuccess(boolean success) + { + this.success = success; + } + + @Override + public Principal getUserPrincipal() + { + return userPrincipal; + } + + @Override + public void setUserPrincipal(Principal userPrincipal) + { + this.userPrincipal = userPrincipal; + } + + @Override + public String[] getRoles() + { + return roles; + } + + @Override + public void setRoles(String[] groups) + { + this.roles = groups; + } + + @Override + public void clearPassword() + { + if (credential != null) + { + credential = null; + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java new file mode 100644 index 000000000000..44e239527f3c --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -0,0 +1,113 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; + +import org.eclipse.jetty.security.AbstractUserAuthentication; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.UserIdentity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * SessionAuthentication + * + * When a user has been successfully authenticated with some types + * of Authenticator, the Authenticator stashes a SessionAuthentication + * into an HttpSession to remember that the user is authenticated. + */ +public class SessionAuthentication extends AbstractUserAuthentication + implements Serializable, HttpSessionActivationListener, HttpSessionBindingListener +{ + private static final Logger LOG = LoggerFactory.getLogger(SessionAuthentication.class); + + private static final long serialVersionUID = -4643200685888258706L; + + public static final String __J_AUTHENTICATED = "org.eclipse.jetty.security.UserIdentity"; + + private final String _name; + private final Object _credentials; + private transient HttpSession _session; + + public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials) + { + super(method, userIdentity); + _name = userIdentity.getUserPrincipal().getName(); + _credentials = credentials; + } + + @Override + public UserIdentity getUserIdentity() + { + if (_userIdentity == null) + throw new IllegalStateException("!UserIdentity"); + return super.getUserIdentity(); + } + + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException + { + stream.defaultReadObject(); + + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + if (security == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("!SecurityHandler"); + return; + } + + LoginService loginService; + Authenticator authenticator = security.getAuthenticator(); + if (authenticator instanceof LoginAuthenticator) + loginService = ((LoginAuthenticator)authenticator).getLoginService(); + else + loginService = security.getLoginService(); + + if (loginService == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("!LoginService"); + return; + } + + _userIdentity = loginService.login(_name, _credentials, null); + LOG.debug("Deserialized and relogged in {}", this); + } + + @Override + public String toString() + { + return String.format("%s@%x{%s,%s}", this.getClass().getSimpleName(), hashCode(), _session == null ? "-" : _session.getId(), _userIdentity); + } + + @Override + public void sessionWillPassivate(HttpSessionEvent se) + { + } + + @Override + public void sessionDidActivate(HttpSessionEvent se) + { + if (_session == null) + { + _session = se.getSession(); + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java new file mode 100644 index 000000000000..15f238884900 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -0,0 +1,153 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.authentication; + +import java.security.Principal; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Objects; + +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.SecureRequestCustomizer; +import org.eclipse.jetty.server.SecureRequestCustomizer.SslSessionData; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.util.ssl.SslContextFactory; + +/** + * CLIENT-CERT authenticator. + * + *

This {@link Authenticator} implements client certificate authentication. + * The client certificates available in the request will be verified against the configured {@link SslContextFactory} instance + *

+ */ +public class SslClientCertAuthenticator extends LoginAuthenticator +{ + private final SslContextFactory sslContextFactory; + private boolean validateCerts = true; + + public SslClientCertAuthenticator(SslContextFactory sslContextFactory) + { + this.sslContextFactory = Objects.requireNonNull(sslContextFactory); + } + + @Override + public String getAuthMethod() + { + return Constraint.__CERT_AUTH; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + { + if (!mandatory) + return new DeferredAuthentication(this); + + //TODO this seems fragile, to rely on this name + //X509Certificate[] certs = (X509Certificate[])req.getAttribute("jakarta.servlet.request.X509Certificate"); + SslSessionData sslSessionData = (SslSessionData)req.getAttribute(SecureRequestCustomizer.DEFAULT_SSL_SESSION_DATA_ATTRIBUTE); + if (sslSessionData == null) + { + Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); + return Authentication.SEND_FAILURE; + } + + X509Certificate[] certs = sslSessionData.peerCertificates(); + + try + { + // Need certificates. + if (certs != null && certs.length > 0) + { + + if (validateCerts) + { + sslContextFactory.validateCerts(certs); + } + + for (X509Certificate cert : certs) + { + if (cert == null) + continue; + + Principal principal = cert.getSubjectDN(); + if (principal == null) + principal = cert.getIssuerDN(); + final String username = principal == null ? "clientcert" : principal.getName(); + + UserIdentity user = login(username, "", req, res); + if (user != null) + { + return new UserAuthentication(getAuthMethod(), user); + } + // try with null password + user = login(username, null, req, res); + if (user != null) + { + return new UserAuthentication(getAuthMethod(), user); + } + // try with certs sig against login service as previous behaviour + final char[] credential = Base64.getEncoder().encodeToString(cert.getSignature()).toCharArray(); + user = login(username, credential, req, res); + if (user != null) + { + return new UserAuthentication(getAuthMethod(), user); + } + } + } + + if (!DeferredAuthentication.isDeferred(res)) + { + Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); + return Authentication.SEND_FAILURE; + } + + return Authentication.UNAUTHENTICATED; + } + catch (Exception e) + { + throw new ServerAuthException(e.getMessage()); + } + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } + + /** + * @return true if SSL certificate has to be validated. + */ + public boolean isValidateCerts() + { + return validateCerts; + } + + /** + * @param validateCerts true if SSL certificates have to be validated. + */ + public void setValidateCerts(boolean validateCerts) + { + this.validateCerts = validateCerts; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java new file mode 100644 index 000000000000..5ceb5432bdaf --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java @@ -0,0 +1,18 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty Security : Authenticators and Callbacks + */ +package org.eclipse.jetty.security.authentication; + diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java new file mode 100644 index 000000000000..b940f0ce18bf --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java @@ -0,0 +1,18 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty Security : Modular Support for Security in Jetty + */ +package org.eclipse.jetty.security; + diff --git a/jetty-core/pom.xml b/jetty-core/pom.xml index 5627d386b63f..19b04fbddb5a 100644 --- a/jetty-core/pom.xml +++ b/jetty-core/pom.xml @@ -34,6 +34,7 @@ jetty-rewrite jetty-server jetty-session + jetty-security jetty-slf4j-impl jetty-start jetty-tests From ab4b3b89353b2c1af5a2f4aecf12cb6c5e2aabb3 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 22 Feb 2023 12:16:29 +1100 Subject: [PATCH 002/129] WIP --- jetty-core/jetty-security/pom.xml | 5 + .../src/main/java/module-info.java | 2 +- .../jetty/security/AbstractLoginService.java | 2 +- .../security/AbstractUserAuthentication.java | 2 +- .../jetty/security/Authentication.java | 39 +- .../eclipse/jetty/security/Authenticator.java | 11 +- .../ConfigurableSpnegoLoginService.java | 2 +- .../{RoleInfo.java => Constraint.java} | 123 ++- .../jetty/security/ConstraintAware.java | 2 +- .../jetty/security/ConstraintMapping.java | 2 +- .../security/ConstraintSecurityHandler.java | 878 ------------------ .../security/DefaultAuthenticatorFactory.java | 2 +- .../security/DefaultIdentityService.java | 2 +- .../jetty/security/DefaultUserIdentity.java | 2 +- .../jetty/security/EmptyLoginService.java | 2 +- .../jetty/security/HashLoginService.java | 2 +- .../jetty/security/IdentityService.java | 2 +- .../jetty/security/JDBCLoginService.java | 2 +- .../security/LoggedOutAuthentication.java | 5 +- .../eclipse/jetty/security/LoginService.java | 2 +- .../jetty/security/PropertyUserStore.java | 2 +- .../eclipse/jetty/security/RolePrincipal.java | 2 +- .../jetty/security/RoleRunAsToken.java | 2 +- .../eclipse/jetty/security/RunAsToken.java | 2 +- .../jetty/security/SecurityHandler.java | 282 +++--- .../jetty/security/ServerAuthException.java | 2 +- .../jetty/security/SpnegoUserIdentity.java | 2 +- .../jetty/security/SpnegoUserPrincipal.java | 2 +- .../jetty/security/UserAuthentication.java | 2 +- .../jetty/security/UserDataConstraint.java | 2 +- .../eclipse/jetty/security/UserIdentity.java | 2 +- .../eclipse/jetty/security/UserPrincipal.java | 2 +- .../org/eclipse/jetty/security/UserStore.java | 2 +- .../security/WrappedAuthConfiguration.java | 10 +- .../authentication/AuthorizationService.java | 2 +- .../authentication/BasicAuthenticator.java | 2 +- .../ClientCertAuthenticator.java | 2 +- .../ConfigurableSpnegoAuthenticator.java | 2 +- .../DeferredAuthentication.java | 2 +- .../authentication/DigestAuthenticator.java | 6 +- .../authentication/FormAuthenticator.java | 123 +-- .../authentication/LoginAuthenticator.java | 14 +- .../authentication/LoginCallback.java | 2 +- .../authentication/LoginCallbackImpl.java | 2 +- .../authentication/SessionAuthentication.java | 11 +- .../SslClientCertAuthenticator.java | 2 +- .../security/authentication/package-info.java | 2 +- .../eclipse/jetty/security/package-info.java | 2 +- .../security/DefaultIdentityServiceTest.java | 88 ++ .../jetty/security/HashLoginServiceTest.java | 85 ++ .../jetty/security/PropertyUserStoreTest.java | 334 +++++++ .../jetty/security/SecurityHandlerTest.java | 183 ++++ .../jetty/security/TestLoginService.java | 49 + .../eclipse/jetty/security/UserStoreTest.java | 56 ++ .../eclipse/jetty/session/ManagedSession.java | 1 + .../jetty/session/SimpleSessionHandler.java | 53 +- .../session/SimpleSessionHandlerTest.java | 10 +- 57 files changed, 1154 insertions(+), 1284 deletions(-) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{RoleInfo.java => Constraint.java} (54%) delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java rename jetty-core/jetty-session/src/{test => main}/java/org/eclipse/jetty/session/SimpleSessionHandler.java (78%) diff --git a/jetty-core/jetty-security/pom.xml b/jetty-core/jetty-security/pom.xml index fc4ffc2505df..836798298ec6 100644 --- a/jetty-core/jetty-security/pom.xml +++ b/jetty-core/jetty-security/pom.xml @@ -24,6 +24,11 @@ org.slf4j slf4j-api + + org.eclipse.jetty + jetty-session + test + org.eclipse.jetty.toolchain jetty-test-helper diff --git a/jetty-core/jetty-security/src/main/java/module-info.java b/jetty-core/jetty-security/src/main/java/module-info.java index 0584ca97a1a5..49226888cd7c 100644 --- a/jetty-core/jetty-security/src/main/java/module-info.java +++ b/jetty-core/jetty-security/src/main/java/module-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java index 0e60c3053e15..5a9649e5fb50 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index 4a0cca6f7667..dd85a7125163 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java index a2843c1b75ec..3e57f511826e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -28,6 +28,17 @@ */ public interface Authentication { + static Authentication getAuthentication(Request request) + { + Object auth = request.getAttribute(Authentication.class.getName()); + return auth instanceof Authentication authentication ? authentication : null; + } + + static void setAuthentication(Request request, Authentication authentication) + { + request.setAttribute(Authentication.class.getName(), authentication); + } + class Failed extends QuietException.Exception { public Failed(String message) @@ -52,7 +63,7 @@ interface User extends LogoutAuthentication * An authentication that is capable of performing a programmatic login * operation. */ - public interface LoginAuthentication extends Authentication + interface LoginAuthentication extends Authentication { /** @@ -70,7 +81,7 @@ public interface LoginAuthentication extends Authentication * An authentication that is capable of performing a programmatic * logout operation. */ - public interface LogoutAuthentication extends Authentication + interface LogoutAuthentication extends Authentication { /** @@ -87,7 +98,7 @@ public interface LogoutAuthentication extends Authentication * A deferred authentication with methods to progress * the authentication process. */ - public interface Deferred extends LoginAuthentication, LogoutAuthentication + interface Deferred extends LoginAuthentication, LogoutAuthentication { /** @@ -118,25 +129,25 @@ public interface Deferred extends LoginAuthentication, LogoutAuthentication * authentication challenge or on successful authentication in * order to redirect the user to the original URL. */ - public interface ResponseSent extends Authentication + interface ResponseSent extends Authentication { } /** * An Authentication Challenge has been sent. */ - public interface Challenge extends ResponseSent + interface Challenge extends ResponseSent { } /** * An Authentication Failure has been sent. */ - public interface Failure extends ResponseSent + interface Failure extends ResponseSent { } - public interface SendSuccess extends ResponseSent + interface SendSuccess extends ResponseSent { } @@ -144,7 +155,7 @@ public interface SendSuccess extends ResponseSent * After a logout, the authentication reverts to a state * where it is possible to programmatically log in again. */ - public interface NonAuthenticated extends LoginAuthentication + interface NonAuthenticated extends LoginAuthentication { } @@ -154,7 +165,7 @@ public interface NonAuthenticated extends LoginAuthentication * This convenience instance is for non mandatory authentication where credentials * have been presented and checked, but failed authentication. */ - public static final Authentication UNAUTHENTICATED = + Authentication UNAUTHENTICATED = new Authentication() { @Override @@ -170,7 +181,7 @@ public String toString() * This convenience instance us for non mandatory authentication when no * credentials are present to be checked. */ - public static final Authentication NOT_CHECKED = new Authentication() + Authentication NOT_CHECKED = new Authentication() { @Override public String toString() @@ -184,7 +195,7 @@ public String toString() *

* This convenience instance is for when an authentication challenge has been sent. */ - public static final Authentication SEND_CONTINUE = new Challenge() + Authentication SEND_CONTINUE = new Challenge() { @Override public String toString() @@ -198,7 +209,7 @@ public String toString() *

* This convenience instance is for when an authentication failure has been sent. */ - public static final Authentication SEND_FAILURE = new Failure() + Authentication SEND_FAILURE = new Failure() { @Override public String toString() @@ -206,7 +217,7 @@ public String toString() return "FAILURE"; } }; - public static final Authentication SEND_SUCCESS = new SendSuccess() + Authentication SEND_SUCCESS = new SendSuccess() { @Override public String toString() diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 11fb3fe3f746..f4643e10933c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -56,9 +56,10 @@ public interface Authenticator * where the http method of the original request causing authentication * is not the same as the http method resulting from the redirect * after authentication. + * * @param request the request to prepare for authentication */ - void prepareRequest(Request request); + Request prepareRequest(Request request); /** * Validate a request @@ -102,17 +103,15 @@ interface AuthConfiguration * * @param param parameter name * @return Parameter value or null - * @see SecurityHandler#getInitParameter(String) */ - String getInitParameter(String param); + String getParameter(String param); /** * Get a SecurityHandler init parameter names * * @return Set of parameter names - * @see SecurityHandler#getInitParameterNames() */ - Set getInitParameterNames(); + Set getParameterNames(); LoginService getLoginService(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java index 23daf2833150..1784c05ab1fd 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java similarity index 54% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 026b27319f5f..51a14ca847f3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleInfo.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -13,44 +13,108 @@ package org.eclipse.jetty.security; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +import java.util.Arrays; +import java.util.Collection; /** - * RoleInfo - * - * Badly named class that holds the role and user data constraint info for a - * path/http method combination, extracted and combined from security - * constraints. - * - * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ + * A Security Constraint interface. */ -public class RoleInfo +public interface Constraint +{ + boolean isForbidden(); + + boolean isAuthenticationMandatory(); + + UserDataConstraint getUserDataConstraint(); + + Authorization getAuthorization(); + + Collection getRoles(); + + enum Authorization + { + AUTHENTICATED, + AUTHENTICATED_IN_KNOWN_ROLE, + AUTHENTICATED_IN_ROLE, + } + + Constraint NONE = null; + Constraint INTEGRAL = from(false, true, UserDataConstraint.Integral, null); + Constraint CONFIDENTAL = from(false, true, UserDataConstraint.Confidential, null); + Constraint AUTHENTICATED = from(false, true, null, Authorization.AUTHENTICATED); + Constraint AUTHENTICATED_IN_KNOWN_ROLE = from(false, true, null, Authorization.AUTHENTICATED_IN_KNOWN_ROLE); + + static Constraint combine(Constraint... constraints) + { + // TODO + return null; + } + + static Constraint from(String... roles) + { + return from(false, true, null, Authorization.AUTHENTICATED_IN_ROLE, roles); + } + + static Constraint from(boolean forbidden, boolean authMandatory, UserDataConstraint userDataConstraint, Authorization authorization, String... roles) + { + return new Constraint() + { + @Override + public boolean isForbidden() + { + return forbidden; + } + + @Override + public boolean isAuthenticationMandatory() + { + return authMandatory; + } + + @Override + public UserDataConstraint getUserDataConstraint() + { + return userDataConstraint; + } + + @Override + public Authorization getAuthorization() + { + return authorization; + } + + @Override + public Collection getRoles() + { + return Arrays.asList(roles); + } + }; + } +} + +/* { private boolean _isAnyAuth; private boolean _isAnyRole; - private boolean _checked; + private boolean _mandatory; private boolean _forbidden; private UserDataConstraint _userDataConstraint; - /** - * List of permitted roles - */ private final Set _roles = new CopyOnWriteArraySet<>(); - public RoleInfo() + public Constraint() { } - public boolean isChecked() + public boolean isMandatory() { - return _checked; + return _mandatory; } - public void setChecked(boolean checked) + public void setMandatory(boolean mandatory) { - this._checked = checked; - if (!checked) + this._mandatory = mandatory; + if (!mandatory) { _forbidden = false; _roles.clear(); @@ -69,7 +133,7 @@ public void setForbidden(boolean forbidden) this._forbidden = forbidden; if (forbidden) { - _checked = true; + _mandatory = true; _userDataConstraint = null; _isAnyRole = false; _isAnyAuth = false; @@ -86,7 +150,7 @@ public void setAnyRole(boolean anyRole) { this._isAnyRole = anyRole; if (anyRole) - _checked = true; + _mandatory = true; } public boolean isAnyAuth() @@ -98,7 +162,7 @@ public void setAnyAuth(boolean anyAuth) { this._isAnyAuth = anyAuth; if (anyAuth) - _checked = true; + _mandatory = true; } public UserDataConstraint getUserDataConstraint() @@ -131,13 +195,13 @@ public void addRole(String role) _roles.add(role); } - public void combine(RoleInfo other) + public void combine(Constraint other) { if (other._forbidden) setForbidden(true); - else if (other._checked) + else if (other._mandatory) { - setChecked(true); + setMandatory(true); if (other._isAnyAuth) setAnyAuth(true); if (other._isAnyRole) @@ -154,9 +218,10 @@ public String toString() return String.format("RoleInfo@%x{%s%s%s%s,%s}", hashCode(), (_forbidden ? "Forbidden," : ""), - (_checked ? "Checked," : ""), + (_mandatory ? "Checked," : ""), (_isAnyAuth ? "AnyAuth," : ""), (_isAnyRole ? "*" : _roles), _userDataConstraint); } -} + + */ diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java index 9396db56e975..fe993645695a 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java index 432fc1029d1c..3e0719d86784 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java deleted file mode 100644 index 94f750926fcb..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintSecurityHandler.java +++ /dev/null @@ -1,878 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.CopyOnWriteArraySet; - -import jakarta.servlet.HttpConstraintElement; -import jakarta.servlet.HttpMethodConstraintElement; -import jakarta.servlet.ServletSecurityElement; -import jakarta.servlet.annotation.ServletSecurity.EmptyRoleSemantic; -import jakarta.servlet.annotation.ServletSecurity.TransportGuarantee; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee10.servlet.ServletApiRequest; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletContextRequest; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.http.pathmap.MappedResource; -import org.eclipse.jetty.http.pathmap.MatchedResource; -import org.eclipse.jetty.http.pathmap.PathMappings; -import org.eclipse.jetty.http.pathmap.PathSpec; -import org.eclipse.jetty.server.HttpConfiguration; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.component.DumpableCollection; -import org.eclipse.jetty.util.security.Constraint; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * ConstraintSecurityHandler - *

- * Handler to enforce SecurityConstraints. This implementation is servlet spec - * 3.1 compliant and pre-computes the constraint combinations for runtime - * efficiency. - */ -public class ConstraintSecurityHandler extends SecurityHandler implements ConstraintAware -{ - private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); //use same as SecurityHandler - - private static final String OMISSION_SUFFIX = ".omission"; - private static final String ALL_METHODS = "*"; - private final List _constraintMappings = new CopyOnWriteArrayList<>(); - private final List _durableConstraintMappings = new CopyOnWriteArrayList<>(); - private final Set _roles = new CopyOnWriteArraySet<>(); - private final PathMappings> _constraintRoles = new PathMappings<>(); - private boolean _denyUncoveredMethods = false; - - public static Constraint createConstraint() - { - return new Constraint(); - } - - public static Constraint createConstraint(Constraint constraint) - { - try - { - return (Constraint)constraint.clone(); - } - catch (CloneNotSupportedException e) - { - throw new IllegalStateException(e); - } - } - - /** - * Create a security constraint - * - * @param name the name of the constraint - * @param authenticate true to authenticate - * @param roles list of roles - * @param dataConstraint the data constraint - * @return the constraint - */ - public static Constraint createConstraint(String name, boolean authenticate, String[] roles, int dataConstraint) - { - Constraint constraint = createConstraint(); - if (name != null) - constraint.setName(name); - constraint.setAuthenticate(authenticate); - constraint.setRoles(roles); - constraint.setDataConstraint(dataConstraint); - return constraint; - } - - /** - * Create a Constraint - * - * @param name the name - * @param element the http constraint element - * @return the created constraint - */ - public static Constraint createConstraint(String name, HttpConstraintElement element) - { - return createConstraint(name, element.getRolesAllowed(), element.getEmptyRoleSemantic(), element.getTransportGuarantee()); - } - - /** - * Create Constraint - * - * @param name the name - * @param rolesAllowed the list of allowed roles - * @param permitOrDeny the permission semantic - * @param transport the transport guarantee - * @return the created constraint - */ - public static Constraint createConstraint(String name, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport) - { - Constraint constraint = createConstraint(); - - if (rolesAllowed == null || rolesAllowed.length == 0) - { - if (permitOrDeny.equals(EmptyRoleSemantic.DENY)) - { - //Equivalent to with no roles - constraint.setName(name + "-Deny"); - constraint.setAuthenticate(true); - } - else - { - //Equivalent to no - constraint.setName(name + "-Permit"); - constraint.setAuthenticate(false); - } - } - else - { - //Equivalent to with list of s - constraint.setAuthenticate(true); - constraint.setRoles(rolesAllowed); - constraint.setName(name + "-RolesAllowed"); - } - - //Equivalent to //CONFIDENTIAL - constraint.setDataConstraint((transport.equals(TransportGuarantee.CONFIDENTIAL) ? Constraint.DC_CONFIDENTIAL : Constraint.DC_NONE)); - return constraint; - } - - public static List getConstraintMappingsForPath(String pathSpec, List constraintMappings) - { - if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0) - return Collections.emptyList(); - - List mappings = new ArrayList<>(); - for (ConstraintMapping mapping : constraintMappings) - { - if (pathSpec.equals(mapping.getPathSpec())) - { - mappings.add(mapping); - } - } - return mappings; - } - - /** - * Take out of the constraint mappings those that match the - * given path. - * - * @param pathSpec the path spec - * @param constraintMappings a new list minus the matching constraints - * @return the list of constraint mappings - */ - public static List removeConstraintMappingsForPath(String pathSpec, List constraintMappings) - { - if (pathSpec == null || "".equals(pathSpec.trim()) || constraintMappings == null || constraintMappings.size() == 0) - return Collections.emptyList(); - - List mappings = new ArrayList<>(); - for (ConstraintMapping mapping : constraintMappings) - { - //Remove the matching mappings by only copying in non-matching mappings - if (!pathSpec.equals(mapping.getPathSpec())) - { - mappings.add(mapping); - } - } - return mappings; - } - - /** - * Generate Constraints and ContraintMappings for the given url pattern and ServletSecurityElement - * - * @param name the name - * @param pathSpec the path spec - * @param securityElement the servlet security element - * @return the list of constraint mappings - */ - public static List createConstraintsWithMappingsForPath(String name, String pathSpec, ServletSecurityElement securityElement) - { - List mappings = new ArrayList<>(); - - //Create a constraint that will describe the default case (ie if not overridden by specific HttpMethodConstraints) - Constraint httpConstraint; - ConstraintMapping httpConstraintMapping = null; - - if (securityElement.getEmptyRoleSemantic() != EmptyRoleSemantic.PERMIT || - securityElement.getRolesAllowed().length != 0 || - securityElement.getTransportGuarantee() != TransportGuarantee.NONE) - { - httpConstraint = ConstraintSecurityHandler.createConstraint(name, securityElement); - - //Create a mapping for the pathSpec for the default case - httpConstraintMapping = new ConstraintMapping(); - httpConstraintMapping.setPathSpec(pathSpec); - httpConstraintMapping.setConstraint(httpConstraint); - mappings.add(httpConstraintMapping); - } - - //See Spec 13.4.1.2 p127 - List methodOmissions = new ArrayList<>(); - - //make constraint mappings for this url for each of the HttpMethodConstraintElements - java.util.Collection methodConstraintElements = securityElement.getHttpMethodConstraints(); - if (methodConstraintElements != null) - { - for (HttpMethodConstraintElement methodConstraintElement : methodConstraintElements) - { - //Make a Constraint that captures the and elements supplied for the HttpMethodConstraintElement - Constraint methodConstraint = ConstraintSecurityHandler.createConstraint(name, methodConstraintElement); - ConstraintMapping mapping = new ConstraintMapping(); - mapping.setConstraint(methodConstraint); - mapping.setPathSpec(pathSpec); - if (methodConstraintElement.getMethodName() != null) - { - mapping.setMethod(methodConstraintElement.getMethodName()); - //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint - methodOmissions.add(methodConstraintElement.getMethodName()); - } - mappings.add(mapping); - } - } - //See spec 13.4.1.2 p127 - add an omission for every method name to the default constraint - //UNLESS the default constraint contains all default values. In that case, we won't add it. See Servlet Spec 3.1 pg 129 - if (methodOmissions.size() > 0 && httpConstraintMapping != null) - httpConstraintMapping.setMethodOmissions(methodOmissions.toArray(new String[0])); - - return mappings; - } - - @Override - public List getConstraintMappings() - { - return _constraintMappings; - } - - @Override - public Set getRoles() - { - return _roles; - } - - /** - * Process the constraints following the combining rules in Servlet 3.0 EA - * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. - * - * @param constraintMappings The constraintMappings to set, from which the set of known roles - * is determined. - */ - public void setConstraintMappings(List constraintMappings) - { - setConstraintMappings(constraintMappings, null); - } - - /** - * Process the constraints following the combining rules in Servlet 3.0 EA - * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. - * - * @param constraintMappings The constraintMappings to set as array, from which the set of known roles - * is determined. Needed to retain API compatibility for 7.x - */ - public void setConstraintMappings(ConstraintMapping[] constraintMappings) - { - setConstraintMappings(Arrays.asList(constraintMappings), null); - } - - /** - * Process the constraints following the combining rules in Servlet 3.0 EA - * spec section 13.7.1 Note that much of the logic is in the RoleInfo class. - * - * @param constraintMappings The constraintMappings to set. - * @param roles The known roles (or null to determine them from the mappings) - */ - @Override - public void setConstraintMappings(List constraintMappings, Set roles) - { - - _constraintMappings.clear(); - _constraintMappings.addAll(constraintMappings); - - _durableConstraintMappings.clear(); - if (isInDurableState()) - { - _durableConstraintMappings.addAll(constraintMappings); - } - - if (roles == null) - { - roles = new HashSet<>(); - for (ConstraintMapping cm : constraintMappings) - { - String[] cmr = cm.getConstraint().getRoles(); - if (cmr != null) - { - for (String r : cmr) - { - if (!ALL_METHODS.equals(r)) - roles.add(r); - } - } - } - } - setRoles(roles); - - if (isStarted()) - { - _constraintMappings.stream().forEach(m -> processConstraintMapping(m)); - } - } - - /** - * Set the known roles. - * This may be overridden by a subsequent call to {@link #setConstraintMappings(ConstraintMapping[])} or - * {@link #setConstraintMappings(List, Set)}. - * - * @param roles The known roles (or null to determine them from the mappings) - */ - public void setRoles(Set roles) - { - _roles.clear(); - _roles.addAll(roles); - } - - @Override - public void addConstraintMapping(ConstraintMapping mapping) - { - _constraintMappings.add(mapping); - - if (isInDurableState()) - _durableConstraintMappings.add(mapping); - - if (mapping.getConstraint() != null && mapping.getConstraint().getRoles() != null) - { - //allow for lazy role naming: if a role is named in a security constraint, try and - //add it to the list of declared roles (ie as if it was declared with a security-role - for (String role : mapping.getConstraint().getRoles()) - { - if ("*".equals(role) || "**".equals(role)) - continue; - addRole(role); - } - } - - if (isStarted()) - processConstraintMapping(mapping); - } - - @Override - public void addRole(String role) - { - //add to list of declared roles - boolean modified = _roles.add(role); - if (isStarted() && modified) - { - // Add the new role to currently defined any role role infos - for (MappedResource> map : _constraintRoles) - { - for (RoleInfo info : map.getResource().values()) - { - if (info.isAnyRole()) - info.addRole(role); - } - } - } - } - - @Override - protected void doStart() throws Exception - { - _constraintRoles.reset(); - _constraintMappings.forEach(this::processConstraintMapping); - - //Servlet Spec 3.1 pg 147 sec 13.8.4.2 log paths for which there are uncovered http methods - checkPathsWithUncoveredHttpMethods(); - - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - super.doStop(); - _constraintRoles.reset(); - _constraintMappings.clear(); - _constraintMappings.addAll(_durableConstraintMappings); - } - - /** - * Create and combine the constraint with the existing processed - * constraints. - * - * @param mapping the constraint mapping - */ - protected void processConstraintMapping(ConstraintMapping mapping) - { - Map mappings = _constraintRoles.get(PathSpec.from(mapping.getPathSpec())); - if (mappings == null) - { - mappings = new HashMap<>(); - _constraintRoles.put(mapping.getPathSpec(), mappings); - } - RoleInfo allMethodsRoleInfo = mappings.get(ALL_METHODS); - if (allMethodsRoleInfo != null && allMethodsRoleInfo.isForbidden()) - return; - - if (mapping.getMethodOmissions() != null && mapping.getMethodOmissions().length > 0) - { - processConstraintMappingWithMethodOmissions(mapping, mappings); - return; - } - - String httpMethod = mapping.getMethod(); - if (httpMethod == null) - httpMethod = ALL_METHODS; - RoleInfo roleInfo = mappings.get(httpMethod); - if (roleInfo == null) - { - roleInfo = new RoleInfo(); - mappings.put(httpMethod, roleInfo); - if (allMethodsRoleInfo != null) - { - roleInfo.combine(allMethodsRoleInfo); - } - } - if (roleInfo.isForbidden()) - return; - - //add in info from the constraint - configureRoleInfo(roleInfo, mapping); - - if (roleInfo.isForbidden()) - { - if (httpMethod.equals(ALL_METHODS)) - { - mappings.clear(); - mappings.put(ALL_METHODS, roleInfo); - } - } - } - - /** - * Constraints that name method omissions are dealt with differently. - * We create an entry in the mappings with key "<method>.omission". This entry - * is only ever combined with other omissions for the same method to produce a - * consolidated RoleInfo. Then, when we wish to find the relevant constraints for - * a given Request (in prepareConstraintInfo()), we consult 3 types of entries in - * the mappings: an entry that names the method of the Request specifically, an - * entry that names constraints that apply to all methods, entries of the form - * <method>.omission, where the method of the Request is not named in the omission. - * - * @param mapping the constraint mapping - * @param mappings the mappings of roles - */ - protected void processConstraintMappingWithMethodOmissions(ConstraintMapping mapping, Map mappings) - { - String[] omissions = mapping.getMethodOmissions(); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < omissions.length; i++) - { - if (i > 0) - sb.append("."); - sb.append(omissions[i]); - } - sb.append(OMISSION_SUFFIX); - RoleInfo ri = new RoleInfo(); - mappings.put(sb.toString(), ri); - configureRoleInfo(ri, mapping); - } - - /** - * Initialize or update the RoleInfo from the constraint - * - * @param ri the role info - * @param mapping the constraint mapping - */ - protected void configureRoleInfo(RoleInfo ri, ConstraintMapping mapping) - { - Constraint constraint = mapping.getConstraint(); - boolean forbidden = constraint.isForbidden(); - ri.setForbidden(forbidden); - - //set up the data constraint (NOTE: must be done after setForbidden, as it nulls out the data constraint - //which we need in order to do combining of omissions in prepareConstraintInfo - UserDataConstraint userDataConstraint = UserDataConstraint.get(mapping.getConstraint().getDataConstraint()); - ri.setUserDataConstraint(userDataConstraint); - - //if forbidden, no point setting up roles - if (!ri.isForbidden()) - { - //add in the roles - boolean checked = mapping.getConstraint().getAuthenticate(); - ri.setChecked(checked); - - if (ri.isChecked()) - { - if (mapping.getConstraint().isAnyRole()) - { - // * means matches any defined role - for (String role : _roles) - { - ri.addRole(role); - } - ri.setAnyRole(true); - } - else if (mapping.getConstraint().isAnyAuth()) - { - //being authenticated is sufficient, not necessary to check roles - ri.setAnyAuth(true); - } - else - { - //user must be in one of the named roles - String[] newRoles = mapping.getConstraint().getRoles(); - for (String role : newRoles) - { - //check role has been defined - if (!_roles.contains(role)) - throw new IllegalArgumentException("Attempt to use undeclared role: " + role + ", known roles: " + _roles); - ri.addRole(role); - } - } - } - } - } - - /** - * Find constraints that apply to the given path. - * In order to do this, we consult 3 different types of information stored in the mappings for each path - each mapping - * represents a merged set of user data constraints, roles etc -: - *

    - *
  1. A mapping of an exact method name
  2. - *
  3. A mapping with key * that matches every method name
  4. - *
  5. Mappings with keys of the form "<method>.<method>.<method>.omission" that indicates it will match every method name EXCEPT those given
  6. - *
- * - * @see SecurityHandler#prepareConstraintInfo(String, HttpServletRequest) - */ - @Override - protected RoleInfo prepareConstraintInfo(String pathInContext, HttpServletRequest request) - { - MatchedResource> resource = _constraintRoles.getMatched(pathInContext); - if (resource == null) - return null; - - Map mappings = resource.getResource(); - if (mappings == null) - return null; - - String httpMethod = request.getMethod(); - RoleInfo roleInfo = mappings.get(httpMethod); - if (roleInfo == null) - { - //No specific http-method names matched - List applicableConstraints = new ArrayList<>(); - - //Get info for constraint that matches all methods if it exists - RoleInfo all = mappings.get(ALL_METHODS); - if (all != null) - applicableConstraints.add(all); - - //Get info for constraints that name method omissions where target method name is not omitted - //(ie matches because target method is not omitted, hence considered covered by the constraint) - for (Entry entry : mappings.entrySet()) - { - if (entry.getKey() != null && entry.getKey().endsWith(OMISSION_SUFFIX) && !entry.getKey().contains(httpMethod)) - applicableConstraints.add(entry.getValue()); - } - - if (applicableConstraints.size() == 0 && isDenyUncoveredHttpMethods()) - { - roleInfo = new RoleInfo(); - roleInfo.setForbidden(true); - } - else if (applicableConstraints.size() == 1) - roleInfo = applicableConstraints.get(0); - else - { - roleInfo = new RoleInfo(); - roleInfo.setUserDataConstraint(UserDataConstraint.None); - - for (RoleInfo r : applicableConstraints) - { - roleInfo.combine(r); - } - } - } - - return roleInfo; - } - - /** - * Return true if ok to proceed, false otherwise. - */ - @Override - protected boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Callback callback, RoleInfo roleInfo) throws IOException - { - if (roleInfo == null) - return true; - - if (roleInfo.isForbidden()) - { - Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN); - return false; - } - - UserDataConstraint dataConstraint = roleInfo.getUserDataConstraint(); - if (dataConstraint == null || dataConstraint == UserDataConstraint.None) - return true; - - HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); - - if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) - { - if (request.isSecure()) - return true; - - if (httpConfig.getSecurePort() > 0) - { - //Redirect to secure port - String scheme = httpConfig.getSecureScheme(); - int port = httpConfig.getSecurePort(); - - String url = URIUtil.newURI(scheme, Request.getServerName(request), port, request.getHttpURI().getPath(), request.getHttpURI().getQuery()); - response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); - - Response.sendRedirect(request, response, callback, HttpStatus.MOVED_TEMPORARILY_302, url, true); - } - else - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); - return false; - } - else - { - throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint); - } - } - - @Override - protected boolean isAuthMandatory(Request request, Response response, Object constraintInfo) - { - return constraintInfo != null && ((RoleInfo)constraintInfo).isChecked(); - } - - @Override - protected boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, UserIdentity userIdentity) - throws IOException - { - ServletContextRequest screquest = Request.as(request, ServletContextRequest.class); - ServletApiRequest sarequest = (screquest == null ? null : screquest.getServletApiRequest()); - - if (constraintInfo == null) - { - return true; - } - RoleInfo roleInfo = (RoleInfo)constraintInfo; - - if (!roleInfo.isChecked()) - { - return true; - } - - //handle ** role constraint - if (roleInfo.isAnyAuth() && sarequest.getUserPrincipal() != null) - { - return true; - } - - //check if user is any of the allowed roles - boolean isUserInRole = false; - for (String role : roleInfo.getRoles()) - { - if (userIdentity.isUserInRole(role)) - { - isUserInRole = true; - break; - } - } - - //handle * role constraint - if (roleInfo.isAnyRole() && sarequest.getUserPrincipal() != null && isUserInRole) - { - return true; - } - - //normal role check - if (isUserInRole) - { - return true; - } - - return false; - } - - @Override - public void dump(Appendable out, String indent) throws IOException - { - dumpObjects(out, indent, - DumpableCollection.from("roles", _roles), - DumpableCollection.from("constraints", _constraintMappings)); - } - - @Override - public void setDenyUncoveredHttpMethods(boolean deny) - { - _denyUncoveredMethods = deny; - } - - @Override - public boolean isDenyUncoveredHttpMethods() - { - return _denyUncoveredMethods; - } - - /** - * Servlet spec 3.1 pg. 147. - */ - @Override - public boolean checkPathsWithUncoveredHttpMethods() - { - Set paths = getPathsWithUncoveredHttpMethods(); - if (paths != null && !paths.isEmpty()) - { - LOG.warn("{} has uncovered HTTP methods for the following paths: {}", - ContextHandler.getCurrentContext(), paths); - return true; - } - return false; - } - - /** - * Servlet spec 3.1 pg. 147. - * The container must check all the combined security constraint - * information and log any methods that are not protected and the - * urls at which they are not protected - * - * @return list of paths for which there are uncovered methods - */ - public Set getPathsWithUncoveredHttpMethods() - { - //if automatically denying uncovered methods, there are no uncovered methods - if (_denyUncoveredMethods) - return Collections.emptySet(); - - Set uncoveredPaths = new HashSet<>(); - - for (MappedResource> resource : _constraintRoles) - { - String path = resource.getPathSpec().getDeclaration(); - Map methodMappings = resource.getResource(); - //Each key is either: - // : an exact method name - // : * which means that the constraint applies to every method - // : a name of the form ...omission, which means it applies to every method EXCEPT those named - if (methodMappings.get(ALL_METHODS) != null) - continue; //can't be any uncovered methods for this url path - - boolean hasOmissions = omissionsExist(path, methodMappings); - - for (String method : methodMappings.keySet()) - { - if (method.endsWith(OMISSION_SUFFIX)) - { - Set omittedMethods = getOmittedMethods(method); - for (String m : omittedMethods) - { - if (!methodMappings.containsKey(m)) - uncoveredPaths.add(path); - } - } - else - { - //an exact method name - if (!hasOmissions) - //an http-method does not have http-method-omission to cover the other method names - uncoveredPaths.add(path); - } - } - } - return uncoveredPaths; - } - - /** - * Check if any http method omissions exist in the list of method - * to auth info mappings. - * - * @param path the path - * @param methodMappings the method mappings - * @return true if omission exist - */ - protected boolean omissionsExist(String path, Map methodMappings) - { - if (methodMappings == null) - return false; - boolean hasOmissions = false; - for (String m : methodMappings.keySet()) - { - if (m.endsWith(OMISSION_SUFFIX)) - hasOmissions = true; - } - return hasOmissions; - } - - /** - * Given a string of the form <method>.<method>.omission - * split out the individual method names. - * - * @param omission the method - * @return the list of strings - */ - protected Set getOmittedMethods(String omission) - { - if (omission == null || !omission.endsWith(OMISSION_SUFFIX)) - return Collections.emptySet(); - - String[] strings = omission.split("\\."); - Set methods = new HashSet<>(); - for (int i = 0; i < strings.length - 1; i++) - { - methods.add(strings[i]); - } - return methods; - } - - /** - * Constraints can be added to the ConstraintSecurityHandler before the - * associated context is started. These constraints should persist across - * a stop/start. Others can be added after the associated context is starting - * (eg by a web.xml/web-fragment.xml, annotation or jakarta.servlet api call) - - * these should not be persisted across a stop/start as they will be re-added on - * the restart. - * - * @return true if the context with which this ConstraintSecurityHandler - * has not yet started, or if there is no context, the server has not yet started. - */ - private boolean isInDurableState() - { - ServletContextHandler contextHandler = ServletContextHandler.getCurrentServletContextHandler(); - Server server = getServer(); - - return (contextHandler == null && server == null) || (contextHandler != null && !contextHandler.isRunning()) || (contextHandler == null && server != null && !server.isRunning()); - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java index ca8af2fee3f5..4d123d1d7e83 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index 3a682de15077..41237d1e92d3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java index b6e3d06e2802..ef56618b9778 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java index e0be900baf14..78ff375e36a6 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java index b0984027ae8d..2e5530e8354a 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/HashLoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 9725f36abad8..d06c75cc8ea2 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java index ea977943ecab..7eca7b876017 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/JDBCLoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java index ac3bada8d130..592d5a8eeb90 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -15,6 +15,7 @@ import org.eclipse.jetty.security.authentication.LoginAuthenticator; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; /** * LoggedOutAuthentication @@ -37,7 +38,7 @@ public Authentication login(String username, Object password, Request request, R if (username == null) return null; - UserIdentity identity = _authenticator.login(username, password, request, res); + UserIdentity identity = _authenticator.login(username, password, request, response); if (identity != null) { IdentityService identityService = _authenticator.getLoginService().getIdentityService(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java index 3fbb37d2f378..3d260f88a21c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index e9a959f982ba..5204a3e3347f 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java index fd34e91800a5..2ddb023c6947 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RolePrincipal.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java index ecb4423497ee..defced954fb1 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java index d0c2a530fce1..b6c55e65d690 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 180fec8dea96..e94d45785a5d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -16,26 +16,25 @@ import java.io.IOException; import java.security.Principal; import java.util.ArrayList; -import java.util.Enumeration; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.Set; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee10.servlet.ServletApiRequest; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletContextRequest; -import org.eclipse.jetty.ee10.servlet.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.component.DumpableCollection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,6 +55,8 @@ */ public abstract class SecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration { + public static String SESSION_AUTHENTICATED_ATTRIBUTE = "org.eclipse.jetty.security.sessionAuthenticated"; + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); private static final List __knownAuthenticatorFactories = new ArrayList<>(); @@ -64,7 +65,7 @@ public abstract class SecurityHandler extends Handler.Wrapper implements Authent private Authenticator.Factory _authenticatorFactory; private String _realmName; private String _authMethod; - private final Map _initParameters = new HashMap<>(); + private final Map _parameters = new HashMap<>(); private LoginService _loginService; private IdentityService _identityService; private boolean _renewSession = true; @@ -218,51 +219,16 @@ public void setAuthMethod(String authMethod) _authMethod = authMethod; } - /** - * @return True if forwards to welcome files are authenticated - */ - public boolean isCheckWelcomeFiles() - { - return _checkWelcomeFiles; - } - - /** - * @param authenticateWelcomeFiles True if forwards to welcome files are - * authenticated - * @throws IllegalStateException if the SecurityHandler is running - */ - public void setCheckWelcomeFiles(boolean authenticateWelcomeFiles) - { - if (isRunning()) - throw new IllegalStateException("running"); - _checkWelcomeFiles = authenticateWelcomeFiles; - } - @Override - public String getInitParameter(String key) + public String getParameter(String key) { - return _initParameters.get(key); + return _parameters.get(key); } @Override - public Set getInitParameterNames() - { - return _initParameters.keySet(); - } - - /** - * Set an initialization parameter. - * - * @param key the init key - * @param value the init value - * @return previous value - * @throws IllegalStateException if the SecurityHandler is started - */ - public String setInitParameter(String key, String value) + public Set getParameterNames() { - if (isStarted()) - throw new IllegalStateException("started"); - return _initParameters.put(key, value); + return _parameters.keySet(); } protected LoginService findLoginService() throws Exception @@ -296,20 +262,6 @@ protected IdentityService findIdentityService() protected void doStart() throws Exception { - // copy security init parameters - Context context = ContextHandler.getCurrentContext(); - if (context != null) - { - Enumeration names = context.getInitParameterNames(); - while (names != null && names.hasMoreElements()) - { - String name = names.nextElement(); - if (name.startsWith("org.eclipse.jetty.security.") && - getInitParameter(name) == null) - setInitParameter(name, context.getInitParameter(name)); - } - } - // complicated resolution of login and identity service to handle // many different ways these can be constructed and injected. @@ -345,6 +297,8 @@ else if (_loginService.getIdentityService() != _identityService) throw new IllegalStateException("LoginService has different IdentityService to " + this); } + Context context = ContextHandler.getCurrentContext(); + if (_authenticator == null) { // If someone has set an authenticator factory only use that, otherwise try the list of discovered factories. @@ -410,25 +364,6 @@ protected void doStop() throws Exception super.doStop(); } - protected boolean checkSecurity(Request request) - { - switch (request.getDispatcherType()) - { - case REQUEST: - case ASYNC: - return true; - case FORWARD: - if (isCheckWelcomeFiles() && request.getAttribute("org.eclipse.jetty.server.welcome") != null) - { - request.removeAttribute("org.eclipse.jetty.server.welcome"); - return true; - } - return false; - default: - return false; - } - } - @Override public boolean isSessionRenewedOnAuthentication() { @@ -449,42 +384,36 @@ public void setSessionRenewedOnAuthentication(boolean renew) } @Override - public boolean process(Request request, Response response, Callback callback) throws Exception + public boolean handle(Request request, Response response, Callback callback) throws Exception { Handler next = getHandler(); if (next == null) return false; - ServletContextRequest servletContextRequest = Request.as(request, ServletContextRequest.class); - if (servletContextRequest == null) - return false; - ServletApiRequest servletApiRequest = servletContextRequest.getServletApiRequest(); Authenticator authenticator = _authenticator; - - if (!checkSecurity(servletApiRequest)) + if (authenticator != null) + request = authenticator.prepareRequest(request); + + String pathInContext = Request.getPathInContext(request); + Constraint constraint = getConstraint(pathInContext, request); + + if (constraint == null) { //don't need to do any security work, let other handlers do the processing - return next.process(request, response, callback); + return next.handle(request, response, callback); } - //See Servlet Spec 3.1 sec 13.6.3 - if (authenticator != null) - authenticator.prepareRequest(request); - - RoleInfo roleInfo = prepareConstraintInfo(servletContextRequest.getPathInContext(), servletApiRequest); - // Check data constraints - if (!checkUserDataPermissions(servletContextRequest.getPathInContext(), servletContextRequest, response, callback, roleInfo)) + if (!checkUserDataConstraint(pathInContext, request, response, callback, constraint)) return true; - // is Auth mandatory? - boolean isAuthMandatory = - isAuthMandatory(request, response, roleInfo); - if (isAuthMandatory && authenticator == null) + // is Auth mandatory? + boolean isAuthenticationMandatory = constraint.isAuthenticationMandatory(); + if (isAuthenticationMandatory && authenticator == null) { - LOG.warn("No authenticator for: {}", roleInfo); - Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN); + LOG.warn("No authenticator for: {}", constraint); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); return true; } @@ -492,85 +421,86 @@ public boolean process(Request request, Response response, Callback callback) th Object previousIdentity = null; try { - Authentication authentication = servletApiRequest.getAuthentication(); + Authentication authentication = Authentication.getAuthentication(request); if (authentication == null || authentication == Authentication.NOT_CHECKED) - authentication = authenticator == null ? Authentication.UNAUTHENTICATED : authenticator.validateRequest(request, response, callback, isAuthMandatory); + authentication = authenticator == null + ? Authentication.UNAUTHENTICATED + : authenticator.validateRequest(request, response, callback, isAuthenticationMandatory); if (authentication instanceof Authentication.ResponseSent) return true; if (authentication instanceof Authentication.User userAuth) { - servletApiRequest.setAuthentication(authentication); + Authentication.setAuthentication(request, authentication); if (_identityService != null) previousIdentity = _identityService.associate(userAuth.getUserIdentity()); - if (isAuthMandatory) + if (isAuthenticationMandatory) { - boolean authorized = checkWebResourcePermissions(Request.getPathInContext(request), request, response, roleInfo, userAuth.getUserIdentity()); + boolean authorized = checkAuthorization(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); if (!authorized) { - Response.writeError(request, response, callback, HttpServletResponse.SC_FORBIDDEN, "!role"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!role"); return true; } } //process the request by other handlers - boolean processed = next.process(request, response, callback); - // TODO this looks wrong + boolean processed = next.handle(request, response, callback); + // TODO this looks wrong as in way too late if (processed && authenticator != null) - authenticator.secureResponse(request, response, callback, isAuthMandatory, userAuth); + authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, userAuth); return processed; } - if (authentication instanceof Authentication.Deferred) + if (authentication instanceof DeferredAuthentication deferred) { - DeferredAuthentication deferred = (DeferredAuthentication)authentication; - servletApiRequest.setAuthentication(authentication); + Authentication.setAuthentication(request, authentication); - boolean processed = false; + boolean handled; try { //process the request by other handlers - processed = next.process(request, response, callback); + handled = next.handle(request, response, callback); } finally { previousIdentity = deferred.getPreviousAssociation(); } - if (processed && authenticator != null) + if (handled && authenticator != null) { - Authentication auth = servletApiRequest.getAuthentication(); + Authentication auth = Authentication.getAuthentication(request); if (auth instanceof Authentication.User userAuth) - authenticator.secureResponse(request, response, callback, isAuthMandatory, userAuth); + authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, userAuth); else - authenticator.secureResponse(request, response, callback, isAuthMandatory, null); + authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, null); } - return processed; + return handled; } - if (isAuthMandatory) + if (isAuthenticationMandatory) { - Response.writeError(request, response, callback, HttpServletResponse.SC_UNAUTHORIZED, "unauthenticated"); + Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401, "unauthenticated"); return true; } - servletApiRequest.setAuthentication(authentication); + Authentication.setAuthentication(request, authentication); if (_identityService != null) previousIdentity = _identityService.associate(null); //process the request by other handlers - boolean processed = next.process(request, response, callback); + boolean handled = next.handle(request, response, callback); - if (processed && authenticator != null) - authenticator.secureResponse(request, response, callback, isAuthMandatory, null); - return processed; + if (handled && authenticator != null) + authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, null); + return handled; } catch (ServerAuthException e) { // jaspi 3.8.3 send HTTP 500 internal server error, with message from AuthException - Response.writeError(request, response, callback, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + Response.writeError(request, response, callback, HttpStatus.INTERNAL_SERVER_ERROR_500, e.getMessage()); return true; } finally @@ -582,11 +512,11 @@ public boolean process(Request request, Response response, Callback callback) th public static SecurityHandler getCurrentSecurityHandler() { - ServletContextHandler contextHandler = ServletContextHandler.getCurrentServletContextHandler(); - if (contextHandler == null) - return null; - - return contextHandler.getDescendant(SecurityHandler.class); + ContextHandler contextHandler = ContextHandler.getCurrentContextHandler(); + if (contextHandler != null) + return contextHandler.getDescendant(SecurityHandler.class); + // TODO what about without context? + return null; } public void logout(Authentication.User user) @@ -610,14 +540,88 @@ public void logout(Authentication.User user) } } - protected abstract RoleInfo prepareConstraintInfo(String pathInContext, HttpServletRequest request); + protected abstract Constraint getConstraint(String pathInContext, Request request); + + protected boolean checkUserDataConstraint(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException + { + if (constraint == null) + return true; + + if (constraint.isForbidden()) + { + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); + return false; + } + + UserDataConstraint dataConstraint = constraint.getUserDataConstraint(); + if (dataConstraint == null || dataConstraint == UserDataConstraint.None) + return true; + + HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); + + if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) + { + if (request.isSecure()) + return true; - protected abstract boolean checkUserDataPermissions(String pathInContext, Request request, Response response, Callback callback, RoleInfo constraintInfo) throws IOException; + if (httpConfig.getSecurePort() > 0) + { + //Redirect to secure port + String scheme = httpConfig.getSecureScheme(); + int port = httpConfig.getSecurePort(); - protected abstract boolean isAuthMandatory(Request baseRequest, Response baseResponse, Object constraintInfo); + String url = URIUtil.newURI(scheme, Request.getServerName(request), port, request.getHttpURI().getPath(), request.getHttpURI().getQuery()); + response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); - protected abstract boolean checkWebResourcePermissions(String pathInContext, Request request, Response response, Object constraintInfo, - UserIdentity userIdentity) throws IOException; + Response.sendRedirect(request, response, callback, HttpStatus.MOVED_TEMPORARILY_302, url, true); + } + else + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); + return false; + } + else + { + throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint); + } + } + + protected boolean checkAuthorization(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) + { + + Constraint.Authorization authorization = constraint.getAuthorization(); + if (authorization == null) + return true; + + switch (constraint.getAuthorization()) + { + case AUTHENTICATED: + return userIdentity.getUserPrincipal() != null; + + case AUTHENTICATED_IN_KNOWN_ROLE: + if (userIdentity.getUserPrincipal() == null) + return false; + for (String role : getKnownRoles()) + if (userIdentity.isUserInRole(role)) + return true; + return false; + + case AUTHENTICATED_IN_ROLE: + if (userIdentity.getUserPrincipal() == null) + return false; + for (String role : constraint.getRoles()) + if (userIdentity.isUserInRole(role)) + return true; + return false; + + default: + return false; + } + } + + protected Set getKnownRoles() + { + return Collections.emptySet(); + } public class NotChecked implements Principal { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java index e503667313b0..7f35b091e0a0 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ServerAuthException.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java index d38dd24d3667..f2f9b4243000 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserIdentity.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java index c7514b1ea073..118046e805af 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SpnegoUserPrincipal.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java index 95abc4752bc7..718a6e043bd3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java index 17d4c96c7fe8..1650761186f0 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java index 5ffae273d99f..4f3d6b3c1014 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java index 069f6616e8ac..5e44a41d6719 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserPrincipal.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java index 0e9341539249..cc3a7391e992 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java index ff0ca3de4e85..adfea3b58fc0 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -43,15 +43,15 @@ public String getRealmName() } @Override - public String getInitParameter(String param) + public String getParameter(String param) { - return _configuration.getInitParameter(param); + return _configuration.getParameter(param); } @Override - public Set getInitParameterNames() + public Set getParameterNames() { - return _configuration.getInitParameterNames(); + return _configuration.getParameterNames(); } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java index a05ede0af0f1..e983965e23cb 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index 1290d24436ad..0b2d1524c1d5 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java index 79cb2a75920b..63171e87740d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index cde8950a0048..7304e3edc75e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 8dcae87f8113..51ec0ab7dda5 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 79ee6a5aa494..c05259f9971c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -63,10 +63,10 @@ public void setConfiguration(AuthConfiguration configuration) { super.setConfiguration(configuration); - String mna = configuration.getInitParameter("maxNonceAge"); + String mna = configuration.getParameter("maxNonceAge"); if (mna != null) setMaxNonceAge(Long.parseLong(mna)); - String mnc = configuration.getInitParameter("maxNonceCount"); + String mnc = configuration.getParameter("maxNonceCount"); if (mnc != null) setMaxNonceCount(Integer.parseInt(mnc)); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 8ca147dcc454..dbf592e733d4 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -15,7 +15,6 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; -import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.http.MimeTypes; @@ -24,6 +23,7 @@ import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Session; @@ -105,13 +105,13 @@ public boolean getAlwaysSaveUri() public void setConfiguration(AuthConfiguration configuration) { super.setConfiguration(configuration); - String login = configuration.getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE); + String login = configuration.getParameter(FormAuthenticator.__FORM_LOGIN_PAGE); if (login != null) setLoginPage(login); - String error = configuration.getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE); + String error = configuration.getParameter(FormAuthenticator.__FORM_ERROR_PAGE); if (error != null) setErrorPage(error); - String dispatch = configuration.getInitParameter(FormAuthenticator.__FORM_DISPATCH); + String dispatch = configuration.getParameter(FormAuthenticator.__FORM_DISPATCH); _dispatch = dispatch == null ? _dispatch : Boolean.parseBoolean(dispatch); } @@ -182,7 +182,7 @@ public void logout(Request request) } @Override - public void prepareRequest(Request request) + public Request prepareRequest(Request request) { //if this is a request resulting from a redirect after auth is complete //(ie its from a redirect to the original request uri) then due to @@ -193,18 +193,18 @@ public void prepareRequest(Request request) //See Servlet Spec 3.1 sec 13.6.3 Session session = request.getSession(false); if (session == null || session.getAttribute(SessionAuthentication.__J_AUTHENTICATED) == null) - return; //not authenticated yet + return request; //not authenticated yet HttpURI juri = (HttpURI)session.getAttribute(__J_URI); if (juri == null) - return; //no original uri saved + return request; //no original uri saved String method = (String)session.getAttribute(__J_METHOD); if (method == null || method.length() == 0) - return; //didn't save original request method + return request; //didn't save original request method if (!juri.equals(request.getHttpURI())) - return; //this request is not for the same url as the original + return request; //this request is not for the same url as the original //restore the original request's method on this request if (LOG.isDebugEnabled()) @@ -212,6 +212,7 @@ public void prepareRequest(Request request) // TODO: Set method. // servletContextRequest.getServletApiRequest().setMethod(method); + return request; } protected Fields getParameters(Request request) @@ -223,99 +224,8 @@ protected Fields getParameters(Request request) protected String encodeURL(String url) { - SessionManager sessionManager = _response.getServletContextRequest().getServletChannel().getContextHandler().getSessionHandler(); - if (sessionManager == null) - return url; - - HttpURI uri = null; - if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) - { - uri = HttpURI.from(url); - String path = uri.getPath(); - path = (path == null ? "" : path); - int port = uri.getPort(); - if (port < 0) - port = HttpScheme.getDefaultPort(uri.getScheme()); - - // Is it the same server? - if (!Request.getServerName(request).equalsIgnoreCase(uri.getHost())) - return url; - if (Request.getServerPort(request) != port) - return url; - if (request.getContext() != null && !path.startsWith(request.getContext().getContextPath())) - return url; - } - - String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix(); - if (sessionURLPrefix == null) - return url; - - if (url == null) - return null; - - // should not encode if cookies in evidence - if ((sessionManager.isUsingCookies() && httpServletRequest.isRequestedSessionIdFromCookie()) || !sessionManager.isUsingURLs()) - { - int prefix = url.indexOf(sessionURLPrefix); - if (prefix != -1) - { - int suffix = url.indexOf("?", prefix); - if (suffix < 0) - suffix = url.indexOf("#", prefix); - - if (suffix <= prefix) - return url.substring(0, prefix); - return url.substring(0, prefix) + url.substring(suffix); - } - return url; - } - - // get session; - Session session = request.getSession(false); - - // no session - if (session == null || !(session instanceof Session.API)) - return url; - - // invalid session - Session.API api = (Session.API)session; - - if (!api.getSession().isValid()) - return url; - - String id = api.getSession().getExtendedId(); - - if (uri == null) - uri = HttpURI.from(url); - - // Already encoded - int prefix = url.indexOf(sessionURLPrefix); - if (prefix != -1) - { - int suffix = url.indexOf("?", prefix); - if (suffix < 0) - suffix = url.indexOf("#", prefix); - - if (suffix <= prefix) - return url.substring(0, prefix + sessionURLPrefix.length()) + id; - return url.substring(0, prefix + sessionURLPrefix.length()) + id + - url.substring(suffix); - } - - // edit the session - int suffix = url.indexOf('?'); - if (suffix < 0) - suffix = url.indexOf('#'); - if (suffix < 0) - { - return url + - ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + //if no path, insert the root path - sessionURLPrefix + id; - } - - return url.substring(0, suffix) + - ((HttpScheme.HTTPS.is(uri.getScheme()) || HttpScheme.HTTP.is(uri.getScheme())) && uri.getPath() == null ? "/" : "") + //if no path so insert the root path - sessionURLPrefix + id + url.substring(suffix); + // TODO + return url; } @Override @@ -453,9 +363,10 @@ public Authentication validateRequest(Request req, Response res, Callback callba session.setAttribute(__J_URI, req.getHttpURI()); session.setAttribute(__J_METHOD, req.getMethod()); - if (MimeTypes.Type.FORM_ENCODED.is(req.getContentType()) && HttpMethod.POST.is(req.getMethod())) + if (HttpMethod.POST.is(req.getMethod()) && MimeTypes.Type.FORM_ENCODED.is(req.getHeaders().get(HttpHeader.CONTENT_TYPE))) { - session.setAttribute(__J_POST, servletApiRequest.getContentParameters()); + // TODO limit size!!! + session.setAttribute(__J_POST, FormFields.from(req)); } } } @@ -473,7 +384,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba else {*/ LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); - Response.sendRedirect(req, res, callback, servletContextRequest.getHttpServletResponse().encodeRedirectURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); + Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); //} return Authentication.SEND_CONTINUE; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index ebc3cebdf7e6..d647d876730e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -16,6 +16,7 @@ import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -36,9 +37,9 @@ protected LoginAuthenticator() } @Override - public void prepareRequest(Request request) + public Request prepareRequest(Request request) { - //empty implementation as the default + return request; } /** @@ -65,9 +66,10 @@ public UserIdentity login(String username, Object password, Request request, Res public void logout(Request request) { + Session session = request.getSession(false); if (session == null) return; - session.removeAttribute(ManagedSession.SESSION_CREATED_SECURE); + session.removeAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE); } @Override @@ -108,9 +110,9 @@ protected Session renewSession(Request httpRequest, Response httpResponse) { //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users //(indicated by SESSION_SECURED not being set on the session) then we should change id - if (session.getAttribute(ManagedSession.SESSION_CREATED_SECURE) != Boolean.TRUE) + if (session.getAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE) != Boolean.TRUE) { - session.setAttribute(ManagedSession.SESSION_CREATED_SECURE, Boolean.TRUE); + session.setAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE, Boolean.TRUE); session.renewId(httpRequest, httpResponse); return session; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java index fc30dbf88170..e4d6514cfe9c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java index 1c5813fe1e87..44aa3bd4ddf1 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 44e239527f3c..6af566f2e4c2 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at @@ -22,6 +22,7 @@ import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Session; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ * into an HttpSession to remember that the user is authenticated. */ public class SessionAuthentication extends AbstractUserAuthentication - implements Serializable, HttpSessionActivationListener, HttpSessionBindingListener + implements Serializable { private static final Logger LOG = LoggerFactory.getLogger(SessionAuthentication.class); @@ -43,7 +44,7 @@ public class SessionAuthentication extends AbstractUserAuthentication private final String _name; private final Object _credentials; - private transient HttpSession _session; + private Session _session; public SessionAuthentication(String method, UserIdentity userIdentity, Object credentials) { @@ -97,6 +98,8 @@ public String toString() return String.format("%s@%x{%s,%s}", this.getClass().getSimpleName(), hashCode(), _session == null ? "-" : _session.getId(), _userIdentity); } + /* TODO + @Override public void sessionWillPassivate(HttpSessionEvent se) { @@ -110,4 +113,6 @@ public void sessionDidActivate(HttpSessionEvent se) _session = se.getSession(); } } + + */ } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java index 15f238884900..9e5c0db90dd6 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java index 5ceb5432bdaf..1e5616d55640 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/package-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java index b940f0ce18bf..1a22276a7415 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/package-info.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java new file mode 100644 index 000000000000..3d7baa988561 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java @@ -0,0 +1,88 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.Callback; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; + +public class DefaultIdentityServiceTest +{ + @Test + public void testDefaultIdentityService() throws Exception + { + Server server = new Server(); + SecurityHandler securityHandler = new SecurityHandler(); + TestAuthenticator authenticator = new TestAuthenticator(); + securityHandler.setAuthenticator(authenticator); + + try + { + server.setHandler(securityHandler); + server.start(); + + // The DefaultIdentityService should have been created by default. + assertThat(securityHandler.getIdentityService(), instanceOf(DefaultIdentityService.class)); + assertThat(authenticator.getIdentityService(), instanceOf(DefaultIdentityService.class)); + } + finally + { + server.stop(); + } + } + + public static class TestAuthenticator implements Authenticator + { + private IdentityService _identityService; + + public IdentityService getIdentityService() + { + return _identityService; + } + + @Override + public void setConfiguration(AuthConfiguration configuration) + { + _identityService = configuration.getIdentityService(); + } + + @Override + public String getAuthMethod() + { + return getClass().getSimpleName(); + } + + @Override + public Request prepareRequest(Request request) + { + } + + @Override + public Authentication validateRequest(Request request, Response response, Callback callback, boolean mandatory) throws ServerAuthException + { + return null; + } + + @Override + public boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, Authentication.User validatedUser) throws ServerAuthException + { + return false; + } + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java new file mode 100644 index 000000000000..4331fc8b9631 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java @@ -0,0 +1,85 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.nio.file.Path; + +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.resource.FileSystemPool; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Tests of the HashLoginService. + */ +public class HashLoginServiceTest +{ + @BeforeEach + public void beforeEach() + { + assertThat(FileSystemPool.INSTANCE.mounts(), empty()); + } + + @AfterEach + public void afterEach() + { + assertThat(FileSystemPool.INSTANCE.mounts(), empty()); + } + + @Test + public void testAutoCreatedUserStore() throws Exception + { + Path fooPropsFile = MavenTestingUtils.getTestResourcePathFile("foo.properties"); + Resource fooResource = ResourceFactory.root().newResource(fooPropsFile); + HashLoginService loginService = new HashLoginService("foo", fooResource); + assertThat(loginService.getIdentityService(), is(notNullValue())); + loginService.start(); + assertTrue(loginService.getUserStore().isStarted()); + assertTrue(loginService.isUserStoreAutoCreate()); + + loginService.stop(); + assertFalse(loginService.isUserStoreAutoCreate()); + assertThat(loginService.getUserStore(), is(nullValue())); + } + + @Test + public void testProvidedUserStore() throws Exception + { + HashLoginService loginService = new HashLoginService("foo"); + assertThat(loginService.getIdentityService(), is(notNullValue())); + UserStore store = new UserStore(); + loginService.setUserStore(store); + assertFalse(store.isStarted()); + loginService.start(); + assertTrue(loginService.getUserStore().isStarted()); + assertFalse(loginService.isUserStoreAutoCreate()); + + loginService.stop(); + + assertFalse(loginService.isUserStoreAutoCreate()); + assertFalse(store.isStarted()); + assertThat(loginService.getUserStore(), is(notNullValue())); + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java new file mode 100644 index 000000000000..e6492f54d1e2 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/PropertyUserStoreTest.java @@ -0,0 +1,334 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + +import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; +import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.NanoTime; +import org.eclipse.jetty.util.Scanner; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.resource.FileSystemPool; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.eclipse.jetty.util.security.Credential; +import org.hamcrest.Matcher; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.OS; +import org.junit.jupiter.api.extension.ExtendWith; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(WorkDirExtension.class) +public class PropertyUserStoreTest +{ + private static final class UserCount implements PropertyUserStore.UserListener + { + private final AtomicInteger userCount = new AtomicInteger(); + private final List users = new ArrayList<>(); + + private UserCount() + { + } + + @Override + public void update(String username, Credential credential, String[] roleArray) + { + if (!users.contains(username)) + { + users.add(username); + userCount.getAndIncrement(); + } + } + + @Override + public void remove(String username) + { + users.remove(username); + userCount.getAndDecrement(); + } + + public void awaitCount(int expectedCount) throws InterruptedException + { + long start = NanoTime.now(); + while (userCount.get() != expectedCount && NanoTime.secondsSince(start) < 10) + { + TimeUnit.MILLISECONDS.sleep(100); + } + + assertThatCount(is(expectedCount)); + } + + public void assertThatCount(Matcher matcher) + { + assertThat("User count", userCount.get(), matcher); + } + + public void assertThatUsers(Matcher> matcher) + { + assertThat("Users list", users, matcher); + } + } + + public WorkDir testdir; + + @BeforeEach + public void beforeEach() + { + assertThat(FileSystemPool.INSTANCE.mounts(), empty()); + } + + @AfterEach + public void afterEach() + { + assertThat(FileSystemPool.INSTANCE.mounts(), empty()); + } + + private Path initUsersText() throws Exception + { + Path dir = testdir.getPath(); + Path users = dir.resolve("users.txt"); + Files.deleteIfExists(users); + + writeUser(users); + return users; + } + + private URI initUsersPackedFileText() + throws Exception + { + Path dir = testdir.getPath(); + Path users = dir.resolve("users.txt"); + writeUser(users); + Path usersJar = dir.resolve("users.jar"); + String entryPath = "mountain_goat/pale_ale.txt"; + try (InputStream fileInputStream = Files.newInputStream(users)) + { + try (OutputStream outputStream = Files.newOutputStream(usersJar)) + { + try (JarOutputStream jarOutputStream = new JarOutputStream(outputStream)) + { + // add fake entry + jarOutputStream.putNextEntry(new JarEntry("foo/wine")); + + JarEntry jarEntry = new JarEntry(entryPath); + jarOutputStream.putNextEntry(jarEntry); + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = fileInputStream.read(buffer)) != -1) + { + jarOutputStream.write(buffer, 0, bytesRead); + } + // add fake entry + jarOutputStream.putNextEntry(new JarEntry("foo/cheese")); + } + } + } + return URIUtil.uriJarPrefix(usersJar.toUri(), "!/" + entryPath); + } + + private void writeUser(File usersFile) throws IOException + { + writeUser(usersFile.toPath()); + } + + private void writeUser(Path usersFile) throws IOException + { + try (Writer writer = Files.newBufferedWriter(usersFile, UTF_8)) + { + writer.append("tom: tom, roleA\n"); + writer.append("dick: dick, roleB\n"); + writer.append("harry: harry, roleA, roleB\n"); + } + } + + private void addAdditionalUser(Path usersFile, String userRef) throws Exception + { + Thread.sleep(1001); + try (Writer writer = Files.newBufferedWriter(usersFile, UTF_8, StandardOpenOption.APPEND)) + { + writer.append(userRef); + } + } + + @Test + public void testPropertyUserStoreLoad() throws Exception + { + testdir.ensureEmpty(); + + final UserCount userCount = new UserCount(); + final Path usersFile = initUsersText(); + + PropertyUserStore store = new PropertyUserStore(); + store.setConfig(ResourceFactory.root().newResource(usersFile)); + + store.registerUserListener(userCount); + + store.start(); + + assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("tom"), notNullValue()); + assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("dick"), notNullValue()); + assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("harry"), notNullValue()); + userCount.assertThatCount(is(3)); + userCount.awaitCount(3); + } + + @Test + public void testPropertyUserStoreFails() + { + assertThrows(IllegalStateException.class, () -> + { + PropertyUserStore store = new PropertyUserStore(); + Resource doesNotExist = ResourceFactory.root().newResource("file:///this/file/does/not/exist.txt"); + store.setConfig(doesNotExist); + store.start(); + }); + } + + @Test + public void testPropertyUserStoreLoadFromJarFile() throws Exception + { + testdir.ensureEmpty(); + + final UserCount userCount = new UserCount(); + final URI usersFile = initUsersPackedFileText(); + + try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) + { + Resource jarResource = resourceFactory.newResource(usersFile); + PropertyUserStore store = new PropertyUserStore(); + store.setConfig(jarResource); + + store.registerUserListener(userCount); + + store.start(); + + assertThat("Failed to retrieve user directly from PropertyUserStore", // + store.getUserPrincipal("tom"), notNullValue()); + assertThat("Failed to retrieve user directly from PropertyUserStore", // + store.getUserPrincipal("dick"), notNullValue()); + assertThat("Failed to retrieve user directly from PropertyUserStore", // + store.getUserPrincipal("harry"), notNullValue()); + userCount.assertThatCount(is(3)); + userCount.awaitCount(3); + } + } + + @Test + public void testPropertyUserStoreLoadUpdateUser() throws Exception + { + testdir.ensureEmpty(); + + final UserCount userCount = new UserCount(); + final Path usersFile = initUsersText(); + final AtomicInteger loadCount = new AtomicInteger(0); + PropertyUserStore store = new PropertyUserStore() + { + @Override + protected void loadUsers() throws IOException + { + loadCount.incrementAndGet(); + super.loadUsers(); + } + }; + store.setRefreshInterval(1); + store.setConfig(ResourceFactory.root().newResource(usersFile)); + store.registerUserListener(userCount); + + store.start(); + + userCount.assertThatCount(is(3)); + assertThat(loadCount.get(), is(1)); + + addAdditionalUser(usersFile, "skip: skip, roleA\n"); + userCount.awaitCount(4); + assertThat(loadCount.get(), is(2)); + assertThat(store.getUserPrincipal("skip"), notNullValue()); + userCount.assertThatCount(is(4)); + userCount.assertThatUsers(hasItem("skip")); + + if (OS.LINUX.isCurrentOs()) + Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt"), + PosixFilePermissions.asFileAttribute(EnumSet.noneOf(PosixFilePermission.class))); + else + Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt")); + + Scanner scanner = store.getBean(Scanner.class); + CountDownLatch latch = new CountDownLatch(2); + scanner.scan(Callback.from(latch::countDown)); + scanner.scan(Callback.from(latch::countDown)); + assertTrue(latch.await(5, TimeUnit.SECONDS)); + assertThat(loadCount.get(), is(2)); + + userCount.assertThatCount(is(4)); + userCount.assertThatUsers(hasItem("skip")); + } + + @Test + public void testPropertyUserStoreLoadRemoveUser() throws Exception + { + testdir.ensureEmpty(); + + final UserCount userCount = new UserCount(); + // initial user file (3) users + final Path usersFile = initUsersText(); + + // adding 4th user + addAdditionalUser(usersFile, "skip: skip, roleA\n"); + + PropertyUserStore store = new PropertyUserStore(); + store.setHotReload(true); + store.setConfig(ResourceFactory.root().newResource(usersFile)); + + store.registerUserListener(userCount); + + store.start(); + + userCount.assertThatCount(is(4)); + + // rewrite file with original 3 users + initUsersText(); + + userCount.awaitCount(3); + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java new file mode 100644 index 000000000000..e3463fb5ebf6 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -0,0 +1,183 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.session.SimpleSessionHandler; +import org.eclipse.jetty.util.Callback; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; + +public class SecurityHandlerTest +{ + private Server _server; + private LocalConnector _connector; + private LocalConnector _connectorS; + private SimpleSessionHandler _sessionHandler; + private SecurityHandler _securityHandler; + + @BeforeEach + public void configureServer() + { + _server = new Server(); + + HttpConnectionFactory http = new HttpConnectionFactory(); + http.getHttpConfiguration().setSecurePort(9999); + http.getHttpConfiguration().setSecureScheme("BWTP"); + _connector = new LocalConnector(_server, http); + _connector.setIdleTimeout(300000); + + HttpConnectionFactory https = new HttpConnectionFactory(); + https.getHttpConfiguration().addCustomizer((request, responseHeaders) -> + { + HttpURI.Mutable uri = HttpURI.build(request.getHttpURI()).scheme(HttpScheme.HTTPS); + return new Request.Wrapper(request) + { + @Override + public HttpURI getHttpURI() + { + return uri; + } + + @Override + public boolean isSecure() + { + return true; + } + }; + }); + + _connectorS = new LocalConnector(_server, https); + _server.setConnectors(new Connector[]{_connector, _connectorS}); + + ContextHandler contextHandler = new ContextHandler(); + _sessionHandler = new SimpleSessionHandler(); + + contextHandler.setContextPath("/ctx"); + _server.setHandler(contextHandler); + contextHandler.setHandler(_sessionHandler); + + _securityHandler = new SecurityHandler() + { + @Override + protected Constraint getConstraint(String pathInContext, Request request) + { + return null; + } + }; + _sessionHandler.setHandler(_securityHandler); + + _securityHandler.setHandler(new TestHandler()); + } + + @AfterEach + public void stopServer() throws Exception + { + if (_server.isRunning()) + { + _server.stop(); + _server.join(); + } + } + + @Test + public void testIntegral() throws Exception + { + _server.start(); + + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, Matchers.containsString("HTTP/1.1 404 Not Found")); + + response = _connector.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); + assertThat(response, Matchers.containsString("HTTP/1.1 302 Found")); + assertThat(response, Matchers.containsString("Location: BWTP://")); + assertThat(response, Matchers.containsString(":9999")); + + response = _connectorS.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); + assertThat(response, Matchers.containsString("HTTP/1.1 404 Not Found")); + } + + public static class TestHandler extends Handler.Abstract + { + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain; charset=UTF-8"); + Response.writeError(request, response, callback, HttpStatus.NOT_FOUND_404); + return true; + } + } + + private class CustomLoginService implements LoginService + { + private IdentityService identityService; + + public CustomLoginService(IdentityService identityService) + { + this.identityService = identityService; + } + + @Override + public String getName() + { + return "name"; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + if ("admin".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, null, new String[]{"admin"}); + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + return false; + } + + @Override + public IdentityService getIdentityService() + { + return identityService; + } + + @Override + public void setIdentityService(IdentityService service) + { + } + + @Override + public void logout(UserIdentity user) + { + } + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java new file mode 100644 index 000000000000..08bd3b7b14f2 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/TestLoginService.java @@ -0,0 +1,49 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.List; + +import org.eclipse.jetty.util.security.Credential; + +/** + * TestLoginService + */ +public class TestLoginService extends AbstractLoginService +{ + + UserStore userStore = new UserStore(); + + public TestLoginService(String name) + { + setName(name); + } + + public void putUser(String username, Credential credential, String[] roles) + { + userStore.addUser(username, credential, roles); + } + + @Override + protected List loadRoleInfo(UserPrincipal user) + { + return userStore.getRolePrincipals(user.getName()); + } + + @Override + protected UserPrincipal loadUserInfo(String username) + { + return userStore.getUserPrincipal(username); + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java new file mode 100644 index 000000000000..be303b0dc912 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/UserStoreTest.java @@ -0,0 +1,56 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.List; + +import org.eclipse.jetty.util.security.Credential; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +public class UserStoreTest +{ + UserStore userStore; + + @BeforeEach + public void setup() + { + userStore = new UserStore(); + } + + @Test + public void addUser() + { + userStore.addUser("foo", Credential.getCredential("beer"), new String[]{"pub"}); + assertNotNull(userStore.getUserPrincipal("foo")); + + List rps = userStore.getRolePrincipals("foo"); + assertNotNull(rps); + assertNotNull(rps.get(0)); + assertEquals("pub", rps.get(0).getName()); + } + + @Test + public void removeUser() + { + this.userStore.addUser("foo", Credential.getCredential("beer"), new String[]{"pub"}); + assertNotNull(userStore.getUserPrincipal("foo")); + userStore.removeUser("foo"); + assertNull(userStore.getUserPrincipal("foo")); + } +} diff --git a/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/ManagedSession.java b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/ManagedSession.java index a58c3d175675..efc313d60c6b 100644 --- a/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/ManagedSession.java +++ b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/ManagedSession.java @@ -49,6 +49,7 @@ public class ManagedSession implements Session /** * Attribute set if the session is secure */ + @Deprecated public static final String SESSION_CREATED_SECURE = "org.eclipse.jetty.security.sessionCreatedSecure"; /** diff --git a/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java similarity index 78% rename from jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java rename to jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java index 79dc2b37ddc0..468fdd912b90 100644 --- a/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java +++ b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java @@ -13,7 +13,6 @@ package org.eclipse.jetty.session; -import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.jetty.http.HttpCookie; @@ -25,7 +24,7 @@ import org.eclipse.jetty.util.Callback; /** - * SimpleSessionHandler example + * A simple core SessionHandler */ public class SimpleSessionHandler extends AbstractSessionManager implements Handler.Singleton { @@ -77,10 +76,10 @@ public ManagedSession getManagedSession(Request request) @Override public Session.API newSessionAPIWrapper(ManagedSession session) { - return new SessionAPI(session); + return null; } - public class SessionRequest extends Request.Wrapper + private class SessionRequest extends Request.Wrapper { private final AtomicReference _session = new AtomicReference<>(); private String _requestedSessionId; @@ -140,50 +139,4 @@ public boolean process(Handler handler, Response response, Callback callback) th return handler.handle(this, _response, callback); } } - - public static class SessionAPI implements Session.API - { - private final Session _session; - - public SessionAPI(Session session) - { - _session = session; - } - - @Override - public Session getSession() - { - return _session; - } - - public String getId() - { - return _session.getId(); - } - - public Set getAttributeNames() - { - return _session.getAttributeNameSet(); - } - - public Object getAttribute(String name) - { - return _session.getAttribute(name); - } - - public void setAttribute(String name, Object value) - { - _session.setAttribute(name, value); - } - - public void invalidate() - { - _session.invalidate(); - } - - public void renewId(Request request, Response response) - { - _session.renewId(request, response); - } - } } diff --git a/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java b/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java index 804de4bb5160..1d13b7f7b78a 100644 --- a/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java +++ b/jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java @@ -22,8 +22,6 @@ import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Session; -import org.eclipse.jetty.session.SimpleSessionHandler.SessionAPI; -import org.eclipse.jetty.session.SimpleSessionHandler.SessionRequest; import org.eclipse.jetty.util.Callback; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -67,9 +65,7 @@ public boolean handle(Request request, Response response, Callback callback) String pathInContext = Request.getPathInContext(request); String[] split = pathInContext.substring(1).split("/"); - SessionRequest sessionRequest = Request.as(request, SessionRequest.class); - Session session = sessionRequest.getSession(false); - SessionAPI api = session == null ? null : session.getApi(); + Session session = request.getSession(false); if (split.length > 0) { @@ -106,7 +102,7 @@ public boolean handle(Request request, Response response, Callback callback) callback.failed(new IllegalStateException("Session already created")); return true; } - session = sessionRequest.getSession(true); + session = request.getSession(true); } case "invalidate" -> @@ -126,7 +122,7 @@ public boolean handle(Request request, Response response, Callback callback) callback.failed(new IllegalStateException("No Session")); return true; } - api.renewId(request, response); + session.renewId(request, response); } } } From dde878032a4c7f6c1693ad36b3bf8281ac79a675 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 22 Feb 2023 17:14:58 +1100 Subject: [PATCH 003/129] BASIC auth working --- jetty-core/jetty-security/pom.xml | 17 ++ .../src/main/java/module-info.java | 3 +- .../eclipse/jetty/security/Authenticator.java | 11 +- .../eclipse/jetty/security/Constraint.java | 248 +++++++----------- .../jetty/security/SecurityHandler.java | 180 ++++++++----- .../jetty/security/UserDataConstraint.java | 38 --- .../authentication/BasicAuthenticator.java | 6 +- .../ClientCertAuthenticator.java | 7 - .../ConfigurableSpnegoAuthenticator.java | 7 - .../authentication/DigestAuthenticator.java | 7 - .../authentication/FormAuthenticator.java | 6 - .../authentication/LoginAuthenticator.java | 6 - .../SslClientCertAuthenticator.java | 7 - .../security/DefaultIdentityServiceTest.java | 7 +- .../jetty/security/HashLoginServiceTest.java | 6 +- .../jetty/security/SecurityHandlerTest.java | 184 +++++++++++-- .../src/test/resources/user.properties | 2 + .../jetty/util/security/Constraint.java | 2 + 18 files changed, 401 insertions(+), 343 deletions(-) delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java create mode 100644 jetty-core/jetty-security/src/test/resources/user.properties diff --git a/jetty-core/jetty-security/pom.xml b/jetty-core/jetty-security/pom.xml index 836798298ec6..894a17b1d80c 100644 --- a/jetty-core/jetty-security/pom.xml +++ b/jetty-core/jetty-security/pom.xml @@ -15,6 +15,22 @@ org.eclipse.jetty.security.* + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} + ${jetty.surefire.argLine} + --add-reads org.eclipse.jetty.security=org.eclipse.jetty.logging + + + + + + org.eclipse.jetty @@ -45,4 +61,5 @@ test + diff --git a/jetty-core/jetty-security/src/main/java/module-info.java b/jetty-core/jetty-security/src/main/java/module-info.java index 49226888cd7c..08e37b55aff4 100644 --- a/jetty-core/jetty-security/src/main/java/module-info.java +++ b/jetty-core/jetty-security/src/main/java/module-info.java @@ -11,8 +11,9 @@ // ======================================================================== // -module org.eclipse.jetty.session +module org.eclipse.jetty.security { + uses org.eclipse.jetty.security.Authenticator.Factory; requires transitive org.eclipse.jetty.server; requires transitive org.eclipse.jetty.util; requires transitive org.slf4j; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index f4643e10933c..036e852a2a90 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -59,7 +59,10 @@ public interface Authenticator * * @param request the request to prepare for authentication */ - Request prepareRequest(Request request); + default Request prepareRequest(Request request) + { + return request; + } /** * Validate a request @@ -87,7 +90,11 @@ public interface Authenticator * @return true if response is secure * @throws ServerAuthException if unable to test response */ - boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException; + @Deprecated + default boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + { + return true; + } /** * Authenticator Configuration diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 51a14ca847f3..3610ad1b0a10 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -14,7 +14,11 @@ package org.eclipse.jetty.security; import java.util.Arrays; -import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * A Security Constraint interface. @@ -23,40 +27,103 @@ public interface Constraint { boolean isForbidden(); - boolean isAuthenticationMandatory(); - - UserDataConstraint getUserDataConstraint(); + UserData getUserData(); Authorization getAuthorization(); - Collection getRoles(); + Set getRoles(); + + enum UserData + { + NONE, + INTEGRAL, + CONFIDENTIAL; + + static UserData combine(UserData a, UserData b) + { + if (a == null) + return b == null ? NONE : b; + if (b == null) + return a; + + return switch (b) + { + case NONE -> a; + case INTEGRAL -> a == CONFIDENTIAL ? CONFIDENTIAL : INTEGRAL; + case CONFIDENTIAL -> CONFIDENTIAL; + }; + } + } enum Authorization { + NONE, AUTHENTICATED, AUTHENTICATED_IN_KNOWN_ROLE, - AUTHENTICATED_IN_ROLE, + AUTHENTICATED_IN_ROLE; + + static Authorization combine(Authorization a, Authorization b) + { + if (a == null) + return b == null ? NONE : b; + if (b == null) + return a; + + return switch (b) + { + case NONE -> a; + case AUTHENTICATED -> a == NONE ? AUTHENTICATED : a; + case AUTHENTICATED_IN_KNOWN_ROLE -> a == AUTHENTICATED_IN_ROLE ? AUTHENTICATED_IN_ROLE : AUTHENTICATED_IN_KNOWN_ROLE; + case AUTHENTICATED_IN_ROLE -> AUTHENTICATED_IN_ROLE; + }; + } } Constraint NONE = null; - Constraint INTEGRAL = from(false, true, UserDataConstraint.Integral, null); - Constraint CONFIDENTAL = from(false, true, UserDataConstraint.Confidential, null); - Constraint AUTHENTICATED = from(false, true, null, Authorization.AUTHENTICATED); - Constraint AUTHENTICATED_IN_KNOWN_ROLE = from(false, true, null, Authorization.AUTHENTICATED_IN_KNOWN_ROLE); + Constraint FORBIDDEN = from(true, null, null); + Constraint INTEGRAL = from(false, UserData.INTEGRAL, null); + Constraint CONFIDENTIAL = from(false, UserData.CONFIDENTIAL, null); + Constraint AUTHENTICATED = from(false, null, Authorization.AUTHENTICATED); + Constraint AUTHENTICATED_IN_KNOWN_ROLE = from(false, null, Authorization.AUTHENTICATED_IN_KNOWN_ROLE); - static Constraint combine(Constraint... constraints) + static Constraint combine(Constraint a, Constraint b) { - // TODO - return null; + if (a == null) + return b == null ? NONE : b; + if (b == null) + return a; + + Set roles = a.getRoles(); + if (roles == null) + roles = b.getRoles(); + else if (b.getRoles() != null || b.getRoles() != null) + roles = Stream.concat(roles.stream(), b.getRoles().stream()).collect(Collectors.toSet()); + + return from( + a.isForbidden() || b.isForbidden(), + UserData.combine(a.getUserData(), b.getUserData()), + Authorization.combine(a.getAuthorization(), b.getAuthorization()), + roles); } - static Constraint from(String... roles) + static Constraint roles(String... roles) { - return from(false, true, null, Authorization.AUTHENTICATED_IN_ROLE, roles); + return from(false, null, Authorization.AUTHENTICATED_IN_ROLE, roles); } - static Constraint from(boolean forbidden, boolean authMandatory, UserDataConstraint userDataConstraint, Authorization authorization, String... roles) + static Constraint from(boolean forbidden, UserData userData, Authorization authorization, String... roles) { + return from(forbidden, userData, authorization, (roles == null || roles.length == 0) + ? Collections.emptySet() + : new HashSet<>(Arrays.stream(roles).toList())); + } + + static Constraint from(boolean forbidden, UserData userData, Authorization authorization, Set roles) + { + Set roleSet = roles == null + ? Collections.emptySet() + : Collections.unmodifiableSet(roles); + return new Constraint() { @Override @@ -66,162 +133,23 @@ public boolean isForbidden() } @Override - public boolean isAuthenticationMandatory() + public UserData getUserData() { - return authMandatory; - } - - @Override - public UserDataConstraint getUserDataConstraint() - { - return userDataConstraint; + return userData == null ? UserData.NONE : userData; } @Override public Authorization getAuthorization() { - return authorization; + return authorization == null ? Authorization.NONE : authorization; } @Override - public Collection getRoles() + public Set getRoles() { - return Arrays.asList(roles); + return roleSet; } }; } } -/* -{ - private boolean _isAnyAuth; - private boolean _isAnyRole; - private boolean _mandatory; - private boolean _forbidden; - private UserDataConstraint _userDataConstraint; - - private final Set _roles = new CopyOnWriteArraySet<>(); - - public Constraint() - { - } - - public boolean isMandatory() - { - return _mandatory; - } - - public void setMandatory(boolean mandatory) - { - this._mandatory = mandatory; - if (!mandatory) - { - _forbidden = false; - _roles.clear(); - _isAnyRole = false; - _isAnyAuth = false; - } - } - - public boolean isForbidden() - { - return _forbidden; - } - - public void setForbidden(boolean forbidden) - { - this._forbidden = forbidden; - if (forbidden) - { - _mandatory = true; - _userDataConstraint = null; - _isAnyRole = false; - _isAnyAuth = false; - _roles.clear(); - } - } - - public boolean isAnyRole() - { - return _isAnyRole; - } - - public void setAnyRole(boolean anyRole) - { - this._isAnyRole = anyRole; - if (anyRole) - _mandatory = true; - } - - public boolean isAnyAuth() - { - return _isAnyAuth; - } - - public void setAnyAuth(boolean anyAuth) - { - this._isAnyAuth = anyAuth; - if (anyAuth) - _mandatory = true; - } - - public UserDataConstraint getUserDataConstraint() - { - return _userDataConstraint; - } - - public void setUserDataConstraint(UserDataConstraint userDataConstraint) - { - if (userDataConstraint == null) - throw new NullPointerException("Null UserDataConstraint"); - if (this._userDataConstraint == null) - { - - this._userDataConstraint = userDataConstraint; - } - else - { - this._userDataConstraint = this._userDataConstraint.combine(userDataConstraint); - } - } - - public Set getRoles() - { - return _roles; - } - - public void addRole(String role) - { - _roles.add(role); - } - - public void combine(Constraint other) - { - if (other._forbidden) - setForbidden(true); - else if (other._mandatory) - { - setMandatory(true); - if (other._isAnyAuth) - setAnyAuth(true); - if (other._isAnyRole) - setAnyRole(true); - - _roles.addAll(other._roles); - } - setUserDataConstraint(other._userDataConstraint); - } - - @Override - public String toString() - { - return String.format("RoleInfo@%x{%s%s%s%s,%s}", - hashCode(), - (_forbidden ? "Forbidden," : ""), - (_mandatory ? "Checked," : ""), - (_isAnyAuth ? "AnyAuth," : ""), - (_isAnyRole ? "*" : _roles), - _userDataConstraint); - } - - */ diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index e94d45785a5d..90e5a8003d9f 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.ServiceLoader; @@ -25,6 +26,9 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.pathmap.MappedResource; +import org.eclipse.jetty.http.pathmap.PathMappings; +import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Handler; @@ -403,14 +407,19 @@ public boolean handle(Request request, Response response, Callback callback) thr return next.handle(request, response, callback); } - // Check data constraints - if (!checkUserDataConstraint(pathInContext, request, response, callback, constraint)) + if (constraint.isForbidden()) + { + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); return true; + } + // Check data constraints + if (!checkUserData(pathInContext, request, response, callback, constraint)) + return true; // is Auth mandatory? - boolean isAuthenticationMandatory = constraint.isAuthenticationMandatory(); - if (isAuthenticationMandatory && authenticator == null) + boolean authMandatory = constraint.getAuthorization() != null && constraint.getAuthorization() != Constraint.Authorization.NONE; + if (authMandatory && authenticator == null) { LOG.warn("No authenticator for: {}", constraint); Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); @@ -425,7 +434,7 @@ public boolean handle(Request request, Response response, Callback callback) thr if (authentication == null || authentication == Authentication.NOT_CHECKED) authentication = authenticator == null ? Authentication.UNAUTHENTICATED - : authenticator.validateRequest(request, response, callback, isAuthenticationMandatory); + : authenticator.validateRequest(request, response, callback, authMandatory); if (authentication instanceof Authentication.ResponseSent) return true; @@ -436,7 +445,7 @@ public boolean handle(Request request, Response response, Callback callback) thr if (_identityService != null) previousIdentity = _identityService.associate(userAuth.getUserIdentity()); - if (isAuthenticationMandatory) + if (authMandatory) { boolean authorized = checkAuthorization(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); if (!authorized) @@ -448,9 +457,10 @@ public boolean handle(Request request, Response response, Callback callback) thr //process the request by other handlers boolean processed = next.handle(request, response, callback); + // TODO this looks wrong as in way too late if (processed && authenticator != null) - authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, userAuth); + authenticator.secureResponse(request, response, callback, authMandatory, userAuth); return processed; } @@ -473,14 +483,14 @@ public boolean handle(Request request, Response response, Callback callback) thr { Authentication auth = Authentication.getAuthentication(request); if (auth instanceof Authentication.User userAuth) - authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, userAuth); + authenticator.secureResponse(request, response, callback, authMandatory, userAuth); else - authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, null); + authenticator.secureResponse(request, response, callback, authMandatory, null); } return handled; } - if (isAuthenticationMandatory) + if (authMandatory) { Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401, "unauthenticated"); return true; @@ -494,7 +504,7 @@ public boolean handle(Request request, Response response, Callback callback) thr boolean handled = next.handle(request, response, callback); if (handled && authenticator != null) - authenticator.secureResponse(request, response, callback, isAuthenticationMandatory, null); + authenticator.secureResponse(request, response, callback, authMandatory, null); return handled; } catch (ServerAuthException e) @@ -542,80 +552,65 @@ public void logout(Authentication.User user) protected abstract Constraint getConstraint(String pathInContext, Request request); - protected boolean checkUserDataConstraint(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException + protected boolean checkUserData(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException { - if (constraint == null) + Constraint.UserData dataConstraint = constraint.getUserData(); + if (dataConstraint == null || dataConstraint == Constraint.UserData.NONE) return true; - if (constraint.isForbidden()) - { - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); - return false; - } + HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); - UserDataConstraint dataConstraint = constraint.getUserDataConstraint(); - if (dataConstraint == null || dataConstraint == UserDataConstraint.None) + if (request.isSecure()) return true; - HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); - - if (dataConstraint == UserDataConstraint.Confidential || dataConstraint == UserDataConstraint.Integral) + if (httpConfig.getSecurePort() > 0) { - if (request.isSecure()) - return true; - - if (httpConfig.getSecurePort() > 0) - { - //Redirect to secure port - String scheme = httpConfig.getSecureScheme(); - int port = httpConfig.getSecurePort(); + //Redirect to secure port + String scheme = httpConfig.getSecureScheme(); + int port = httpConfig.getSecurePort(); - String url = URIUtil.newURI(scheme, Request.getServerName(request), port, request.getHttpURI().getPath(), request.getHttpURI().getQuery()); - response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); + String url = URIUtil.newURI(scheme, Request.getServerName(request), port, request.getHttpURI().getPath(), request.getHttpURI().getQuery()); + response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); - Response.sendRedirect(request, response, callback, HttpStatus.MOVED_TEMPORARILY_302, url, true); - } - else - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); - return false; + Response.sendRedirect(request, response, callback, HttpStatus.MOVED_TEMPORARILY_302, url, true); } else { - throw new IllegalArgumentException("Invalid dataConstraint value: " + dataConstraint); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); } + return false; } protected boolean checkAuthorization(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) { - Constraint.Authorization authorization = constraint.getAuthorization(); if (authorization == null) return true; - switch (constraint.getAuthorization()) + return switch (constraint.getAuthorization()) { - case AUTHENTICATED: - return userIdentity.getUserPrincipal() != null; + case NONE -> true; - case AUTHENTICATED_IN_KNOWN_ROLE: - if (userIdentity.getUserPrincipal() == null) - return false; - for (String role : getKnownRoles()) - if (userIdentity.isUserInRole(role)) - return true; - return false; + case AUTHENTICATED -> userIdentity.getUserPrincipal() != null; - case AUTHENTICATED_IN_ROLE: - if (userIdentity.getUserPrincipal() == null) - return false; - for (String role : constraint.getRoles()) - if (userIdentity.isUserInRole(role)) - return true; - return false; + case AUTHENTICATED_IN_KNOWN_ROLE -> + { + if (userIdentity.getUserPrincipal() != null) + for (String role : getKnownRoles()) + if (userIdentity.isUserInRole(role)) + yield true; + yield false; + } - default: - return false; - } + case AUTHENTICATED_IN_ROLE -> + { + if (userIdentity.getUserPrincipal() != null) + for (String role : constraint.getRoles()) + if (userIdentity.isUserInRole(role)) + yield true; + yield false; + } + }; } protected Set getKnownRoles() @@ -680,4 +675,69 @@ public String toString() return getName(); } }; + + public static class Mapped extends SecurityHandler + { + private final PathMappings _mappings = new PathMappings<>(); + private final Set _knownRoles = new HashSet<>(); + + public Mapped() + { + } + + public Constraint add(String pathSpec, Constraint constraint) + { + return add(PathSpec.from(pathSpec), constraint); + } + + public Constraint add(PathSpec pathSpec, Constraint constraint) + { + Set roles = constraint.getRoles(); + if (roles != null) + _knownRoles.addAll(roles); + return _mappings.put(pathSpec, constraint); + } + + public Constraint get(PathSpec pathSpec) + { + return _mappings.get(pathSpec); + } + + public Constraint remove(PathSpec pathSpec) + { + Constraint removed = _mappings.remove(pathSpec); + _knownRoles.clear(); + _mappings.values().forEach(c -> + { + Set roles = c.getRoles(); + if (roles != null) + _knownRoles.addAll(roles); + + }); + return removed; + } + + @Override + protected Constraint getConstraint(String pathInContext, Request request) + { + List> matches = _mappings.getMatches(pathInContext); + if (matches == null || matches.isEmpty()) + return null; + + if (matches.size() == 1) + return matches.get(0).getResource(); + + Constraint constraint = null; + for (MappedResource c : matches) + constraint = Constraint.combine(constraint, c.getResource()); + + return constraint; + } + + @Override + protected Set getKnownRoles() + { + return _knownRoles; + } + } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java deleted file mode 100644 index 1650761186f0..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserDataConstraint.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security; - -/** - * @version $Rev: 4466 $ $Date: 2009-02-10 23:42:54 +0100 (Tue, 10 Feb 2009) $ - */ -public enum UserDataConstraint -{ - None, Integral, Confidential; - - public static UserDataConstraint get(int dataConstraint) - { - if (dataConstraint < -1 || dataConstraint > 2) - throw new IllegalArgumentException("Expected -1, 0, 1, or 2, not: " + dataConstraint); - if (dataConstraint == -1) - return None; - return values()[dataConstraint]; - } - - public UserDataConstraint combine(UserDataConstraint other) - { - if (this.compareTo(other) < 0) - return this; - return other; - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index 0b2d1524c1d5..b41fe67cfb7e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -20,7 +20,6 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -96,9 +95,8 @@ public Authentication validateRequest(Request req, Response res, Callback callba return Authentication.SEND_CONTINUE; } - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException + public static String authorization(String user, String password) { - return true; + return "basic " + Base64.getEncoder().encodeToString((user + ":" + password).getBytes(StandardCharsets.ISO_8859_1)); } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java index 63171e87740d..de923088e912 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java @@ -22,7 +22,6 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -196,12 +195,6 @@ protected Collection loadCRL(String crlPath) throws Exception return CertificateUtils.loadCRL(crlPath); } - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException - { - return true; - } - /** * @return true if SSL certificate has to be validated */ diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index 7304e3edc75e..796c0a7ed0f3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -21,7 +21,6 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.ConfigurableSpnegoLoginService; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.SpnegoUserIdentity; @@ -210,12 +209,6 @@ private String getSpnegoToken(String header) return null; } - @Override - public boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) - { - return true; - } - private static class UserIdentityHolder implements Serializable { private static final String ATTRIBUTE = UserIdentityHolder.class.getName(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index c05259f9971c..8394a7e807ee 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -27,7 +27,6 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; @@ -97,12 +96,6 @@ public String getAuthMethod() return Constraint.__DIGEST_AUTH; } - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException - { - return true; - } - @Override public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index dbf592e733d4..ceb5170e36d3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -406,12 +406,6 @@ public boolean isLoginOrErrorPage(String pathInContext) { return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath)); } - - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException - { - return true; - } //TODO reinstate use of forward dispatch /* diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index d647d876730e..50ce2b24cf5d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -36,12 +36,6 @@ protected LoginAuthenticator() { } - @Override - public Request prepareRequest(Request request) - { - return request; - } - /** * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, Request)}, it * is assumed that the user is fully authenticated and we need to change the session id to prevent diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java index 9e5c0db90dd6..b97d1930be15 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -20,7 +20,6 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; @@ -129,12 +128,6 @@ public Authentication validateRequest(Request req, Response res, Callback callba } } - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException - { - return true; - } - /** * @return true if SSL certificate has to be validated. */ diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java index 3d7baa988561..86811af49e7f 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java @@ -28,7 +28,7 @@ public class DefaultIdentityServiceTest public void testDefaultIdentityService() throws Exception { Server server = new Server(); - SecurityHandler securityHandler = new SecurityHandler(); + SecurityHandler securityHandler = new SecurityHandler.Mapped(); TestAuthenticator authenticator = new TestAuthenticator(); securityHandler.setAuthenticator(authenticator); @@ -68,11 +68,6 @@ public String getAuthMethod() return getClass().getSimpleName(); } - @Override - public Request prepareRequest(Request request) - { - } - @Override public Authentication validateRequest(Request request, Response response, Callback callback, boolean mandatory) throws ServerAuthException { diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java index 4331fc8b9631..0f5ea0a17a63 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/HashLoginServiceTest.java @@ -51,9 +51,9 @@ public void afterEach() @Test public void testAutoCreatedUserStore() throws Exception { - Path fooPropsFile = MavenTestingUtils.getTestResourcePathFile("foo.properties"); + Path fooPropsFile = MavenTestingUtils.getTestResourcePathFile("user.properties"); Resource fooResource = ResourceFactory.root().newResource(fooPropsFile); - HashLoginService loginService = new HashLoginService("foo", fooResource); + HashLoginService loginService = new HashLoginService("users", fooResource); assertThat(loginService.getIdentityService(), is(notNullValue())); loginService.start(); assertTrue(loginService.getUserStore().isStarted()); @@ -67,7 +67,7 @@ public void testAutoCreatedUserStore() throws Exception @Test public void testProvidedUserStore() throws Exception { - HashLoginService loginService = new HashLoginService("foo"); + HashLoginService loginService = new HashLoginService("users"); assertThat(loginService.getIdentityService(), is(notNullValue())); UserStore store = new UserStore(); loginService.setUserStore(store); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index e3463fb5ebf6..6623c8970bc2 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -13,12 +13,14 @@ package org.eclipse.jetty.security; -import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpScheme; -import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; @@ -27,12 +29,13 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.session.SimpleSessionHandler; import org.eclipse.jetty.util.Callback; -import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; public class SecurityHandlerTest { @@ -40,16 +43,20 @@ public class SecurityHandlerTest private LocalConnector _connector; private LocalConnector _connectorS; private SimpleSessionHandler _sessionHandler; - private SecurityHandler _securityHandler; + private SecurityHandler.Mapped _securityHandler; @BeforeEach - public void configureServer() + public void configureServer() throws Exception { _server = new Server(); + _server.addBean(new CustomLoginService(new DefaultIdentityService())); + HttpConnectionFactory http = new HttpConnectionFactory(); - http.getHttpConfiguration().setSecurePort(9999); - http.getHttpConfiguration().setSecureScheme("BWTP"); + HttpConfiguration httpConfiguration = http.getHttpConfiguration(); + httpConfiguration.setSecurePort(9999); + httpConfiguration.setSecureScheme("BWTP"); + httpConfiguration.addCustomizer(new ForwardedRequestCustomizer()); _connector = new LocalConnector(_server, http); _connector.setIdleTimeout(300000); @@ -83,17 +90,10 @@ public boolean isSecure() _server.setHandler(contextHandler); contextHandler.setHandler(_sessionHandler); - _securityHandler = new SecurityHandler() - { - @Override - protected Constraint getConstraint(String pathInContext, Request request) - { - return null; - } - }; + _securityHandler = new SecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); - _securityHandler.setHandler(new TestHandler()); + _securityHandler.setHandler(new OkHandler()); } @AfterEach @@ -107,37 +107,161 @@ public void stopServer() throws Exception } @Test - public void testIntegral() throws Exception + public void testNoConstraints() throws Exception + { + _server.start(); + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + } + + @Test + public void testForbidden() throws Exception + { + _securityHandler.add("/secret/*", Constraint.FORBIDDEN); + _server.start(); + + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + + response = _connector.getResponse("GET /ctx/secret/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, not(containsString("You are OK"))); + } + + @Test + public void testUserData() throws Exception { + _securityHandler.add("/integral/*", Constraint.INTEGRAL); + _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); _server.start(); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); - assertThat(response, Matchers.containsString("HTTP/1.1 404 Not Found")); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); response = _connector.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); - assertThat(response, Matchers.containsString("HTTP/1.1 302 Found")); - assertThat(response, Matchers.containsString("Location: BWTP://")); - assertThat(response, Matchers.containsString(":9999")); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: BWTP://")); + assertThat(response, containsString(":9999")); + assertThat(response, not(containsString("You are OK"))); + + response = _connectorS.getResponse("GET /ctx/integral/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("UNAUTHENTICATED is not OK")); + + response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: BWTP://")); + assertThat(response, containsString(":9999")); + assertThat(response, not(containsString("You are OK"))); + + response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("UNAUTHENTICATED is not OK")); + } + + @Test + public void testCombinedForbiddenConfidential() throws Exception + { + _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); + _securityHandler.add("*.hidden", Constraint.FORBIDDEN); + _server.start(); + + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + + response = _connector.getResponse("GET /ctx/something.hidden HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, not(containsString("You are OK"))); + + response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: BWTP://")); + assertThat(response, containsString(":9999")); + assertThat(response, not(containsString("You are OK"))); + + response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("UNAUTHENTICATED is not OK")); + + response = _connectorS.getResponse("GET /ctx/confidential/info.hidden HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, not(containsString("You are OK"))); + } + + @Test + public void testBasic() throws Exception + { + _securityHandler.add("/admin/*", Constraint.roles("admin")); + _securityHandler.add("/any/*", Constraint.AUTHENTICATED); + _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); + _securityHandler.setAuthenticator(new BasicAuthenticator()); + _server.start(); + + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + assertThat(response, not(containsString("You are OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("wrong", "user"))); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + assertThat(response, not(containsString("You are OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("user is OK")); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("admin is OK")); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("admin is OK")); - response = _connectorS.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); - assertThat(response, Matchers.containsString("HTTP/1.1 404 Not Found")); + response = _connector.getResponse("GET /ctx/known/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); } - public static class TestHandler extends Handler.Abstract + public static class OkHandler extends Handler.Abstract { @Override public boolean handle(Request request, Response response, Callback callback) throws Exception { - response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain; charset=UTF-8"); - Response.writeError(request, response, callback, HttpStatus.NOT_FOUND_404); + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication user) + Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); + else if (authentication instanceof Authentication.Deferred) + Content.Sink.write(response, true, "Somebody might be OK", callback); + else if (authentication == null) + Content.Sink.write(response, true, "You are OK", callback); + else + Content.Sink.write(response, true, authentication + " is not OK", callback); return true; } } - private class CustomLoginService implements LoginService + private static class CustomLoginService implements LoginService { - private IdentityService identityService; + private final IdentityService identityService; public CustomLoginService(IdentityService identityService) { @@ -154,7 +278,9 @@ public String getName() public UserIdentity login(String username, Object credentials, Request request) { if ("admin".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, null, new String[]{"admin"}); + return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); + if ("user".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); return null; } diff --git a/jetty-core/jetty-security/src/test/resources/user.properties b/jetty-core/jetty-security/src/test/resources/user.properties new file mode 100644 index 000000000000..aee03ecb84b4 --- /dev/null +++ b/jetty-core/jetty-security/src/test/resources/user.properties @@ -0,0 +1,2 @@ +ken=123 +amy=456 diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java index 5c977e890c2f..6aee16da9cbb 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java @@ -20,7 +20,9 @@ * Constraint * * Describe an auth and/or data constraint. + * TODO remove */ +@Deprecated public class Constraint implements Cloneable, Serializable { From 7ff7d8901948fec85cea5796ab6f16b1e310d181 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 22 Feb 2023 23:14:58 +1100 Subject: [PATCH 004/129] FORM auth working --- .../eclipse/jetty/security/Constraint.java | 2 +- .../jetty/security/IdentityService.java | 2 +- .../authentication/FormAuthenticator.java | 41 ++- .../authentication/SessionAuthentication.java | 2 +- .../security/BasicAuthenticatorTest.java | 219 +++++++++++ .../jetty/security/FormAuthenticatorTest.java | 347 ++++++++++++++++++ .../jetty/security/SecurityHandlerTest.java | 116 +----- .../org/eclipse/jetty/server/FormFields.java | 2 +- .../org/eclipse/jetty/server/Request.java | 5 +- .../java/org/eclipse/jetty/util/Fields.java | 8 + 10 files changed, 616 insertions(+), 128 deletions(-) create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 3610ad1b0a10..5abdffbb68c7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -79,7 +79,7 @@ static Authorization combine(Authorization a, Authorization b) } } - Constraint NONE = null; + Constraint NONE = from(false, UserData.NONE, Authorization.NONE); Constraint FORBIDDEN = from(true, null, null); Constraint INTEGRAL = from(false, UserData.INTEGRAL, null); Constraint CONFIDENTIAL = from(false, UserData.CONFIDENTIAL, null); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index d06c75cc8ea2..3cded1905302 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -29,7 +29,7 @@ public interface IdentityService /** * Associate a user identity with the current thread. * This is called with as a thread enters the - * {@link Handler#process(Request, org.eclipse.jetty.server.Response, org.eclipse.jetty.util.Callback)} + * {@link Handler#handle(Request, org.eclipse.jetty.server.Response, org.eclipse.jetty.util.Callback)} * method and then again with a null argument as that call exits. * * @param user The current user or null for no user to associated. diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index ceb5170e36d3..50489a536d27 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.security.authentication; +import java.util.concurrent.ExecutionException; + import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; @@ -164,7 +166,7 @@ public UserIdentity login(String username, Object password, Request request, Res { Session session = request.getSession(true); Authentication cached = new SessionAuthentication(getAuthMethod(), user, password); - session.setAttribute(SessionAuthentication.__J_AUTHENTICATED, cached); + session.setAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE, cached); } return user; } @@ -178,7 +180,7 @@ public void logout(Request request) return; //clean up session - session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); } @Override @@ -192,7 +194,7 @@ public Request prepareRequest(Request request) // //See Servlet Spec 3.1 sec 13.6.3 Session session = request.getSession(false); - if (session == null || session.getAttribute(SessionAuthentication.__J_AUTHENTICATED) == null) + if (session == null || session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) return request; //not authenticated yet HttpURI juri = (HttpURI)session.getAttribute(__J_URI); @@ -217,9 +219,26 @@ public Request prepareRequest(Request request) protected Fields getParameters(Request request) { - // TODO: Content parameters? - // TODO: override for servlet so we don't lose content parameters when we read them? - return Request.extractQueryParameters(request); + try + { + Fields queryFields = Request.extractQueryParameters(request); + Fields formFields = FormFields.from(request).get(); + + if (queryFields.isEmpty()) + return formFields; + + if (formFields.isEmpty()) + return Fields.EMPTY; + + Fields fields = new Fields(); + fields.addAll(queryFields); + fields.addAll(formFields); + return fields; + } + catch (InterruptedException | ExecutionException e) + { + throw new RuntimeException(e); + } } protected String encodeURL(String url) @@ -304,7 +323,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba // Look for cached authentication Session session = req.getSession(false); - Authentication authentication = session == null ? null : (Authentication)session.getAttribute(SessionAuthentication.__J_AUTHENTICATED); + Authentication authentication = session == null ? null : (Authentication)session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); if (authentication != null) { // Has authentication been revoked? @@ -313,7 +332,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba !_loginService.validate(((User)authentication).getUserIdentity())) { LOG.debug("auth revoked {}", authentication); - session.removeAttribute(SessionAuthentication.__J_AUTHENTICATED); + session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); } else { @@ -335,10 +354,10 @@ public Authentication validateRequest(Request req, Response res, Callback callba LOG.debug("auth rePOST {}->{}", authentication, jUri); // servletApiRequest.setContentParameters(jPost); } - session.removeAttribute(__J_URI); - session.removeAttribute(__J_METHOD); - session.removeAttribute(__J_POST); } + session.removeAttribute(__J_URI); + session.removeAttribute(__J_METHOD); + session.removeAttribute(__J_POST); } } LOG.debug("auth {}", authentication); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 6af566f2e4c2..2907da77fdc7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -40,7 +40,7 @@ public class SessionAuthentication extends AbstractUserAuthentication private static final long serialVersionUID = -4643200685888258706L; - public static final String __J_AUTHENTICATED = "org.eclipse.jetty.security.UserIdentity"; + public static final String AUTHENTICATED_ATTRIBUTE = "org.eclipse.jetty.security.UserIdentity"; private final String _name; private final Object _credentials; diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java new file mode 100644 index 000000000000..9467883369ff --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -0,0 +1,219 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.ForwardedRequestCustomizer; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.session.SimpleSessionHandler; +import org.eclipse.jetty.util.Callback; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; + +public class BasicAuthenticatorTest +{ + private Server _server; + private LocalConnector _connector; + private LocalConnector _connectorS; + private SimpleSessionHandler _sessionHandler; + private SecurityHandler.Mapped _securityHandler; + + @BeforeEach + public void configureServer() throws Exception + { + _server = new Server(); + + _server.addBean(new CustomLoginService(new DefaultIdentityService())); + + HttpConnectionFactory http = new HttpConnectionFactory(); + HttpConfiguration httpConfiguration = http.getHttpConfiguration(); + httpConfiguration.setSecurePort(9999); + httpConfiguration.setSecureScheme("BWTP"); + httpConfiguration.addCustomizer(new ForwardedRequestCustomizer()); + _connector = new LocalConnector(_server, http); + _connector.setIdleTimeout(300000); + + HttpConnectionFactory https = new HttpConnectionFactory(); + https.getHttpConfiguration().addCustomizer((request, responseHeaders) -> + { + HttpURI.Mutable uri = HttpURI.build(request.getHttpURI()).scheme(HttpScheme.HTTPS); + return new Request.Wrapper(request) + { + @Override + public HttpURI getHttpURI() + { + return uri; + } + + @Override + public boolean isSecure() + { + return true; + } + }; + }); + + _connectorS = new LocalConnector(_server, https); + _server.setConnectors(new Connector[]{_connector, _connectorS}); + + ContextHandler contextHandler = new ContextHandler(); + _sessionHandler = new SimpleSessionHandler(); + + contextHandler.setContextPath("/ctx"); + _server.setHandler(contextHandler); + contextHandler.setHandler(_sessionHandler); + + _securityHandler = new SecurityHandler.Mapped(); + _sessionHandler.setHandler(_securityHandler); + + _securityHandler.setHandler(new OkHandler()); + + _securityHandler.add("/admin/*", Constraint.roles("admin")); + _securityHandler.add("/any/*", Constraint.AUTHENTICATED); + _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); + _securityHandler.setAuthenticator(new BasicAuthenticator()); + _server.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + if (_server.isRunning()) + { + _server.stop(); + _server.join(); + } + } + + @Test + public void testBasic() throws Exception + { + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + assertThat(response, not(containsString("You are OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("wrong", "user"))); + assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); + assertThat(response, not(containsString("You are OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("user is OK")); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("admin is OK")); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("admin is OK")); + + response = _connector.getResponse("GET /ctx/known/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); + } + + public static class OkHandler extends Handler.Abstract + { + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication user) + Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); + else if (authentication instanceof Authentication.Deferred) + Content.Sink.write(response, true, "Somebody might be OK", callback); + else if (authentication == null) + Content.Sink.write(response, true, "You are OK", callback); + else + Content.Sink.write(response, true, authentication + " is not OK", callback); + return true; + } + } + + private static class CustomLoginService implements LoginService + { + private final IdentityService identityService; + + public CustomLoginService(IdentityService identityService) + { + this.identityService = identityService; + } + + @Override + public String getName() + { + return "name"; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + if ("admin".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); + if ("user".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + return false; + } + + @Override + public IdentityService getIdentityService() + { + return identityService; + } + + @Override + public void setIdentityService(IdentityService service) + { + } + + @Override + public void logout(UserIdentity user) + { + } + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java new file mode 100644 index 000000000000..c7233259b388 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -0,0 +1,347 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.FormAuthenticator; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.ForwardedRequestCustomizer; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.session.SimpleSessionHandler; +import org.eclipse.jetty.util.Callback; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; + +public class FormAuthenticatorTest +{ + public static final String SET_COOKIE_JSESSIONID = "Set-Cookie: JSESSIONID="; + private Server _server; + private LocalConnector _connector; + private LocalConnector _connectorS; + private SimpleSessionHandler _sessionHandler; + private SecurityHandler.Mapped _securityHandler; + + @BeforeEach + public void configureServer() throws Exception + { + _server = new Server(); + + _server.addBean(new CustomLoginService(new DefaultIdentityService())); + + HttpConnectionFactory http = new HttpConnectionFactory(); + HttpConfiguration httpConfiguration = http.getHttpConfiguration(); + httpConfiguration.setSecurePort(9999); + httpConfiguration.setSecureScheme("BWTP"); + httpConfiguration.addCustomizer(new ForwardedRequestCustomizer()); + _connector = new LocalConnector(_server, http); + _connector.setIdleTimeout(300000); + + HttpConnectionFactory https = new HttpConnectionFactory(); + https.getHttpConfiguration().addCustomizer((request, responseHeaders) -> + { + HttpURI.Mutable uri = HttpURI.build(request.getHttpURI()).scheme(HttpScheme.HTTPS); + return new Request.Wrapper(request) + { + @Override + public HttpURI getHttpURI() + { + return uri; + } + + @Override + public boolean isSecure() + { + return true; + } + }; + }); + + _connectorS = new LocalConnector(_server, https); + _server.setConnectors(new Connector[]{_connector, _connectorS}); + + ContextHandler contextHandler = new ContextHandler(); + _sessionHandler = new SimpleSessionHandler(); + + contextHandler.setContextPath("/ctx"); + _server.setHandler(contextHandler); + contextHandler.setHandler(_sessionHandler); + + _securityHandler = new SecurityHandler.Mapped(); + _sessionHandler.setHandler(_securityHandler); + + _securityHandler.setHandler(new OkHandler()); + + _securityHandler.add("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed + _securityHandler.add("/any/*", Constraint.AUTHENTICATED); + _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); + _securityHandler.add("/admin/*", Constraint.roles("admin")); + _securityHandler.setAuthenticator(new FormAuthenticator("/login", "/error", false)); + _server.start(); + } + + @AfterEach + public void stopServer() throws Exception + { + if (_server.isRunning()) + { + _server.stop(); + _server.join(); + } + } + + @Test + public void testLoginRedirect() throws Exception + { + String response; + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("You are OK")); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + + response = _connector.getResponse("GET /ctx/known/user HTTP/1.0\r\nHost:host:8888\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nHost:host:8888\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + } + + private static String sessionId(String response) + { + int cookie = response.indexOf(SET_COOKIE_JSESSIONID); + if (cookie < 0) + return null; + int semi = response.indexOf(";", cookie); + return response.substring(cookie + SET_COOKIE_JSESSIONID.length(), semi); + } + + @Test + public void testUseExistingSession() throws Exception + { + String response; + response = _connector.getResponse("GET /ctx/some/thing?createSession=true HTTP/1.0\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + assertThat(response, containsString("You are OK")); + String sessionId = sessionId(response); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + } + + @Test + public void testError() throws Exception + { + String response; + + String sessionId = "unknown"; + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + sessionId = sessionId(response); + + response = _connector.getResponse("GET /ctx/j_security_check?j_username=user&j_password=wrong HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/error")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + + response = _connector.getResponse(""" + POST /ctx/j_security_check HTTP/1.0\r + Host: host:8888\r + Content-Length: 32\r + Content-Type: application/x-www-form-urlencoded\r + Cookie: JSESSIONID=" + sessionId + "\r + \r + j_username=user&j_password=wrong + """); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/error")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + } + + @Test + public void testLoginQuery() throws Exception + { + String response; + + String sessionId = "unknown"; + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + sessionId = sessionId(response); + + response = _connector.getResponse("GET /ctx/j_security_check?j_username=user&j_password=password HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/any/user")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + String unsafeSessionId = sessionId; + sessionId = sessionId(response); + assertThat(sessionId, not(equalTo(unsafeSessionId))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + assertThat(response, containsString("user is OK")); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + unsafeSessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + } + + @Test + public void testLoginForm() throws Exception + { + String response; + + String sessionId = "unknown"; + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + sessionId = sessionId(response); + + response = _connector.getResponse(""" + POST /ctx/j_security_check HTTP/1.0\r + Host: host:8888\r + Content-Length: 35\r + Content-Type: application/x-www-form-urlencoded\r + Cookie: JSESSIONID=%s\r + \r + j_username=user&j_password=password + """.formatted(sessionId)); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/any/user")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + String unsafeSessionId = sessionId; + sessionId = sessionId(response); + assertThat(sessionId, not(equalTo(unsafeSessionId))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + assertThat(response, containsString("user is OK")); + + response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 403 Forbidden")); + assertThat(response, containsString("!role")); + assertThat(response, not(containsString("OK"))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + unsafeSessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + } + + public static class OkHandler extends Handler.Abstract + { + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + if (Boolean.parseBoolean(Request.extractQueryParameters(request).getValue("createSession"))) + request.getSession(true); + + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof Authentication.User user) + Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); + else if (authentication instanceof Authentication.Deferred) + Content.Sink.write(response, true, "Somebody might be OK", callback); + else if (authentication == null) + Content.Sink.write(response, true, "You are OK", callback); + else + Content.Sink.write(response, true, authentication + " is not OK", callback); + return true; + } + } + + private static class CustomLoginService implements LoginService + { + private final IdentityService identityService; + + public CustomLoginService(IdentityService identityService) + { + this.identityService = identityService; + } + + @Override + public String getName() + { + return "name"; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + if ("admin".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); + if ("user".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + return user instanceof DefaultUserIdentity; + } + + @Override + public IdentityService getIdentityService() + { + return identityService; + } + + @Override + public void setIdentityService(IdentityService service) + { + throw new UnsupportedOperationException(); + } + + @Override + public void logout(UserIdentity user) + { + } + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 6623c8970bc2..3d2410925eab 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -16,7 +16,6 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.io.Content; -import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.Handler; @@ -27,7 +26,6 @@ import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.session.SimpleSessionHandler; import org.eclipse.jetty.util.Callback; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -42,7 +40,6 @@ public class SecurityHandlerTest private Server _server; private LocalConnector _connector; private LocalConnector _connectorS; - private SimpleSessionHandler _sessionHandler; private SecurityHandler.Mapped _securityHandler; @BeforeEach @@ -50,8 +47,6 @@ public void configureServer() throws Exception { _server = new Server(); - _server.addBean(new CustomLoginService(new DefaultIdentityService())); - HttpConnectionFactory http = new HttpConnectionFactory(); HttpConfiguration httpConfiguration = http.getHttpConfiguration(); httpConfiguration.setSecurePort(9999); @@ -83,17 +78,12 @@ public boolean isSecure() _connectorS = new LocalConnector(_server, https); _server.setConnectors(new Connector[]{_connector, _connectorS}); - ContextHandler contextHandler = new ContextHandler(); - _sessionHandler = new SimpleSessionHandler(); - - contextHandler.setContextPath("/ctx"); + ContextHandler contextHandler = new ContextHandler("/ctx"); _server.setHandler(contextHandler); - contextHandler.setHandler(_sessionHandler); - _securityHandler = new SecurityHandler.Mapped(); - _sessionHandler.setHandler(_securityHandler); - + contextHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); + _server.start(); } @AfterEach @@ -109,7 +99,6 @@ public void stopServer() throws Exception @Test public void testNoConstraints() throws Exception { - _server.start(); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); @@ -120,7 +109,6 @@ public void testNoConstraints() throws Exception public void testForbidden() throws Exception { _securityHandler.add("/secret/*", Constraint.FORBIDDEN); - _server.start(); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); @@ -137,7 +125,6 @@ public void testUserData() throws Exception { _securityHandler.add("/integral/*", Constraint.INTEGRAL); _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); - _server.start(); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); @@ -168,14 +155,14 @@ public void testUserData() throws Exception @Test public void testCombinedForbiddenConfidential() throws Exception { + _securityHandler.add("/*", Constraint.NONE); _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); _securityHandler.add("*.hidden", Constraint.FORBIDDEN); - _server.start(); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("UNAUTHENTICATED is not OK")); response = _connector.getResponse("GET /ctx/something.hidden HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); @@ -196,51 +183,6 @@ public void testCombinedForbiddenConfidential() throws Exception assertThat(response, not(containsString("You are OK"))); } - @Test - public void testBasic() throws Exception - { - _securityHandler.add("/admin/*", Constraint.roles("admin")); - _securityHandler.add("/any/*", Constraint.AUTHENTICATED); - _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); - _securityHandler.setAuthenticator(new BasicAuthenticator()); - _server.start(); - - String response; - response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); - assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); - - response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\n\r\n"); - assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); - assertThat(response, not(containsString("You are OK"))); - - response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("wrong", "user"))); - assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); - assertThat(response, not(containsString("You are OK"))); - - response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); - assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("user is OK")); - - response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); - assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("admin is OK")); - - response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); - assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); - assertThat(response, not(containsString("OK"))); - - response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); - assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("admin is OK")); - - response = _connector.getResponse("GET /ctx/known/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); - assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); - assertThat(response, not(containsString("OK"))); - } - public static class OkHandler extends Handler.Abstract { @Override @@ -258,52 +200,4 @@ else if (authentication == null) return true; } } - - private static class CustomLoginService implements LoginService - { - private final IdentityService identityService; - - public CustomLoginService(IdentityService identityService) - { - this.identityService = identityService; - } - - @Override - public String getName() - { - return "name"; - } - - @Override - public UserIdentity login(String username, Object credentials, Request request) - { - if ("admin".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); - if ("user".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - return false; - } - - @Override - public IdentityService getIdentityService() - { - return identityService; - } - - @Override - public void setIdentityService(IdentityService service) - { - } - - @Override - public void logout(UserIdentity user) - { - } - } } diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java index 880fd25cd641..d4ed6fbdf2a0 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java @@ -37,7 +37,7 @@ public class FormFields extends CompletableFuture implements Runnable { public static final String MAX_FIELDS_ATTRIBUTE = "org.eclipse.jetty.server.Request.maxFormKeys"; public static final String MAX_LENGTH_ATTRIBUTE = "org.eclipse.jetty.server.Request.maxFormContentSize"; - private static final CompletableFuture EMPTY = CompletableFuture.completedFuture(new Fields()); + private static final CompletableFuture EMPTY = CompletableFuture.completedFuture(Fields.EMPTY); public static Charset getFormEncodedCharset(Request request) { diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 47108db886ec..c6aebd02a8a0 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -35,7 +35,6 @@ import org.eclipse.jetty.http.MetaData; import org.eclipse.jetty.http.Trailers; import org.eclipse.jetty.io.Content; -import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.internal.HttpChannelState; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.Callback; @@ -410,8 +409,10 @@ static InputStream asInputStream(Request request) static Fields extractQueryParameters(Request request) { - Fields fields = new Fields(true); String query = request.getHttpURI().getQuery(); + if (StringUtil.isBlank(query)) + return Fields.EMPTY; + Fields fields = new Fields(true); if (StringUtil.isNotBlank(query)) UrlEncoded.decodeUtf8To(query, fields); return fields; diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index da1beead92a2..1a3789a764ff 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -35,6 +35,8 @@ */ public class Fields implements Iterable { + public static final Fields EMPTY = new Fields(); // TODO make immutable + private final boolean caseSensitive; private final Map fields; @@ -220,6 +222,12 @@ public void add(Field field) }); } + public void addAll(Fields fields) + { + for (Field field : fields) + add(field); + } + /** *

Removes the {@link Field} with the given name.

* From 2db4777f22c7768e58d5bbede8683468bb305651 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 23 Feb 2023 10:12:51 +1100 Subject: [PATCH 005/129] FORM auth working --- .../jetty/security/authentication/FormAuthenticator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 50489a536d27..74847609873c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -228,7 +228,7 @@ protected Fields getParameters(Request request) return formFields; if (formFields.isEmpty()) - return Fields.EMPTY; + return queryFields; Fields fields = new Fields(); fields.addAll(queryFields); From 5e929d52a2c159c3feb29bc31e0f8607219a1315 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 23 Feb 2023 13:06:47 +1100 Subject: [PATCH 006/129] FORM auth POST working --- .../jetty/client/transport/HttpRequest.java | 2 +- .../authentication/FormAuthenticator.java | 48 +++++++---- .../jetty/security/FormAuthenticatorTest.java | 46 ++++++++++ .../org/eclipse/jetty/server/FormFields.java | 2 + .../java/org/eclipse/jetty/util/Fields.java | 85 +++++++------------ .../jetty/ee10/servlet/ServletApiRequest.java | 5 +- .../ee10/servlet/ServletContextRequest.java | 5 +- 7 files changed, 119 insertions(+), 74 deletions(-) diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpRequest.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpRequest.java index c2d88c302818..814f68802228 100644 --- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpRequest.java +++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpRequest.java @@ -273,7 +273,7 @@ private Request param(String name, String value, boolean fromQuery) @Override public Fields getParams() { - return new Fields(params, true); + return params.asImmutable(); } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 74847609873c..1fa2cee46f49 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -194,27 +194,36 @@ public Request prepareRequest(Request request) // //See Servlet Spec 3.1 sec 13.6.3 Session session = request.getSession(false); - if (session == null || session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) - return request; //not authenticated yet - - HttpURI juri = (HttpURI)session.getAttribute(__J_URI); - if (juri == null) - return request; //no original uri saved + if (session == null) + return request; // couldn't be authenticated yet String method = (String)session.getAttribute(__J_METHOD); - if (method == null || method.length() == 0) - return request; //didn't save original request method + if (method == null) + return request; // No method so no wrapping required - if (!juri.equals(request.getHttpURI())) - return request; //this request is not for the same url as the original + if (session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) + return request; // not authenticated yet + + HttpURI juri = (HttpURI)session.getAttribute(__J_URI); + if (juri == null || !juri.equals(request.getHttpURI())) + return request; //no original uri saved or this is not a request for it //restore the original request's method on this request if (LOG.isDebugEnabled()) LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); - // TODO: Set method. - // servletContextRequest.getServletApiRequest().setMethod(method); - return request; + Fields fields = (Fields)session.removeAttribute(__J_POST); + if (fields != null) + request.setAttribute(FormFields.class.getName(), fields); + + return new Request.Wrapper(request) + { + @Override + public String getMethod() + { + return method; + } + }; } protected Fields getParameters(Request request) @@ -380,12 +389,19 @@ public Authentication validateRequest(Request req, Response res, Callback callba if (session.getAttribute(__J_URI) == null || _alwaysSaveUri) { session.setAttribute(__J_URI, req.getHttpURI()); - session.setAttribute(__J_METHOD, req.getMethod()); + if (!req.getMethod().equals(HttpMethod.GET.asString())) + session.setAttribute(__J_METHOD, req.getMethod()); if (HttpMethod.POST.is(req.getMethod()) && MimeTypes.Type.FORM_ENCODED.is(req.getHeaders().get(HttpHeader.CONTENT_TYPE))) { - // TODO limit size!!! - session.setAttribute(__J_POST, FormFields.from(req)); + try + { + session.setAttribute(__J_POST, FormFields.from(req).get()); + } + catch (InterruptedException | ExecutionException e) + { + throw new ServerAuthException(e); + } } } } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index c7233259b388..f61710b096b8 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -18,6 +18,7 @@ import org.eclipse.jetty.io.Content; import org.eclipse.jetty.security.authentication.FormAuthenticator; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; @@ -29,6 +30,7 @@ import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.session.SimpleSessionHandler; import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Fields; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -275,6 +277,43 @@ public void testLoginForm() throws Exception assertThat(response, containsString("Set-Cookie: JSESSIONID=")); } + @Test + public void testRedirectToPost() throws Exception + { + String response; + String sessionId = "unknown"; + + response = _connector.getResponse(""" + POST /ctx/any/user HTTP/1.0\r + Host: host:8888\r + Content-Length: 25\r + Content-Type: application/x-www-form-urlencoded\r + Cookie: JSESSIONID=%s\r + \r + name1=value1&name2=value2\r + """.formatted(sessionId)); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/login")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + sessionId = sessionId(response); + + response = _connector.getResponse("GET /ctx/j_security_check?j_username=user&j_password=password HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 302 Found")); + assertThat(response, containsString("Location: http://host:8888/ctx/any/user")); + assertThat(response, containsString("Set-Cookie: JSESSIONID=")); + String unsafeSessionId = sessionId; + sessionId = sessionId(response); + assertThat(sessionId, not(equalTo(unsafeSessionId))); + + response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); + assertThat(response, containsString("name1: value1\r\n")); + assertThat(response, containsString("name2: value2\r\n")); + assertThat(response, containsString("user is OK")); + + } + public static class OkHandler extends Handler.Abstract { @Override @@ -283,6 +322,13 @@ public boolean handle(Request request, Response response, Callback callback) thr if (Boolean.parseBoolean(Request.extractQueryParameters(request).getValue("createSession"))) request.getSession(true); + if (request.getMethod().equals("POST")) + { + Fields form = FormFields.from(request).get(); + for (Fields.Field field : form) + response.getHeaders().put(field.getName(), field.getValue()); + } + Authentication authentication = Authentication.getAuthentication(request); if (authentication instanceof Authentication.User user) Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java index d4ed6fbdf2a0..cf34584c1e81 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java @@ -80,6 +80,8 @@ public static CompletableFuture from(Request request, int maxFields, int Object attr = request.getAttribute(FormFields.class.getName()); if (attr instanceof FormFields futureFormFields) return futureFormFields; + else if (attr instanceof Fields fields) + return CompletableFuture.completedFuture(fields); Charset charset = getFormEncodedCharset(request); if (charset == null) diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index 1a3789a764ff..6d641bfea534 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -19,10 +19,10 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.TreeMap; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -35,15 +35,12 @@ */ public class Fields implements Iterable { - public static final Fields EMPTY = new Fields(); // TODO make immutable + public static final Fields EMPTY = new Fields(Collections.emptyMap()); - private final boolean caseSensitive; private final Map fields; /** *

Creates an empty, modifiable, case insensitive {@code Fields} instance.

- * - * @see #Fields(Fields, boolean) */ public Fields() { @@ -54,26 +51,20 @@ public Fields() *

Creates an empty, modifiable, case insensitive {@code Fields} instance.

* * @param caseSensitive whether this {@code Fields} instance must be case sensitive - * @see #Fields(Fields, boolean) */ public Fields(boolean caseSensitive) { - this.caseSensitive = caseSensitive; - fields = new LinkedHashMap<>(); + this(caseSensitive ? new LinkedHashMap<>() : new TreeMap<>(String::compareToIgnoreCase)); } - /** - *

Creates a {@code Fields} instance by copying the fields from the given - * {@code Fields} and making it (im)mutable depending on the given {@code immutable} parameter

- * - * @param original the {@code Fields} to copy fields from - * @param immutable whether this instance is immutable - */ - public Fields(Fields original, boolean immutable) + public Fields(Map fields) + { + this.fields = fields; + } + + public Fields asImmutable() { - this.caseSensitive = original.caseSensitive; - Map copy = new LinkedHashMap<>(original.fields); - fields = immutable ? Collections.unmodifiableMap(copy) : copy; + return new Fields(Collections.unmodifiableMap(fields)); } @Override @@ -81,21 +72,22 @@ public boolean equals(Object obj) { if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) - return false; - Fields that = (Fields)obj; - if (getSize() != that.getSize()) + if (obj == null) return false; - if (caseSensitive != that.caseSensitive) - return false; - for (Map.Entry entry : fields.entrySet()) + if (obj instanceof Fields that) { - String name = entry.getKey(); - Field value = entry.getValue(); - if (!value.equals(that.get(name), caseSensitive)) + if (getSize() != that.getSize()) return false; + for (Map.Entry entry : fields.entrySet()) + { + String name = entry.getKey(); + Field value = entry.getValue(); + if (!value.equals(that.get(name))) + return false; + } + return true; } - return true; + return false; } @Override @@ -122,18 +114,13 @@ public Stream stream() return fields.values().stream(); } - protected String normalizeName(String name) - { - return caseSensitive ? name : name.toLowerCase(Locale.ENGLISH); - } - /** * @param name the field name * @return the {@link Field} with the given name, or null if no such field exists */ public Field get(String name) { - return fields.get(normalizeName(name)); + return fields.get(name); } /** @@ -170,7 +157,7 @@ public void put(String name, String value) { // Preserve the case for the field name Field field = new Field(name, value); - fields.put(normalizeName(name), field); + fields.put(name, field); } /** @@ -181,7 +168,10 @@ public void put(String name, String value) public void put(Field field) { if (field != null) - fields.put(normalizeName(field.getName()), field); + { + String s = field.getName(); + fields.put(s, field); + } } /** @@ -193,7 +183,7 @@ public void put(Field field) */ public void add(String name, String value) { - String key = normalizeName(name); + String key = name; fields.compute(key, (k, f) -> { if (f == null) @@ -212,7 +202,8 @@ public void add(String name, String value) */ public void add(Field field) { - String key = normalizeName(field.getName()); + String s = field.getName(); + String key = s; fields.compute(key, (k, f) -> { if (f == null) @@ -236,7 +227,7 @@ public void addAll(Fields fields) */ public Field remove(String name) { - return fields.remove(normalizeName(name)); + return fields.remove(name); } /** @@ -320,18 +311,6 @@ private Field(String name, List values, List moreValues) this.values = List.copyOf(list); } - @SuppressWarnings("ReferenceEquality") - public boolean equals(Field that, boolean caseSensitive) - { - if (this == that) - return true; - if (that == null) - return false; - if (caseSensitive) - return equals(that); - return name.equalsIgnoreCase(that.name) && values.equals(that.values); - } - @Override public boolean equals(Object obj) { diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java index d4e21360f0ef..be2e51253dd4 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java @@ -825,8 +825,9 @@ else if (ServletContextRequest.isNoParams(_contentParameters) || _contentParamet _parameters = _queryParameters; else if (_parameters == null) { - _parameters = new Fields(_queryParameters, false); - _contentParameters.forEach(_parameters::add); + _parameters = new Fields(true); + _parameters.addAll(_queryParameters); + _parameters.addAll(_contentParameters); } // protect against calls to recycled requests (which is illegal, but diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextRequest.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextRequest.java index df1d9e7e6670..3a1e97abaeab 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextRequest.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextRequest.java @@ -15,6 +15,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.Collections; import java.util.EventListener; import java.util.List; @@ -50,8 +51,8 @@ public class ServletContextRequest extends ContextRequest static final int INPUT_STREAM = 1; static final int INPUT_READER = 2; - static final Fields NO_PARAMS = new Fields(new Fields(), true); - static final Fields BAD_PARAMS = new Fields(new Fields(), true); + static final Fields NO_PARAMS = new Fields(Collections.emptyMap()); + static final Fields BAD_PARAMS = new Fields(Collections.emptyMap()); public static ServletContextRequest getServletContextRequest(ServletRequest request) { From 63f394c8ee6fbce0496f1de75eae4bd4e24eca10 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 23 Feb 2023 16:43:52 +1100 Subject: [PATCH 007/129] WIP Signed-off-by: gregw --- .../eclipse/jetty/security/Constraint.java | 17 ++++++- .../authentication/FormAuthenticator.java | 12 +---- .../security/BasicAuthenticatorTest.java | 2 +- .../jetty/security/FormAuthenticatorTest.java | 2 +- .../org/eclipse/jetty/server/FormFields.java | 7 +-- .../server/handler/gzip/GzipHandlerTest.java | 7 +-- .../java/org/eclipse/jetty/util/Fields.java | 23 ++++++++- .../jetty/util/security/Constraint.java | 47 +------------------ 8 files changed, 48 insertions(+), 69 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 5abdffbb68c7..7f5b818ab531 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -33,6 +33,21 @@ public interface Constraint Set getRoles(); + default Constraint with(UserData userData) + { + return from(isForbidden(), userData, getAuthorization(), getRoles()); + } + + default Constraint with(Authorization authorization) + { + return from(isForbidden(), getUserData(), authorization, getRoles()); + } + + default Constraint with(String... roles) + { + return from(isForbidden(), getUserData(), getAuthorization(), roles); + } + enum UserData { NONE, @@ -106,7 +121,7 @@ else if (b.getRoles() != null || b.getRoles() != null) roles); } - static Constraint roles(String... roles) + static Constraint from(String... roles) { return from(false, null, Authorization.AUTHENTICATED_IN_ROLE, roles); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 1fa2cee46f49..c2b11fed3245 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -232,17 +232,7 @@ protected Fields getParameters(Request request) { Fields queryFields = Request.extractQueryParameters(request); Fields formFields = FormFields.from(request).get(); - - if (queryFields.isEmpty()) - return formFields; - - if (formFields.isEmpty()) - return queryFields; - - Fields fields = new Fields(); - fields.addAll(queryFields); - fields.addAll(formFields); - return fields; + return Fields.combine(queryFields, formFields); } catch (InterruptedException | ExecutionException e) { diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index 9467883369ff..e4d6815520ab 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -95,7 +95,7 @@ public boolean isSecure() _securityHandler.setHandler(new OkHandler()); - _securityHandler.add("/admin/*", Constraint.roles("admin")); + _securityHandler.add("/admin/*", Constraint.from("admin")); _securityHandler.add("/any/*", Constraint.AUTHENTICATED); _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); _securityHandler.setAuthenticator(new BasicAuthenticator()); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index f61710b096b8..0415e9933463 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -102,7 +102,7 @@ public boolean isSecure() _securityHandler.add("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed _securityHandler.add("/any/*", Constraint.AUTHENTICATED); _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); - _securityHandler.add("/admin/*", Constraint.roles("admin")); + _securityHandler.add("/admin/*", Constraint.from("admin")); _securityHandler.setAuthenticator(new FormAuthenticator("/login", "/error", false)); _server.start(); } diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java index cf34584c1e81..93d61193c502 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java @@ -124,17 +124,12 @@ private static int getRequestAttribute(Request request, String attribute) private byte _percentCode; public FormFields(Content.Source source, Charset charset, int maxFields, int maxSize) - { - this(source, charset, maxFields, maxSize, null); - } - - public FormFields(Content.Source source, Charset charset, int maxFields, int maxSize, Fields fields) { _source = source; _maxFields = maxFields; _maxLength = maxSize; _builder = CharsetStringBuilder.forCharset(charset); - _fields = fields == null ? new Fields() : fields; + _fields = new Fields(); } @Override diff --git a/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java b/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java index 9591b7d99972..9151f5bd9753 100644 --- a/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java +++ b/jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java @@ -1980,10 +1980,11 @@ public boolean handle(Request request, Response response, Callback callback) thr { response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain"); - Fields parameters = Request.extractQueryParameters(request); - FormFields futureFormFields = new FormFields(request, StandardCharsets.UTF_8, -1, -1, parameters); + Fields queryParameters = Request.extractQueryParameters(request); + FormFields futureFormFields = new FormFields(request, StandardCharsets.UTF_8, -1, -1); futureFormFields.run(); - parameters = futureFormFields.get(); + Fields formParameters = futureFormFields.get(); + Fields parameters = Fields.combine(queryParameters, formParameters); String dump = parameters.stream().map(f -> "%s: %s\n".formatted(f.getName(), f.getValue())).collect(Collectors.joining()); Content.Sink.write(response, true, dump, callback); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index 6d641bfea534..b045fe7820e7 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -48,7 +48,7 @@ public Fields() } /** - *

Creates an empty, modifiable, case insensitive {@code Fields} instance.

+ *

Creates an empty, modifiable, case insensitive {@code Fields} instance.

** * * @param caseSensitive whether this {@code Fields} instance must be case sensitive */ @@ -380,4 +380,25 @@ public String toString() return String.format("%s=%s", name, values); } } + + /** + *

Combine two Fields

+ * @param a The base Fields or null + * @param b The overlayed Fields or null + * @return Fields, which may be empty, but never null. + */ + public static Fields combine(Fields a, Fields b) + { + if (b == null || b.isEmpty()) + return a == null ? EMPTY : a; + + if (a == null || a.isEmpty()) + return b; + + Fields fields = new Fields(); + fields.addAll(a); + fields.addAll(b); + return fields; + } + } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java index 6aee16da9cbb..42ba5a28c350 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java @@ -25,7 +25,6 @@ @Deprecated public class Constraint implements Cloneable, Serializable { - public static final String __BASIC_AUTH = "BASIC"; public static final String __FORM_AUTH = "FORM"; @@ -41,26 +40,9 @@ public class Constraint implements Cloneable, Serializable public static final String __NEGOTIATE_AUTH = "NEGOTIATE"; public static final String __OPENID_AUTH = "OPENID"; - public static boolean validateMethod(String method) - { - if (method == null) - return false; - method = method.trim(); - return (method.equals(__FORM_AUTH) || - method.equals(__BASIC_AUTH) || - method.equals(__DIGEST_AUTH) || - method.equals(__CERT_AUTH) || - method.equals(__CERT_AUTH2) || - method.equals(__SPNEGO_AUTH) || - method.equals(__NEGOTIATE_AUTH) || - method.equals(__OPENID_AUTH)); - } - - public static final int DC_UNSET = -1; public static final int DC_NONE = 0; public static final int DC_INTEGRAL = 1; public static final int DC_CONFIDENTIAL = 2; - public static final int DC_FORBIDDEN = 3; public static final String NONE = "NONE"; @@ -72,7 +54,7 @@ public static boolean validateMethod(String method) private String[] _roles; - private int _dataConstraint = DC_UNSET; + private int _dataConstraint = -1; private boolean _anyRole = false; @@ -159,23 +141,6 @@ public String[] getRoles() return _roles; } - /** - * @param role the role - * @return True if the constraint contains the role. - */ - public boolean hasRole(String role) - { - if (_anyRole) - return true; - if (_roles != null) - for (int i = _roles.length; i-- > 0; ) - { - if (role.equals(_roles[i])) - return true; - } - return false; - } - /** * @param authenticate True if users must be authenticated */ @@ -220,19 +185,11 @@ public int getDataConstraint() return _dataConstraint; } - /** - * @return True if a data constraint has been set. - */ - public boolean hasDataConstraint() - { - return _dataConstraint >= DC_NONE; - } - @Override public String toString() { return "SC{" + _name + "," + (_anyRole ? "*" : (_roles == null ? "-" : Arrays.asList(_roles).toString())) + - "," + (_dataConstraint == DC_UNSET ? "DC_UNSET}" : (_dataConstraint == DC_NONE ? "NONE}" : (_dataConstraint == DC_INTEGRAL ? "INTEGRAL}" : "CONFIDENTIAL}"))); + "," + (_dataConstraint == -1 ? "UNSET}" : (_dataConstraint == DC_NONE ? "NONE}" : (_dataConstraint == DC_INTEGRAL ? "INTEGRAL}" : "CONFIDENTIAL}"))); } } From a926bc1320a1c51a9c8885bdbd30d145352a8c0f Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 23 Feb 2023 20:28:56 +1100 Subject: [PATCH 008/129] WIP Signed-off-by: gregw --- .../eclipse/jetty/security/Constraint.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 7f5b818ab531..d66af45cbf9e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -21,18 +21,35 @@ import java.util.stream.Stream; /** - * A Security Constraint interface. + * A Security Constraint. */ public interface Constraint { + /** + * @return true if the {@code Constraint} forbids all access. + */ boolean isForbidden(); + /** + * @return The {@link UserData} criteria applied by this {@code Constraint}. + */ UserData getUserData(); + /** + * @return The {@link Authorization} criteria applied by this {@code Constraint}. + */ Authorization getAuthorization(); + /** + * @return The set of roles applied by this {@code Constraint} or the empty set. + */ Set getRoles(); + /** + *

Create a new {@code Constraint}, based on this one but with the supplied {@link UserData}.

+ * @param userData The {@code UserData} to apply to the new {@code Constraint}. + * @return a new {@code Constraint} with the passed {@code UserData}. + */ default Constraint with(UserData userData) { return from(isForbidden(), userData, getAuthorization(), getRoles()); From 87fff1a5dba25b8f5400a32373b9a6fbb9b7986b Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 23 Feb 2023 22:13:23 +1100 Subject: [PATCH 009/129] WIP --- .../java/org/eclipse/jetty/security/IdentityService.java | 2 +- .../java/org/eclipse/jetty/security/SecurityHandler.java | 2 ++ .../java/org/eclipse/jetty/security/UserAuthentication.java | 1 - .../main/java/org/eclipse/jetty/security/UserIdentity.java | 5 ++--- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 3cded1905302..dcbe429ac1a6 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -24,7 +24,7 @@ */ public interface IdentityService { - static final String[] NO_ROLES = new String[]{}; + String[] NO_ROLES = new String[]{}; /** * Associate a user identity with the current thread. diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 90e5a8003d9f..5c886496150c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -221,6 +221,8 @@ public void setAuthMethod(String authMethod) if (isRunning()) throw new IllegalStateException("running"); _authMethod = authMethod; + if (_authenticator != null && !_authenticator.getAuthMethod().equals(_authMethod)) + _authenticator = null; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java index 718a6e043bd3..1c8d185a89a3 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserAuthentication.java @@ -18,7 +18,6 @@ */ public class UserAuthentication extends AbstractUserAuthentication { - public UserAuthentication(String method, UserIdentity userIdentity) { super(method, userIdentity); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java index 4f3d6b3c1014..dd7ead49650c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserIdentity.java @@ -25,7 +25,6 @@ */ public interface UserIdentity { - /** * @return The user subject */ @@ -46,11 +45,11 @@ public interface UserIdentity */ boolean isUserInRole(String role); - public interface UnauthenticatedUserIdentity extends UserIdentity + interface UnauthenticatedUserIdentity extends UserIdentity { } - public static final UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity() + UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity() { @Override public Subject getSubject() From 724141cda529c834fd44a36908ebc281c112cf0f Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 24 Feb 2023 15:31:44 +1100 Subject: [PATCH 010/129] WIP --- jetty-core/jetty-ee/pom.xml | 4 + .../jetty-ee/src/main/java/module-info.java | 2 + .../jetty/ee}/security/ConstraintAware.java | 6 +- .../jetty/ee}/security/ConstraintMapping.java | 6 +- .../security/AbstractUserAuthentication.java | 10 +- .../eclipse/jetty/security/Constraint.java | 104 +++++++++++------- ...andler.java => SimpleSecurityHandler.java} | 16 +-- .../DeferredAuthentication.java | 4 +- .../authentication/DigestAuthenticator.java | 6 +- .../authentication/LoginAuthenticator.java | 8 +- .../authentication/SessionAuthentication.java | 4 +- .../security/BasicAuthenticatorTest.java | 4 +- .../security/DefaultIdentityServiceTest.java | 2 +- .../jetty/security/FormAuthenticatorTest.java | 4 +- ...st.java => SimpleSecurityHandlerTest.java} | 6 +- .../org/eclipse/jetty/util/UrlEncoded.java | 33 +----- .../jetty/util/security/Constraint.java | 1 - 17 files changed, 115 insertions(+), 105 deletions(-) rename jetty-core/{jetty-security/src/main/java/org/eclipse/jetty => jetty-ee/src/main/java/org/eclipse/jetty/ee}/security/ConstraintAware.java (94%) rename jetty-core/{jetty-security/src/main/java/org/eclipse/jetty => jetty-ee/src/main/java/org/eclipse/jetty/ee}/security/ConstraintMapping.java (95%) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{SecurityHandler.java => SimpleSecurityHandler.java} (97%) rename jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/{SecurityHandlerTest.java => SimpleSecurityHandlerTest.java} (98%) diff --git a/jetty-core/jetty-ee/pom.xml b/jetty-core/jetty-ee/pom.xml index 1b57a02231f8..be7471ef83f2 100644 --- a/jetty-core/jetty-ee/pom.xml +++ b/jetty-core/jetty-ee/pom.xml @@ -33,6 +33,10 @@ org.eclipse.jetty jetty-io
+ + org.eclipse.jetty + jetty-security + org.eclipse.jetty jetty-jmx diff --git a/jetty-core/jetty-ee/src/main/java/module-info.java b/jetty-core/jetty-ee/src/main/java/module-info.java index 55903c1eb463..603376945d79 100644 --- a/jetty-core/jetty-ee/src/main/java/module-info.java +++ b/jetty-core/jetty-ee/src/main/java/module-info.java @@ -16,9 +16,11 @@ requires org.slf4j; requires transitive org.eclipse.jetty.io; + requires transitive org.eclipse.jetty.security; // Only required if using JMX. requires static org.eclipse.jetty.jmx; exports org.eclipse.jetty.ee; + exports org.eclipse.jetty.ee.security; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java b/jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintAware.java similarity index 94% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java rename to jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintAware.java index fe993645695a..bbece95c1980 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintAware.java +++ b/jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintAware.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.security; +package org.eclipse.jetty.ee.security; import java.util.List; import java.util.Set; @@ -20,7 +20,7 @@ public interface ConstraintAware { List getConstraintMappings(); - Set getRoles(); + Set getKnownRoles(); /** * Set Constraint Mappings and roles. @@ -45,7 +45,7 @@ public interface ConstraintAware * * @param role the role */ - void addRole(String role); + void addKnownRole(String role); /** * See Servlet Spec 31, sec 13.8.4, pg 145 diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java b/jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintMapping.java similarity index 95% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java rename to jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintMapping.java index 3e0719d86784..f2884efd4fd2 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConstraintMapping.java +++ b/jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/security/ConstraintMapping.java @@ -11,17 +11,15 @@ // ======================================================================== // -package org.eclipse.jetty.security; +package org.eclipse.jetty.ee.security; -import org.eclipse.jetty.util.security.Constraint; +import org.eclipse.jetty.security.Constraint; public class ConstraintMapping { String _method; String[] _methodOmissions; - String _pathSpec; - Constraint _constraint; /** diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index dd85a7125163..7bac07a635fc 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -14,7 +14,6 @@ package org.eclipse.jetty.security; import java.io.Serializable; -import java.util.Set; import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.authentication.LoginAuthenticator; @@ -53,6 +52,7 @@ public UserIdentity getUserIdentity() @Override public boolean isUserInRole(String role) { + /* TODO move to somewhere in ee //Servlet Spec 3.1 pg 125 if testing special role ** if ("**".equals(role.trim())) { @@ -64,10 +64,12 @@ public boolean isUserInRole(String role) else return _userIdentity.isUserInRole(role); } + */ return _userIdentity.isUserInRole(role); } + /* TODO remove this public boolean declaredRolesContains(String roleName) { SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); @@ -76,17 +78,19 @@ public boolean declaredRolesContains(String roleName) if (security instanceof ConstraintAware) { - Set declaredRoles = ((ConstraintAware)security).getRoles(); + xxx; Set declaredRoles = ((ConstraintAware)security).getRoles(); return (declaredRoles != null) && declaredRoles.contains(roleName); } return false; } + */ + @Override public Authentication logout(Request request) { - SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); if (security != null) { security.logout(this); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index d66af45cbf9e..ed6746c25eba 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -25,46 +25,6 @@ */ public interface Constraint { - /** - * @return true if the {@code Constraint} forbids all access. - */ - boolean isForbidden(); - - /** - * @return The {@link UserData} criteria applied by this {@code Constraint}. - */ - UserData getUserData(); - - /** - * @return The {@link Authorization} criteria applied by this {@code Constraint}. - */ - Authorization getAuthorization(); - - /** - * @return The set of roles applied by this {@code Constraint} or the empty set. - */ - Set getRoles(); - - /** - *

Create a new {@code Constraint}, based on this one but with the supplied {@link UserData}.

- * @param userData The {@code UserData} to apply to the new {@code Constraint}. - * @return a new {@code Constraint} with the passed {@code UserData}. - */ - default Constraint with(UserData userData) - { - return from(isForbidden(), userData, getAuthorization(), getRoles()); - } - - default Constraint with(Authorization authorization) - { - return from(isForbidden(), getUserData(), authorization, getRoles()); - } - - default Constraint with(String... roles) - { - return from(isForbidden(), getUserData(), getAuthorization(), roles); - } - enum UserData { NONE, @@ -111,6 +71,59 @@ static Authorization combine(Authorization a, Authorization b) } } + /** + * @return The name for the {@code Constraint} or "unnamed@hashcode" if not named + */ + default String getName() + { + return "unnamed@%x".formatted(hashCode()); + } + + /** + * @return true if the {@code Constraint} forbids all access. + */ + boolean isForbidden(); + + /** + * @return The {@link UserData} criteria applied by this {@code Constraint}. + */ + UserData getUserData(); + + /** + * @return The {@link Authorization} criteria applied by this {@code Constraint}. + */ + Authorization getAuthorization(); + + /** + * @return The set of roles applied by this {@code Constraint} or the empty set. + */ + Set getRoles(); + + /** + *

Create a new {@code Constraint}, based on this one but with the supplied {@link UserData}.

+ * @param userData The {@code UserData} to apply to the new {@code Constraint}. + * @return a new {@code Constraint} with the passed {@code UserData}. + */ + default Constraint with(UserData userData) + { + return from(isForbidden(), userData, getAuthorization(), getRoles()); + } + + default Constraint with(Authorization authorization) + { + return from(isForbidden(), getUserData(), authorization, getRoles()); + } + + default Constraint with(String... roles) + { + return from(isForbidden(), getUserData(), getAuthorization(), roles); + } + + default Constraint named(String name) + { + return from(name, isForbidden(), getUserData(), getAuthorization(), getRoles()); + } + Constraint NONE = from(false, UserData.NONE, Authorization.NONE); Constraint FORBIDDEN = from(true, null, null); Constraint INTEGRAL = from(false, UserData.INTEGRAL, null); @@ -151,6 +164,11 @@ static Constraint from(boolean forbidden, UserData userData, Authorization autho } static Constraint from(boolean forbidden, UserData userData, Authorization authorization, Set roles) + { + return from(null, forbidden, userData, authorization, roles); + } + + static Constraint from(String name, boolean forbidden, UserData userData, Authorization authorization, Set roles) { Set roleSet = roles == null ? Collections.emptySet() @@ -158,6 +176,12 @@ static Constraint from(boolean forbidden, UserData userData, Authorization autho return new Constraint() { + @Override + public String getName() + { + return name != null ? name : Constraint.super.getName(); + } + @Override public boolean isForbidden() { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java similarity index 97% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java index 5c886496150c..a3398bebd30e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java @@ -57,11 +57,11 @@ * that start with "org.eclipse.jetty.security." that do not have * values in the SecurityHandler init parameters, are copied. */ -public abstract class SecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration +public abstract class SimpleSecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration { public static String SESSION_AUTHENTICATED_ATTRIBUTE = "org.eclipse.jetty.security.sessionAuthenticated"; - private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleSecurityHandler.class); private static final List __knownAuthenticatorFactories = new ArrayList<>(); private boolean _checkWelcomeFiles = false; @@ -81,7 +81,7 @@ public abstract class SecurityHandler extends Handler.Wrapper implements Authent __knownAuthenticatorFactories.add(new DefaultAuthenticatorFactory()); } - protected SecurityHandler() + protected SimpleSecurityHandler() { addBean(new DumpableCollection("knownAuthenticatorFactories", __knownAuthenticatorFactories)); } @@ -522,11 +522,11 @@ public boolean handle(Request request, Response response, Callback callback) thr } } - public static SecurityHandler getCurrentSecurityHandler() + public static SimpleSecurityHandler getCurrentSecurityHandler() { ContextHandler contextHandler = ContextHandler.getCurrentContextHandler(); if (contextHandler != null) - return contextHandler.getDescendant(SecurityHandler.class); + return contextHandler.getDescendant(SimpleSecurityHandler.class); // TODO what about without context? return null; } @@ -634,9 +634,9 @@ public String toString() return "NOT CHECKED"; } - public SecurityHandler getSecurityHandler() + public SimpleSecurityHandler getSecurityHandler() { - return SecurityHandler.this; + return SimpleSecurityHandler.this; } } @@ -678,7 +678,7 @@ public String toString() } }; - public static class Mapped extends SecurityHandler + public static class Mapped extends SimpleSecurityHandler { private final PathMappings _mappings = new PathMappings<>(); private final Set _knownRoles = new HashSet<>(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 51ec0ab7dda5..a648af727964 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -23,8 +23,8 @@ import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoggedOutAuthentication; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.SimpleSecurityHandler; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; @@ -112,7 +112,7 @@ public Authentication login(String username, Object password, Request request, R @Override public Authentication logout(Request request) { - SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); if (security != null) { security.logout(null); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 8394a7e807ee..486b0cff4b16 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -27,8 +27,8 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.SimpleSecurityHandler; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; @@ -43,8 +43,8 @@ import org.slf4j.LoggerFactory; /** - * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} - * using the name "maxNonceAge". The nonce max count can be set with {@link SecurityHandler#setInitParameter(String, String)} + * The nonce max age in ms can be set with the {@link SimpleSecurityHandler#setInitParameter(String, String)} + * using the name "maxNonceAge". The nonce max count can be set with {@link SimpleSecurityHandler#setInitParameter(String, String)} * using the name "maxNonceCount". When the age or count is exceeded, the nonce is considered stale. */ public class DigestAuthenticator extends LoginAuthenticator diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 50ce2b24cf5d..895d62d4d43d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -16,7 +16,7 @@ import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.SimpleSecurityHandler; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -63,7 +63,7 @@ public void logout(Request request) Session session = request.getSession(false); if (session == null) return; - session.removeAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE); + session.removeAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE); } @Override @@ -104,9 +104,9 @@ protected Session renewSession(Request httpRequest, Response httpResponse) { //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users //(indicated by SESSION_SECURED not being set on the session) then we should change id - if (session.getAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE) != Boolean.TRUE) + if (session.getAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE) != Boolean.TRUE) { - session.setAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE, Boolean.TRUE); + session.setAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE, Boolean.TRUE); session.renewId(httpRequest, httpResponse); return session; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 2907da77fdc7..59685b82e34e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -20,7 +20,7 @@ import org.eclipse.jetty.security.AbstractUserAuthentication; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.SimpleSecurityHandler; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Session; import org.slf4j.Logger; @@ -66,7 +66,7 @@ private void readObject(ObjectInputStream stream) { stream.defaultReadObject(); - SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); if (security == null) { if (LOG.isDebugEnabled()) diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index e4d6815520ab..45b42aae4ca9 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -43,7 +43,7 @@ public class BasicAuthenticatorTest private LocalConnector _connector; private LocalConnector _connectorS; private SimpleSessionHandler _sessionHandler; - private SecurityHandler.Mapped _securityHandler; + private SimpleSecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -90,7 +90,7 @@ public boolean isSecure() _server.setHandler(contextHandler); contextHandler.setHandler(_sessionHandler); - _securityHandler = new SecurityHandler.Mapped(); + _securityHandler = new SimpleSecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java index 86811af49e7f..8ef75ce73015 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java @@ -28,7 +28,7 @@ public class DefaultIdentityServiceTest public void testDefaultIdentityService() throws Exception { Server server = new Server(); - SecurityHandler securityHandler = new SecurityHandler.Mapped(); + SimpleSecurityHandler securityHandler = new SimpleSecurityHandler.Mapped(); TestAuthenticator authenticator = new TestAuthenticator(); securityHandler.setAuthenticator(authenticator); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index 0415e9933463..4d83934a1ee1 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -47,7 +47,7 @@ public class FormAuthenticatorTest private LocalConnector _connector; private LocalConnector _connectorS; private SimpleSessionHandler _sessionHandler; - private SecurityHandler.Mapped _securityHandler; + private SimpleSecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -94,7 +94,7 @@ public boolean isSecure() _server.setHandler(contextHandler); contextHandler.setHandler(_sessionHandler); - _securityHandler = new SecurityHandler.Mapped(); + _securityHandler = new SimpleSecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java similarity index 98% rename from jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java rename to jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java index 3d2410925eab..179da56cd24a 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java @@ -35,12 +35,12 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -public class SecurityHandlerTest +public class SimpleSecurityHandlerTest { private Server _server; private LocalConnector _connector; private LocalConnector _connectorS; - private SecurityHandler.Mapped _securityHandler; + private SimpleSecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -80,7 +80,7 @@ public boolean isSecure() ContextHandler contextHandler = new ContextHandler("/ctx"); _server.setHandler(contextHandler); - _securityHandler = new SecurityHandler.Mapped(); + _securityHandler = new SimpleSecurityHandler.Mapped(); contextHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); _server.start(); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java index 6e9bb94350c5..3d312311893c 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java @@ -553,35 +553,14 @@ public static void decodeUtf16To(InputStream in, MultiMap map, int maxLe } /** - * Decoded parameters to Map. - * - * @param in the stream containing the encoded parameters - * @param map the MultiMap to decode into - * @param charset the charset to use for decoding - * @param maxLength the maximum length of the form to decode or -1 for no limit - * @param maxKeys the maximum number of keys to decode or -1 for no limit - * @throws IOException if unable to decode the input stream - * @deprecated use {@link #decodeTo(InputStream, MultiMap, Charset, int, int)} instead + * @param charsetName The charset name for decoding or null for the default + * @return A Charset to use for decoding. */ - @Deprecated(since = "10", forRemoval = true) - public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength, int maxKeys) - throws IOException + public static Charset decodeCharset(String charsetName) { - if (charset == null) - { - if (ENCODING.equals(StandardCharsets.UTF_8)) - decodeUtf8To(in, map, maxLength, maxKeys); - else - decodeTo(in, map, ENCODING, maxLength, maxKeys); - } - else if (StringUtil.__UTF8.equalsIgnoreCase(charset)) - decodeUtf8To(in, map, maxLength, maxKeys); - else if (StringUtil.__ISO_8859_1.equalsIgnoreCase(charset)) - decode88591To(in, map, maxLength, maxKeys); - else if (StringUtil.__UTF16.equalsIgnoreCase(charset)) - decodeUtf16To(in, map, maxLength, maxKeys); - else - decodeTo(in, map, Charset.forName(charset), maxLength, maxKeys); + if (charsetName == null) + return ENCODING; + return Charset.forName(charsetName); } /** diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java index 42ba5a28c350..c78c2209c278 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java @@ -47,7 +47,6 @@ public class Constraint implements Cloneable, Serializable public static final String NONE = "NONE"; public static final String ANY_ROLE = "*"; - public static final String ANY_AUTH = "**"; //Servlet Spec 3.1 pg 140 private String _name; From 214a28cc1a75454c5ad6d65caa42b1fc74d7836a Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 24 Feb 2023 15:37:15 +1100 Subject: [PATCH 011/129] WIP Signed-off-by: gregw --- .../security/AbstractUserAuthentication.java | 2 +- ...SecurityHandler.java => SecurityHandler.java} | 16 ++++++++-------- .../authentication/DeferredAuthentication.java | 4 ++-- .../authentication/DigestAuthenticator.java | 6 +++--- .../authentication/LoginAuthenticator.java | 8 ++++---- .../authentication/SessionAuthentication.java | 4 ++-- .../jetty/security/BasicAuthenticatorTest.java | 4 ++-- .../security/DefaultIdentityServiceTest.java | 2 +- .../jetty/security/FormAuthenticatorTest.java | 4 ++-- ...HandlerTest.java => SecurityHandlerTest.java} | 6 +++--- 10 files changed, 28 insertions(+), 28 deletions(-) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{SimpleSecurityHandler.java => SecurityHandler.java} (97%) rename jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/{SimpleSecurityHandlerTest.java => SecurityHandlerTest.java} (98%) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index 7bac07a635fc..725e1fbc6593 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -90,7 +90,7 @@ public boolean declaredRolesContains(String roleName) @Override public Authentication logout(Request request) { - SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); if (security != null) { security.logout(this); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java similarity index 97% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index a3398bebd30e..5c886496150c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SimpleSecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -57,11 +57,11 @@ * that start with "org.eclipse.jetty.security." that do not have * values in the SecurityHandler init parameters, are copied. */ -public abstract class SimpleSecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration +public abstract class SecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration { public static String SESSION_AUTHENTICATED_ATTRIBUTE = "org.eclipse.jetty.security.sessionAuthenticated"; - private static final Logger LOG = LoggerFactory.getLogger(SimpleSecurityHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); private static final List __knownAuthenticatorFactories = new ArrayList<>(); private boolean _checkWelcomeFiles = false; @@ -81,7 +81,7 @@ public abstract class SimpleSecurityHandler extends Handler.Wrapper implements A __knownAuthenticatorFactories.add(new DefaultAuthenticatorFactory()); } - protected SimpleSecurityHandler() + protected SecurityHandler() { addBean(new DumpableCollection("knownAuthenticatorFactories", __knownAuthenticatorFactories)); } @@ -522,11 +522,11 @@ public boolean handle(Request request, Response response, Callback callback) thr } } - public static SimpleSecurityHandler getCurrentSecurityHandler() + public static SecurityHandler getCurrentSecurityHandler() { ContextHandler contextHandler = ContextHandler.getCurrentContextHandler(); if (contextHandler != null) - return contextHandler.getDescendant(SimpleSecurityHandler.class); + return contextHandler.getDescendant(SecurityHandler.class); // TODO what about without context? return null; } @@ -634,9 +634,9 @@ public String toString() return "NOT CHECKED"; } - public SimpleSecurityHandler getSecurityHandler() + public SecurityHandler getSecurityHandler() { - return SimpleSecurityHandler.this; + return SecurityHandler.this; } } @@ -678,7 +678,7 @@ public String toString() } }; - public static class Mapped extends SimpleSecurityHandler + public static class Mapped extends SecurityHandler { private final PathMappings _mappings = new PathMappings<>(); private final Set _knownRoles = new HashSet<>(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index a648af727964..fc5fd958762f 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -24,7 +24,7 @@ import org.eclipse.jetty.security.LoggedOutAuthentication; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.security.SimpleSecurityHandler; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; @@ -112,7 +112,7 @@ public Authentication login(String username, Object password, Request request, R @Override public Authentication logout(Request request) { - SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); if (security != null) { security.logout(null); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 486b0cff4b16..b87afc63bcdd 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -28,7 +28,7 @@ import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.security.SimpleSecurityHandler; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; @@ -43,8 +43,8 @@ import org.slf4j.LoggerFactory; /** - * The nonce max age in ms can be set with the {@link SimpleSecurityHandler#setInitParameter(String, String)} - * using the name "maxNonceAge". The nonce max count can be set with {@link SimpleSecurityHandler#setInitParameter(String, String)} + * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} + * using the name "maxNonceAge". The nonce max count can be set with {@link SecurityHandler#setInitParameter(String, String)} * using the name "maxNonceCount". When the age or count is exceeded, the nonce is considered stale. */ public class DigestAuthenticator extends LoginAuthenticator diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 895d62d4d43d..50ce2b24cf5d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -16,7 +16,7 @@ import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SimpleSecurityHandler; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -63,7 +63,7 @@ public void logout(Request request) Session session = request.getSession(false); if (session == null) return; - session.removeAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE); + session.removeAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE); } @Override @@ -104,9 +104,9 @@ protected Session renewSession(Request httpRequest, Response httpResponse) { //if we should renew sessions, and there is an existing session that may have been seen by non-authenticated users //(indicated by SESSION_SECURED not being set on the session) then we should change id - if (session.getAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE) != Boolean.TRUE) + if (session.getAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE) != Boolean.TRUE) { - session.setAttribute(SimpleSecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE, Boolean.TRUE); + session.setAttribute(SecurityHandler.SESSION_AUTHENTICATED_ATTRIBUTE, Boolean.TRUE); session.renewId(httpRequest, httpResponse); return session; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java index 59685b82e34e..2907da77fdc7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SessionAuthentication.java @@ -20,7 +20,7 @@ import org.eclipse.jetty.security.AbstractUserAuthentication; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SimpleSecurityHandler; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Session; import org.slf4j.Logger; @@ -66,7 +66,7 @@ private void readObject(ObjectInputStream stream) { stream.defaultReadObject(); - SimpleSecurityHandler security = SimpleSecurityHandler.getCurrentSecurityHandler(); + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); if (security == null) { if (LOG.isDebugEnabled()) diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index 45b42aae4ca9..e4d6815520ab 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -43,7 +43,7 @@ public class BasicAuthenticatorTest private LocalConnector _connector; private LocalConnector _connectorS; private SimpleSessionHandler _sessionHandler; - private SimpleSecurityHandler.Mapped _securityHandler; + private SecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -90,7 +90,7 @@ public boolean isSecure() _server.setHandler(contextHandler); contextHandler.setHandler(_sessionHandler); - _securityHandler = new SimpleSecurityHandler.Mapped(); + _securityHandler = new SecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java index 8ef75ce73015..86811af49e7f 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java @@ -28,7 +28,7 @@ public class DefaultIdentityServiceTest public void testDefaultIdentityService() throws Exception { Server server = new Server(); - SimpleSecurityHandler securityHandler = new SimpleSecurityHandler.Mapped(); + SecurityHandler securityHandler = new SecurityHandler.Mapped(); TestAuthenticator authenticator = new TestAuthenticator(); securityHandler.setAuthenticator(authenticator); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index 4d83934a1ee1..0415e9933463 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -47,7 +47,7 @@ public class FormAuthenticatorTest private LocalConnector _connector; private LocalConnector _connectorS; private SimpleSessionHandler _sessionHandler; - private SimpleSecurityHandler.Mapped _securityHandler; + private SecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -94,7 +94,7 @@ public boolean isSecure() _server.setHandler(contextHandler); contextHandler.setHandler(_sessionHandler); - _securityHandler = new SimpleSecurityHandler.Mapped(); + _securityHandler = new SecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java similarity index 98% rename from jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java rename to jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 179da56cd24a..3d2410925eab 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SimpleSecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -35,12 +35,12 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.not; -public class SimpleSecurityHandlerTest +public class SecurityHandlerTest { private Server _server; private LocalConnector _connector; private LocalConnector _connectorS; - private SimpleSecurityHandler.Mapped _securityHandler; + private SecurityHandler.Mapped _securityHandler; @BeforeEach public void configureServer() throws Exception @@ -80,7 +80,7 @@ public boolean isSecure() ContextHandler contextHandler = new ContextHandler("/ctx"); _server.setHandler(contextHandler); - _securityHandler = new SimpleSecurityHandler.Mapped(); + _securityHandler = new SecurityHandler.Mapped(); contextHandler.setHandler(_securityHandler); _securityHandler.setHandler(new OkHandler()); _server.start(); From e33d07643156ab624de55bb7ebc2a8bcd90ba6f3 Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 24 Feb 2023 16:04:45 +1100 Subject: [PATCH 012/129] WIP --- .../security/authentication/DeferredAuthentication.java | 2 +- .../jetty/security/authentication/DigestAuthenticator.java | 2 +- .../src/main/java/org/eclipse/jetty/ee9/nested/Request.java | 2 +- pom.xml | 5 +++++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index fc5fd958762f..51ec0ab7dda5 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -23,8 +23,8 @@ import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoggedOutAuthentication; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index b87afc63bcdd..8394a7e807ee 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -27,8 +27,8 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java index 42af442405e6..fa31b6107b44 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java @@ -526,7 +526,7 @@ public void extractFormParameters(MultiMap params) if (_input.isAsync()) throw new IllegalStateException("Cannot extract parameters with async IO"); - UrlEncoded.decodeTo(in, params, getCharacterEncoding(), maxFormContentSize, maxFormKeys); + UrlEncoded.decodeTo(in, params, UrlEncoded.decodeCharset(getCharacterEncoding()), maxFormContentSize, maxFormKeys); } catch (IOException e) { diff --git a/pom.xml b/pom.xml index 7ba0e901ab07..2cf24324315f 100644 --- a/pom.xml +++ b/pom.xml @@ -1272,6 +1272,11 @@ jetty-rewrite ${project.version}
+ + org.eclipse.jetty + jetty-security + ${project.version} + org.eclipse.jetty jetty-session From 70db4697a435402e12dff77c6e43def8d2ec9ca0 Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 26 Feb 2023 08:48:53 +1100 Subject: [PATCH 013/129] WIP auth parameters --- .../jetty/security/SecurityHandler.java | 20 +++++++++++++++++-- .../authentication/DigestAuthenticator.java | 4 ++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 5c886496150c..6bc2b176fe6e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.http.pathmap.MappedResource; import org.eclipse.jetty.http.pathmap.PathMappings; import org.eclipse.jetty.http.pathmap.PathSpec; +import org.eclipse.jetty.security.Authenticator.AuthConfiguration; import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Handler; @@ -57,7 +58,7 @@ * that start with "org.eclipse.jetty.security." that do not have * values in the SecurityHandler init parameters, are copied. */ -public abstract class SecurityHandler extends Handler.Wrapper implements Authenticator.AuthConfiguration +public abstract class SecurityHandler extends Handler.Wrapper implements AuthConfiguration { public static String SESSION_AUTHENTICATED_ATTRIBUTE = "org.eclipse.jetty.security.sessionAuthenticated"; @@ -237,6 +238,21 @@ public Set getParameterNames() return _parameters.keySet(); } + /** + * Set an authentication parameter for retrieval via {@link AuthConfiguration#getParameter(String)} + * + * @param key the key + * @param value the init value + * @return previous value + * @throws IllegalStateException if the SecurityHandler is started + */ + public String setParameter(String key, String value) + { + if (isStarted()) + throw new IllegalStateException("started"); + return _parameters.put(key, value); + } + protected LoginService findLoginService() throws Exception { java.util.Collection list = getServer().getBeans(LoginService.class); @@ -382,7 +398,7 @@ public boolean isSessionRenewedOnAuthentication() * If set to true, then on authentication, the session associated with a reqeuest is invalidated and replaced with a new session. * * @param renew true to renew the authentication on session - * @see Authenticator.AuthConfiguration#isSessionRenewedOnAuthentication() + * @see AuthConfiguration#isSessionRenewedOnAuthentication() */ public void setSessionRenewedOnAuthentication(boolean renew) { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 8394a7e807ee..f8c17784d786 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -43,8 +43,8 @@ import org.slf4j.LoggerFactory; /** - * The nonce max age in ms can be set with the {@link SecurityHandler#setInitParameter(String, String)} - * using the name "maxNonceAge". The nonce max count can be set with {@link SecurityHandler#setInitParameter(String, String)} + * The nonce max age in ms can be set with the {@link SecurityHandler#setParameter(String, String)} + * using the name "maxNonceAge". The nonce max count can be set with {@link SecurityHandler#setParameter(String, String)} * using the name "maxNonceCount". When the age or count is exceeded, the nonce is considered stale. */ public class DigestAuthenticator extends LoginAuthenticator From 00c81c46e9b79d3c297b0706e9e5c40b0d592d5b Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 1 Mar 2023 08:18:26 +1100 Subject: [PATCH 014/129] WIP --- .../src/main/java/module-info.java | 5 +- .../eclipse/jetty/security/Constraint.java | 125 ++++++++++++------ .../security/DefaultIdentityService.java | 45 ++++--- .../jetty/security/IdentityService.java | 40 +++--- .../jetty/security/PropertyUserStore.java | 2 +- .../jetty/security/SecurityHandler.java | 74 +++++------ .../DeferredAuthentication.java | 12 +- .../{ => internal}/DefaultUserIdentity.java | 8 +- .../LoginCallbackImpl.java | 6 +- .../{ => internal}/RoleRunAsToken.java | 2 +- .../security/{ => internal}/RunAsToken.java | 2 +- .../security/BasicAuthenticatorTest.java | 1 + .../jetty/security/FormAuthenticatorTest.java | 1 + .../jetty/ee10/servlet/ServletHolder.java | 11 +- 14 files changed, 190 insertions(+), 144 deletions(-) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{ => internal}/DefaultUserIdentity.java (87%) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{authentication => internal}/LoginCallbackImpl.java (93%) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{ => internal}/RoleRunAsToken.java (95%) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/{ => internal}/RunAsToken.java (94%) diff --git a/jetty-core/jetty-security/src/main/java/module-info.java b/jetty-core/jetty-security/src/main/java/module-info.java index 08e37b55aff4..ba6ca822aee3 100644 --- a/jetty-core/jetty-security/src/main/java/module-info.java +++ b/jetty-core/jetty-security/src/main/java/module-info.java @@ -13,7 +13,6 @@ module org.eclipse.jetty.security { - uses org.eclipse.jetty.security.Authenticator.Factory; requires transitive org.eclipse.jetty.server; requires transitive org.eclipse.jetty.util; requires transitive org.slf4j; @@ -21,4 +20,8 @@ requires java.sql; exports org.eclipse.jetty.security; + exports org.eclipse.jetty.security.authentication; + exports org.eclipse.jetty.security.internal; + + uses org.eclipse.jetty.security.Authenticator.Factory; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index ed6746c25eba..997cbc646c35 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -25,22 +25,22 @@ */ public interface Constraint { - enum UserData + enum Transport { - NONE, + CLEAR, INTEGRAL, CONFIDENTIAL; - static UserData combine(UserData a, UserData b) + static Transport combine(Transport a, Transport b) { if (a == null) - return b == null ? NONE : b; + return b == null ? CLEAR : b; if (b == null) return a; return switch (b) { - case NONE -> a; + case CLEAR -> a; case INTEGRAL -> a == CONFIDENTIAL ? CONFIDENTIAL : INTEGRAL; case CONFIDENTIAL -> CONFIDENTIAL; }; @@ -74,10 +74,7 @@ static Authorization combine(Authorization a, Authorization b) /** * @return The name for the {@code Constraint} or "unnamed@hashcode" if not named */ - default String getName() - { - return "unnamed@%x".formatted(hashCode()); - } + String getName(); /** * @return true if the {@code Constraint} forbids all access. @@ -85,9 +82,9 @@ default String getName() boolean isForbidden(); /** - * @return The {@link UserData} criteria applied by this {@code Constraint}. + * @return The {@link Transport} criteria applied by this {@code Constraint}. */ - UserData getUserData(); + Transport getUserData(); /** * @return The {@link Authorization} criteria applied by this {@code Constraint}. @@ -99,35 +96,77 @@ default String getName() */ Set getRoles(); - /** - *

Create a new {@code Constraint}, based on this one but with the supplied {@link UserData}.

- * @param userData The {@code UserData} to apply to the new {@code Constraint}. - * @return a new {@code Constraint} with the passed {@code UserData}. - */ - default Constraint with(UserData userData) + default Builder builder() { - return from(isForbidden(), userData, getAuthorization(), getRoles()); + return new Builder(this); } - default Constraint with(Authorization authorization) + class Builder { - return from(isForbidden(), getUserData(), authorization, getRoles()); - } + private String _name; + private boolean _forbidden; + private Transport _transport; + private Authorization _authorization; + private Set _roles; - default Constraint with(String... roles) - { - return from(isForbidden(), getUserData(), getAuthorization(), roles); - } + public Builder() + {} - default Constraint named(String name) - { - return from(name, isForbidden(), getUserData(), getAuthorization(), getRoles()); + Builder(Constraint constraint) + { + _forbidden = constraint.isForbidden(); + _transport = constraint.getUserData(); + _authorization = constraint.getAuthorization(); + _roles = constraint.getRoles(); + } + + public Builder name(String name) + { + _name = name; + return this; + } + + public Builder forbidden(boolean forbidden) + { + _forbidden = forbidden; + return this; + } + + public Builder transport(Transport transport) + { + _transport = transport; + return this; + } + + public Builder authorization(Authorization authorization) + { + _authorization = authorization; + return this; + } + + public Builder roles(String... roles) + { + if (roles != null && roles.length > 0) + { + if (_roles == null) + _roles = new HashSet<>(); + else if (!(_roles instanceof HashSet)) + _roles = new HashSet<>(_roles); + _roles.addAll(Arrays.asList(roles)); + } + return this; + } + + public Constraint build() + { + return from(_name, _forbidden, _transport, _authorization, _roles); + } } - Constraint NONE = from(false, UserData.NONE, Authorization.NONE); + Constraint NONE = from(false, Transport.CLEAR, Authorization.NONE); Constraint FORBIDDEN = from(true, null, null); - Constraint INTEGRAL = from(false, UserData.INTEGRAL, null); - Constraint CONFIDENTIAL = from(false, UserData.CONFIDENTIAL, null); + Constraint INTEGRAL = from(false, Transport.INTEGRAL, null); + Constraint CONFIDENTIAL = from(false, Transport.CONFIDENTIAL, null); Constraint AUTHENTICATED = from(false, null, Authorization.AUTHENTICATED); Constraint AUTHENTICATED_IN_KNOWN_ROLE = from(false, null, Authorization.AUTHENTICATED_IN_KNOWN_ROLE); @@ -146,7 +185,7 @@ else if (b.getRoles() != null || b.getRoles() != null) return from( a.isForbidden() || b.isForbidden(), - UserData.combine(a.getUserData(), b.getUserData()), + Transport.combine(a.getUserData(), b.getUserData()), Authorization.combine(a.getAuthorization(), b.getAuthorization()), roles); } @@ -156,19 +195,19 @@ static Constraint from(String... roles) return from(false, null, Authorization.AUTHENTICATED_IN_ROLE, roles); } - static Constraint from(boolean forbidden, UserData userData, Authorization authorization, String... roles) + static Constraint from(boolean forbidden, Transport transport, Authorization authorization, String... roles) { - return from(forbidden, userData, authorization, (roles == null || roles.length == 0) + return from(forbidden, transport, authorization, (roles == null || roles.length == 0) ? Collections.emptySet() : new HashSet<>(Arrays.stream(roles).toList())); } - static Constraint from(boolean forbidden, UserData userData, Authorization authorization, Set roles) + static Constraint from(boolean forbidden, Transport transport, Authorization authorization, Set roles) { - return from(null, forbidden, userData, authorization, roles); + return from(null, forbidden, transport, authorization, roles); } - static Constraint from(String name, boolean forbidden, UserData userData, Authorization authorization, Set roles) + static Constraint from(String name, boolean forbidden, Transport transport, Authorization authorization, Set roles) { Set roleSet = roles == null ? Collections.emptySet() @@ -179,7 +218,7 @@ static Constraint from(String name, boolean forbidden, UserData userData, Author @Override public String getName() { - return name != null ? name : Constraint.super.getName(); + return name; } @Override @@ -189,9 +228,9 @@ public boolean isForbidden() } @Override - public UserData getUserData() + public Transport getUserData() { - return userData == null ? UserData.NONE : userData; + return transport == null ? Transport.CLEAR : transport; } @Override @@ -205,6 +244,12 @@ public Set getRoles() { return roleSet; } + + @Override + public Builder builder() + { + return null; + } }; } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index 41237d1e92d3..2f0b40e1af4e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -16,42 +16,46 @@ import java.security.Principal; import javax.security.auth.Subject; +import org.eclipse.jetty.security.internal.DefaultUserIdentity; +import org.eclipse.jetty.security.internal.RoleRunAsToken; +import org.eclipse.jetty.security.internal.RunAsToken; + /** - * Default Identity Service implementation. - * This service handles only role reference maps passed in an - * associated {@link UserIdentity}. If there are roles - * refs present, then associate will wrap the UserIdentity with one - * that uses the role references in the - * {@link UserIdentity#isUserInRole(String)} - * implementation. All other operations are effectively noops. - * TODO associate on demand and write callbacks? + * */ public class DefaultIdentityService implements IdentityService { - /** - * If there are roles refs present in the scope, then wrap the UserIdentity - * with one that uses the role references in the {@link UserIdentity#isUserInRole(String)} - */ - @Override - public Object associate(UserIdentity user) + private static final ThreadLocal runAsRole = new ThreadLocal<>(); + + public static boolean isRoleAssociated(String role) { - return null; + return role != null && role.equals(runAsRole.get()); } @Override - public void disassociate(Object previous) + public Association associate(UserIdentity user) { + return NOOP; } @Override - public Object setRunAs(UserIdentity user, RunAsToken token) + public Association associate(UserIdentity user, Object token) { - return token; + if (token instanceof RoleRunAsToken roleRunAsToken) + { + String oldAssociate = runAsRole.get(); + runAsRole.set(roleRunAsToken.getRunAsRole()); + if (oldAssociate == null) + return CLEAR_RUN_AS; + return () -> runAsRole.set(oldAssociate); + } + return NOOP; } @Override - public void unsetRunAs(Object lastToken) + public void logout(UserIdentity user) { + runAsRole.set(null); } @Override @@ -71,4 +75,7 @@ public UserIdentity newUserIdentity(final Subject subject, final Principal userP { return new DefaultUserIdentity(subject, userPrincipal, roles); } + + private static final Association NOOP = () -> {}; + private static final Association CLEAR_RUN_AS = () -> runAsRole.set(null); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index dcbe429ac1a6..42a61e3b0633 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -13,6 +13,7 @@ package org.eclipse.jetty.security; +import java.io.Closeable; import java.security.Principal; import javax.security.auth.Subject; @@ -24,43 +25,27 @@ */ public interface IdentityService { - String[] NO_ROLES = new String[]{}; - /** * Associate a user identity with the current thread. * This is called with as a thread enters the * {@link Handler#handle(Request, org.eclipse.jetty.server.Response, org.eclipse.jetty.util.Callback)} * method and then again with a null argument as that call exits. * - * @param user The current user or null for no user to associated. - * @return an object representing the previous associated state - */ - Object associate(UserIdentity user); - - /** - * Disassociate the user identity from the current thread - * and restore previous identity. - * - * @param previous The opaque object returned from a call to {@link IdentityService#associate(UserIdentity)} + * @param user The current user or null for no user to associate. + * @return A {@link Closeable} that, when closed, will disassociate the user and restore any prior associations. */ - void disassociate(Object previous); + Association associate(UserIdentity user); /** * Associate a runas Token with the current user and thread. * * @param user The UserIdentity - * @param token The runAsToken to associate. - * @return The previous runAsToken or null. + * @param token The runAsToken to associate, obtained from {@link #newRunAsToken(String)}. + * @return A {@link Closeable} that, when closed, will disassociate the token and restore any prior associations. */ - Object setRunAs(UserIdentity user, RunAsToken token); + Association associate(UserIdentity user, Object token); - /** - * Disassociate the current runAsToken from the thread - * and reassociate the previous token. - * - * @param token RUNAS returned from previous associateRunAs call - */ - void unsetRunAs(Object token); + void logout(UserIdentity user); /** * Create a new UserIdentity for use with this identity service. @@ -77,9 +62,14 @@ public interface IdentityService * Create a new RunAsToken from a runAsName (normally a role). * * @param runAsName Normally a role name - * @return A new immutable RunAsToken + * @return A token that can be passed to {@link #associate(UserIdentity, Object)}. */ - RunAsToken newRunAsToken(String runAsName); + Object newRunAsToken(String runAsName); UserIdentity getSystemUserIdentity(); + + interface Association extends AutoCloseable + { + + } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java index 5204a3e3347f..071623241fe0 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/PropertyUserStore.java @@ -180,7 +180,7 @@ protected void loadUsers() throws IOException if (username.length() > 0) { - String[] roleArray = IdentityService.NO_ROLES; + String[] roleArray = new String[0]; if (roles != null && roles.length() > 0) roleArray = StringUtil.csvSplit(roles); known.add(username); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 6bc2b176fe6e..8c35dea4b684 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -445,7 +445,6 @@ public boolean handle(Request request, Response response, Callback callback) thr } // check authentication - Object previousIdentity = null; try { Authentication authentication = Authentication.getAuthentication(request); @@ -460,26 +459,26 @@ public boolean handle(Request request, Response response, Callback callback) thr if (authentication instanceof Authentication.User userAuth) { Authentication.setAuthentication(request, authentication); - if (_identityService != null) - previousIdentity = _identityService.associate(userAuth.getUserIdentity()); - - if (authMandatory) + try (AutoCloseable association = _identityService.associate(userAuth.getUserIdentity())) { - boolean authorized = checkAuthorization(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); - if (!authorized) + if (authMandatory) { - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!role"); - return true; + boolean authorized = checkAuthorization(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); + if (!authorized) + { + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!role"); + return true; + } } - } - //process the request by other handlers - boolean processed = next.handle(request, response, callback); + //process the request by other handlers + boolean processed = next.handle(request, response, callback); - // TODO this looks wrong as in way too late - if (processed && authenticator != null) - authenticator.secureResponse(request, response, callback, authMandatory, userAuth); - return processed; + // TODO this looks wrong as in way too late + if (processed && authenticator != null) + authenticator.secureResponse(request, response, callback, authMandatory, userAuth); + return processed; + } } if (authentication instanceof DeferredAuthentication deferred) @@ -491,21 +490,23 @@ public boolean handle(Request request, Response response, Callback callback) thr { //process the request by other handlers handled = next.handle(request, response, callback); + + if (handled && authenticator != null) + { + Authentication auth = Authentication.getAuthentication(request); + if (auth instanceof Authentication.User userAuth) + authenticator.secureResponse(request, response, callback, authMandatory, userAuth); + else + authenticator.secureResponse(request, response, callback, authMandatory, null); + } + return handled; } finally { - previousIdentity = deferred.getPreviousAssociation(); - } - - if (handled && authenticator != null) - { - Authentication auth = Authentication.getAuthentication(request); - if (auth instanceof Authentication.User userAuth) - authenticator.secureResponse(request, response, callback, authMandatory, userAuth); - else - authenticator.secureResponse(request, response, callback, authMandatory, null); + IdentityService.Association association = deferred.getAssociation(); + if (association != null) + association.close(); } - return handled; } if (authMandatory) @@ -515,8 +516,6 @@ public boolean handle(Request request, Response response, Callback callback) thr } Authentication.setAuthentication(request, authentication); - if (_identityService != null) - previousIdentity = _identityService.associate(null); //process the request by other handlers boolean handled = next.handle(request, response, callback); @@ -531,11 +530,6 @@ public boolean handle(Request request, Response response, Callback callback) thr Response.writeError(request, response, callback, HttpStatus.INTERNAL_SERVER_ERROR_500, e.getMessage()); return true; } - finally - { - if (_identityService != null) - _identityService.disassociate(previousIdentity); - } } public static SecurityHandler getCurrentSecurityHandler() @@ -555,25 +549,19 @@ public void logout(Authentication.User user) LoginService loginService = getLoginService(); if (loginService != null) - { loginService.logout(user.getUserIdentity()); - } IdentityService identityService = getIdentityService(); if (identityService != null) - { - // TODO recover previous from threadlocal (or similar) - Object previous = null; - identityService.disassociate(previous); - } + identityService.logout(user.getUserIdentity()); } protected abstract Constraint getConstraint(String pathInContext, Request request); protected boolean checkUserData(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException { - Constraint.UserData dataConstraint = constraint.getUserData(); - if (dataConstraint == null || dataConstraint == Constraint.UserData.NONE) + Constraint.Transport dataConstraint = constraint.getUserData(); + if (dataConstraint == null || dataConstraint == Constraint.Transport.CLEAR) return true; HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 51ec0ab7dda5..464fe4bffd5d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -37,7 +37,7 @@ public class DeferredAuthentication implements Authentication.Deferred { private static final Logger LOG = LoggerFactory.getLogger(DeferredAuthentication.class); protected final LoginAuthenticator _authenticator; - private Object _previousAssociation; + private IdentityService.Association _association; public DeferredAuthentication(LoginAuthenticator authenticator) { @@ -58,7 +58,7 @@ public Authentication authenticate(Request request) IdentityService identityService = loginService.getIdentityService(); if (identityService != null) - _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); return authentication; } @@ -81,7 +81,7 @@ public Authentication authenticate(Request request, Response response, Callback Authentication authentication = _authenticator.validateRequest(request, response, callback, true); if (authentication instanceof Authentication.User && identityService != null) - _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); return authentication; } catch (ServerAuthException e) @@ -103,7 +103,7 @@ public Authentication login(String username, Object password, Request request, R IdentityService identityService = _authenticator.getLoginService().getIdentityService(); UserAuthentication authentication = new UserAuthentication("API", identity); if (identityService != null) - _previousAssociation = identityService.associate(identity); + _association = identityService.associate(identity); return authentication; } return null; @@ -123,9 +123,9 @@ public Authentication logout(Request request) return Authentication.UNAUTHENTICATED; } - public Object getPreviousAssociation() + public IdentityService.Association getAssociation() { - return _previousAssociation; + return _association; } /** diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java similarity index 87% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java index ef56618b9778..198d684118b4 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultUserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java @@ -11,11 +11,14 @@ // ======================================================================== // -package org.eclipse.jetty.security; +package org.eclipse.jetty.security.internal; import java.security.Principal; import javax.security.auth.Subject; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.UserIdentity; + /** * The default implementation of UserIdentity. */ @@ -47,6 +50,9 @@ public Principal getUserPrincipal() @Override public boolean isUserInRole(String role) { + if (DefaultIdentityService.isRoleAssociated(role)) + return true; + //Servlet Spec 3.1, pg 125 if ("*".equals(role)) return false; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java similarity index 93% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java index 44aa3bd4ddf1..3eb1add82930 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallbackImpl.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java @@ -11,12 +11,12 @@ // ======================================================================== // -package org.eclipse.jetty.security.authentication; +package org.eclipse.jetty.security.internal; import java.security.Principal; import javax.security.auth.Subject; -import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.authentication.LoginCallback; /** * This is similar to the jaspi PasswordValidationCallback but includes user @@ -37,7 +37,7 @@ public class LoginCallbackImpl implements LoginCallback private Principal userPrincipal; - private String[] roles = IdentityService.NO_ROLES; + private String[] roles = new String[0]; //TODO could use Credential instance instead of Object if Basic/Form create a Password object public LoginCallbackImpl(Subject subject, String userName, Object credential) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java similarity index 95% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java index defced954fb1..848b0364180e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RoleRunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.security; +package org.eclipse.jetty.security.internal; /** * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java similarity index 94% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java index b6c55e65d690..e0f9423d8290 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/RunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.security; +package org.eclipse.jetty.security.internal; /** * marker interface for run-as-role tokens diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index e4d6815520ab..820f986e7ef5 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -17,6 +17,7 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.io.Content; import org.eclipse.jetty.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.Handler; diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index 0415e9933463..cbeec3724a94 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -17,6 +17,7 @@ import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.io.Content; import org.eclipse.jetty.security.authentication.FormAuthenticator; +import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.ForwardedRequestCustomizer; diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHolder.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHolder.java index 41962f99f3e8..3c11b931ba9a 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHolder.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHolder.java @@ -42,8 +42,10 @@ import jakarta.servlet.ServletSecurityElement; import jakarta.servlet.UnavailableException; import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.ee10.servlet.security.Authentication; import org.eclipse.jetty.ee10.servlet.security.IdentityService; import org.eclipse.jetty.ee10.servlet.security.RunAsToken; +import org.eclipse.jetty.ee10.servlet.security.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.NanoTime; @@ -1336,12 +1338,15 @@ public void init(ServletConfig config) throws ServletException } @Override - public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException + public void service(ServletRequest request, ServletResponse res) throws ServletException, IOException { - Object oldRunAs = _identityService.setRunAs(_identityService.getSystemUserIdentity(), _runAsToken); + ServletContextRequest servletContextRequest = ServletContextRequest.getServletContextRequest(request); + Authentication authentication = servletContextRequest.getServletApiRequest().getAuthentication(); + UserIdentity userIdentity = (authentication instanceof Authentication.User user) ? user.getUserIdentity() : _identityService.getSystemUserIdentity(); + Object oldRunAs = _identityService.setRunAs(userIdentity, _runAsToken); try { - getWrapped().service(req, res); + getWrapped().service(request, res); } finally { From 62166342884f17f4ef4c6a5fddf18134d4c9ead0 Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 3 Mar 2023 16:27:06 +0100 Subject: [PATCH 015/129] WIP --- .../eclipse/jetty/security/Constraint.java | 113 +++++++++++------- .../security/DefaultIdentityService.java | 7 +- .../jetty/security/IdentityService.java | 11 +- .../jetty/security/SecurityHandler.java | 34 +++--- .../authentication/LoginCallback.java | 46 ------- .../security/internal/LoginCallbackImpl.java | 112 ----------------- .../security/internal/RoleRunAsToken.java | 4 +- .../jetty/security/internal/RunAsToken.java | 23 ---- .../security/BasicAuthenticatorTest.java | 2 +- .../jetty/security/FormAuthenticatorTest.java | 2 +- 10 files changed, 101 insertions(+), 253 deletions(-) delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index 997cbc646c35..b3495786fdc8 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -27,46 +27,46 @@ public interface Constraint { enum Transport { - CLEAR, - INTEGRAL, - CONFIDENTIAL; + REQUIRE_NONE, + REQUIRE_INTEGRAL, + REQUIRE_CONFIDENTIAL; static Transport combine(Transport a, Transport b) { if (a == null) - return b == null ? CLEAR : b; + return b == null ? REQUIRE_NONE : b; if (b == null) return a; return switch (b) { - case CLEAR -> a; - case INTEGRAL -> a == CONFIDENTIAL ? CONFIDENTIAL : INTEGRAL; - case CONFIDENTIAL -> CONFIDENTIAL; + case REQUIRE_NONE -> a; + case REQUIRE_INTEGRAL -> a == REQUIRE_CONFIDENTIAL ? REQUIRE_CONFIDENTIAL : REQUIRE_INTEGRAL; + case REQUIRE_CONFIDENTIAL -> REQUIRE_CONFIDENTIAL; }; } } - enum Authorization + enum Authentication { - NONE, - AUTHENTICATED, - AUTHENTICATED_IN_KNOWN_ROLE, - AUTHENTICATED_IN_ROLE; + REQUIRE_NONE, + REQUIRE, + REQUIRE_KNOWN_ROLE, + REQUIRE_SPECIFIC_ROLE; - static Authorization combine(Authorization a, Authorization b) + static Authentication combine(Authentication a, Authentication b) { if (a == null) - return b == null ? NONE : b; + return b == null ? REQUIRE_NONE : b; if (b == null) return a; return switch (b) { - case NONE -> a; - case AUTHENTICATED -> a == NONE ? AUTHENTICATED : a; - case AUTHENTICATED_IN_KNOWN_ROLE -> a == AUTHENTICATED_IN_ROLE ? AUTHENTICATED_IN_ROLE : AUTHENTICATED_IN_KNOWN_ROLE; - case AUTHENTICATED_IN_ROLE -> AUTHENTICATED_IN_ROLE; + case REQUIRE_NONE -> a; + case REQUIRE -> a == REQUIRE_NONE ? REQUIRE : a; + case REQUIRE_KNOWN_ROLE -> a == REQUIRE_SPECIFIC_ROLE ? REQUIRE_SPECIFIC_ROLE : REQUIRE_KNOWN_ROLE; + case REQUIRE_SPECIFIC_ROLE -> REQUIRE_SPECIFIC_ROLE; }; } } @@ -84,12 +84,12 @@ static Authorization combine(Authorization a, Authorization b) /** * @return The {@link Transport} criteria applied by this {@code Constraint}. */ - Transport getUserData(); + Transport getTransport(); /** - * @return The {@link Authorization} criteria applied by this {@code Constraint}. + * @return The {@link Authentication} criteria applied by this {@code Constraint}. */ - Authorization getAuthorization(); + Authentication getAuthentication(); /** * @return The set of roles applied by this {@code Constraint} or the empty set. @@ -106,7 +106,7 @@ class Builder private String _name; private boolean _forbidden; private Transport _transport; - private Authorization _authorization; + private Authentication _authentication; private Set _roles; public Builder() @@ -115,8 +115,8 @@ public Builder() Builder(Constraint constraint) { _forbidden = constraint.isForbidden(); - _transport = constraint.getUserData(); - _authorization = constraint.getAuthorization(); + _transport = constraint.getTransport(); + _authentication = constraint.getAuthentication(); _roles = constraint.getRoles(); } @@ -126,24 +126,44 @@ public Builder name(String name) return this; } + public String getName() + { + return _name; + } + public Builder forbidden(boolean forbidden) { _forbidden = forbidden; return this; } + public boolean isForbidden() + { + return _forbidden; + } + public Builder transport(Transport transport) { _transport = transport; return this; } - public Builder authorization(Authorization authorization) + public Transport getTransport() { - _authorization = authorization; + return _transport; + } + + public Builder authentication(Authentication authentication) + { + _authentication = authentication; return this; } + public Authentication getAuthentication() + { + return _authentication; + } + public Builder roles(String... roles) { if (roles != null && roles.length > 0) @@ -157,18 +177,23 @@ else if (!(_roles instanceof HashSet)) return this; } + public Set getRoles() + { + return _roles == null ? Collections.emptySet() : _roles; + } + public Constraint build() { - return from(_name, _forbidden, _transport, _authorization, _roles); + return from(_name, _forbidden, _transport, _authentication, _roles); } } - Constraint NONE = from(false, Transport.CLEAR, Authorization.NONE); + Constraint NONE = from(false, Transport.REQUIRE_NONE, Authentication.REQUIRE_NONE); Constraint FORBIDDEN = from(true, null, null); - Constraint INTEGRAL = from(false, Transport.INTEGRAL, null); - Constraint CONFIDENTIAL = from(false, Transport.CONFIDENTIAL, null); - Constraint AUTHENTICATED = from(false, null, Authorization.AUTHENTICATED); - Constraint AUTHENTICATED_IN_KNOWN_ROLE = from(false, null, Authorization.AUTHENTICATED_IN_KNOWN_ROLE); + Constraint INTEGRAL = from(false, Transport.REQUIRE_INTEGRAL, null); + Constraint CONFIDENTIAL = from(false, Transport.REQUIRE_CONFIDENTIAL, null); + Constraint AUTHENTICATED = from(false, null, Authentication.REQUIRE); + Constraint AUTHENTICATED_KNOWN_ROLE = from(false, null, Authentication.REQUIRE_KNOWN_ROLE); static Constraint combine(Constraint a, Constraint b) { @@ -185,29 +210,29 @@ else if (b.getRoles() != null || b.getRoles() != null) return from( a.isForbidden() || b.isForbidden(), - Transport.combine(a.getUserData(), b.getUserData()), - Authorization.combine(a.getAuthorization(), b.getAuthorization()), + Transport.combine(a.getTransport(), b.getTransport()), + Authentication.combine(a.getAuthentication(), b.getAuthentication()), roles); } static Constraint from(String... roles) { - return from(false, null, Authorization.AUTHENTICATED_IN_ROLE, roles); + return from(false, null, Authentication.REQUIRE_SPECIFIC_ROLE, roles); } - static Constraint from(boolean forbidden, Transport transport, Authorization authorization, String... roles) + static Constraint from(boolean forbidden, Transport transport, Authentication authentication, String... roles) { - return from(forbidden, transport, authorization, (roles == null || roles.length == 0) + return from(forbidden, transport, authentication, (roles == null || roles.length == 0) ? Collections.emptySet() : new HashSet<>(Arrays.stream(roles).toList())); } - static Constraint from(boolean forbidden, Transport transport, Authorization authorization, Set roles) + static Constraint from(boolean forbidden, Transport transport, Authentication authentication, Set roles) { - return from(null, forbidden, transport, authorization, roles); + return from(null, forbidden, transport, authentication, roles); } - static Constraint from(String name, boolean forbidden, Transport transport, Authorization authorization, Set roles) + static Constraint from(String name, boolean forbidden, Transport transport, Authentication authentication, Set roles) { Set roleSet = roles == null ? Collections.emptySet() @@ -228,15 +253,15 @@ public boolean isForbidden() } @Override - public Transport getUserData() + public Transport getTransport() { - return transport == null ? Transport.CLEAR : transport; + return transport == null ? Transport.REQUIRE_NONE : transport; } @Override - public Authorization getAuthorization() + public Authentication getAuthentication() { - return authorization == null ? Authorization.NONE : authorization; + return authentication == null ? Authentication.REQUIRE_NONE : authentication; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index 2f0b40e1af4e..4ba81c2bd587 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -18,7 +18,6 @@ import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.security.internal.RoleRunAsToken; -import org.eclipse.jetty.security.internal.RunAsToken; /** * @@ -39,7 +38,7 @@ public Association associate(UserIdentity user) } @Override - public Association associate(UserIdentity user, Object token) + public Association associate(UserIdentity user, Token token) { if (token instanceof RoleRunAsToken roleRunAsToken) { @@ -59,9 +58,9 @@ public void logout(UserIdentity user) } @Override - public RunAsToken newRunAsToken(String runAsName) + public Token newRunAsToken(String roleName) { - return new RoleRunAsToken(runAsName); + return new RoleRunAsToken(roleName); } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 42a61e3b0633..fcc0bd68b10c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -43,7 +43,7 @@ public interface IdentityService * @param token The runAsToken to associate, obtained from {@link #newRunAsToken(String)}. * @return A {@link Closeable} that, when closed, will disassociate the token and restore any prior associations. */ - Association associate(UserIdentity user, Object token); + Association associate(UserIdentity user, Token token); void logout(UserIdentity user); @@ -61,15 +61,18 @@ public interface IdentityService /** * Create a new RunAsToken from a runAsName (normally a role). * - * @param runAsName Normally a role name - * @return A token that can be passed to {@link #associate(UserIdentity, Object)}. + * @param roleName a role name + * @return A token that can be passed to {@link #associate(UserIdentity, Token)}. */ - Object newRunAsToken(String runAsName); + Token newRunAsToken(String roleName); UserIdentity getSystemUserIdentity(); interface Association extends AutoCloseable { + } + interface Token + { } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 8c35dea4b684..649e09ea0241 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -436,7 +436,7 @@ public boolean handle(Request request, Response response, Callback callback) thr return true; // is Auth mandatory? - boolean authMandatory = constraint.getAuthorization() != null && constraint.getAuthorization() != Constraint.Authorization.NONE; + boolean authMandatory = constraint.getAuthentication() != null && constraint.getAuthentication() != Constraint.Authentication.REQUIRE_NONE; if (authMandatory && authenticator == null) { LOG.warn("No authenticator for: {}", constraint); @@ -447,10 +447,10 @@ public boolean handle(Request request, Response response, Callback callback) thr // check authentication try { - Authentication authentication = Authentication.getAuthentication(request); - if (authentication == null || authentication == Authentication.NOT_CHECKED) + Authentication authentication = org.eclipse.jetty.security.Authentication.getAuthentication(request); + if (authentication == null || authentication == org.eclipse.jetty.security.Authentication.NOT_CHECKED) authentication = authenticator == null - ? Authentication.UNAUTHENTICATED + ? org.eclipse.jetty.security.Authentication.UNAUTHENTICATED : authenticator.validateRequest(request, response, callback, authMandatory); if (authentication instanceof Authentication.ResponseSent) @@ -458,7 +458,7 @@ public boolean handle(Request request, Response response, Callback callback) thr if (authentication instanceof Authentication.User userAuth) { - Authentication.setAuthentication(request, authentication); + org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); try (AutoCloseable association = _identityService.associate(userAuth.getUserIdentity())) { if (authMandatory) @@ -483,7 +483,7 @@ public boolean handle(Request request, Response response, Callback callback) thr if (authentication instanceof DeferredAuthentication deferred) { - Authentication.setAuthentication(request, authentication); + org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); boolean handled; try @@ -493,7 +493,7 @@ public boolean handle(Request request, Response response, Callback callback) thr if (handled && authenticator != null) { - Authentication auth = Authentication.getAuthentication(request); + Authentication auth = org.eclipse.jetty.security.Authentication.getAuthentication(request); if (auth instanceof Authentication.User userAuth) authenticator.secureResponse(request, response, callback, authMandatory, userAuth); else @@ -515,7 +515,7 @@ public boolean handle(Request request, Response response, Callback callback) thr return true; } - Authentication.setAuthentication(request, authentication); + org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); //process the request by other handlers boolean handled = next.handle(request, response, callback); @@ -560,8 +560,8 @@ public void logout(Authentication.User user) protected boolean checkUserData(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException { - Constraint.Transport dataConstraint = constraint.getUserData(); - if (dataConstraint == null || dataConstraint == Constraint.Transport.CLEAR) + Constraint.Transport dataConstraint = constraint.getTransport(); + if (dataConstraint == null || dataConstraint == Constraint.Transport.REQUIRE_NONE) return true; HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); @@ -589,17 +589,17 @@ protected boolean checkUserData(String pathInContext, Request request, Response protected boolean checkAuthorization(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) { - Constraint.Authorization authorization = constraint.getAuthorization(); - if (authorization == null) + Constraint.Authentication authentication = constraint.getAuthentication(); + if (authentication == null) return true; - return switch (constraint.getAuthorization()) + return switch (constraint.getAuthentication()) { - case NONE -> true; + case REQUIRE_NONE -> true; - case AUTHENTICATED -> userIdentity.getUserPrincipal() != null; + case REQUIRE -> userIdentity.getUserPrincipal() != null; - case AUTHENTICATED_IN_KNOWN_ROLE -> + case REQUIRE_KNOWN_ROLE -> { if (userIdentity.getUserPrincipal() != null) for (String role : getKnownRoles()) @@ -608,7 +608,7 @@ protected boolean checkAuthorization(String pathInContext, Request request, Resp yield false; } - case AUTHENTICATED_IN_ROLE -> + case REQUIRE_SPECIFIC_ROLE -> { if (userIdentity.getUserPrincipal() != null) for (String role : constraint.getRoles()) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java deleted file mode 100644 index e4d6514cfe9c..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginCallback.java +++ /dev/null @@ -1,46 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security.authentication; - -import java.security.Principal; -import javax.security.auth.Subject; - -/** - * This is similar to the jaspi PasswordValidationCallback but includes user - * principal and group info as well. - * - * @version $Rev: 4792 $ $Date: 2009-03-18 22:55:52 +0100 (Wed, 18 Mar 2009) $ - */ -public interface LoginCallback -{ - public Subject getSubject(); - - public String getUserName(); - - public Object getCredential(); - - public boolean isSuccess(); - - public void setSuccess(boolean success); - - public Principal getUserPrincipal(); - - public void setUserPrincipal(Principal userPrincipal); - - public String[] getRoles(); - - public void setRoles(String[] roles); - - public void clearPassword(); -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java deleted file mode 100644 index 3eb1add82930..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/LoginCallbackImpl.java +++ /dev/null @@ -1,112 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security.internal; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.security.authentication.LoginCallback; - -/** - * This is similar to the jaspi PasswordValidationCallback but includes user - * principal and group info as well. - * - * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ - */ -public class LoginCallbackImpl implements LoginCallback -{ - // initial data - private final Subject subject; - - private final String userName; - - private Object credential; - - private boolean success; - - private Principal userPrincipal; - - private String[] roles = new String[0]; - - //TODO could use Credential instance instead of Object if Basic/Form create a Password object - public LoginCallbackImpl(Subject subject, String userName, Object credential) - { - this.subject = subject; - this.userName = userName; - this.credential = credential; - } - - @Override - public Subject getSubject() - { - return subject; - } - - @Override - public String getUserName() - { - return userName; - } - - @Override - public Object getCredential() - { - return credential; - } - - @Override - public boolean isSuccess() - { - return success; - } - - @Override - public void setSuccess(boolean success) - { - this.success = success; - } - - @Override - public Principal getUserPrincipal() - { - return userPrincipal; - } - - @Override - public void setUserPrincipal(Principal userPrincipal) - { - this.userPrincipal = userPrincipal; - } - - @Override - public String[] getRoles() - { - return roles; - } - - @Override - public void setRoles(String[] groups) - { - this.roles = groups; - } - - @Override - public void clearPassword() - { - if (credential != null) - { - credential = null; - } - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java index 848b0364180e..1b49fccc3e48 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java @@ -13,10 +13,12 @@ package org.eclipse.jetty.security.internal; +import org.eclipse.jetty.security.IdentityService; + /** * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ */ -public class RoleRunAsToken implements RunAsToken +public class RoleRunAsToken implements IdentityService.Token { private final String _runAsRole; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java deleted file mode 100644 index e0f9423d8290..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RunAsToken.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security.internal; - -/** - * marker interface for run-as-role tokens - * - * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ - */ -public interface RunAsToken -{ -} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index 820f986e7ef5..ca370701d943 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -98,7 +98,7 @@ public boolean isSecure() _securityHandler.add("/admin/*", Constraint.from("admin")); _securityHandler.add("/any/*", Constraint.AUTHENTICATED); - _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); + _securityHandler.add("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); _securityHandler.setAuthenticator(new BasicAuthenticator()); _server.start(); } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index cbeec3724a94..d35d58210a10 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -102,7 +102,7 @@ public boolean isSecure() _securityHandler.add("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed _securityHandler.add("/any/*", Constraint.AUTHENTICATED); - _securityHandler.add("/known/*", Constraint.AUTHENTICATED_IN_KNOWN_ROLE); + _securityHandler.add("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); _securityHandler.add("/admin/*", Constraint.from("admin")); _securityHandler.setAuthenticator(new FormAuthenticator("/login", "/error", false)); _server.start(); From 8044355af6affed91c663679093371c62d8d1787 Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 3 Mar 2023 20:15:51 +0100 Subject: [PATCH 016/129] WIP --- .../eclipse/jetty/security/Authenticator.java | 61 ++- .../eclipse/jetty/security/Constraint.java | 69 ++-- .../security/DefaultAuthenticatorFactory.java | 42 +- .../security/DefaultIdentityService.java | 6 +- .../jetty/security/IdentityService.java | 10 +- .../jetty/security/SecurityHandler.java | 24 +- .../security/WrappedAuthConfiguration.java | 74 ---- .../authentication/BasicAuthenticator.java | 4 +- .../ClientCertAuthenticator.java | 361 ------------------ .../ConfigurableSpnegoAuthenticator.java | 4 +- .../authentication/DigestAuthenticator.java | 4 +- .../authentication/FormAuthenticator.java | 4 +- .../SslClientCertAuthenticator.java | 3 +- .../security/internal/RoleRunAsToken.java | 2 +- .../jetty/security/SecurityHandlerTest.java | 11 - 15 files changed, 121 insertions(+), 558 deletions(-) delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 036e852a2a90..2d534a51d8be 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -34,6 +34,13 @@ */ public interface Authenticator { + String BASIC_AUTH = "BASIC"; + String FORM_AUTH = "FORM"; + String DIGEST_AUTH = "DIGEST"; + String CERT_AUTH = "CLIENT_CERT"; + String SPNEGO_AUTH = "SPNEGO"; + String NEGOTIATE_AUTH = "NEGOTIATE"; + String OPENID_AUTH = "OPENID"; /** * Configure the Authenticator @@ -125,6 +132,58 @@ interface AuthConfiguration IdentityService getIdentityService(); boolean isSessionRenewedOnAuthentication(); + + class Wrapper implements AuthConfiguration + { + private final AuthConfiguration _configuration; + + public Wrapper(AuthConfiguration configuration) + { + _configuration = configuration; + } + + @Override + public String getAuthMethod() + { + return _configuration.getAuthMethod(); + } + + @Override + public String getRealmName() + { + return _configuration.getRealmName(); + } + + @Override + public String getParameter(String param) + { + return _configuration.getParameter(param); + } + + @Override + public Set getParameterNames() + { + return _configuration.getParameterNames(); + } + + @Override + public LoginService getLoginService() + { + return _configuration.getLoginService(); + } + + @Override + public IdentityService getIdentityService() + { + return _configuration.getIdentityService(); + } + + @Override + public boolean isSessionRenewedOnAuthentication() + { + return _configuration.isSessionRenewedOnAuthentication(); + } + } } /** @@ -132,6 +191,6 @@ interface AuthConfiguration */ interface Factory { - Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService); + Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration); } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java index b3495786fdc8..710e47b54ec8 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Constraint.java @@ -25,28 +25,6 @@ */ public interface Constraint { - enum Transport - { - REQUIRE_NONE, - REQUIRE_INTEGRAL, - REQUIRE_CONFIDENTIAL; - - static Transport combine(Transport a, Transport b) - { - if (a == null) - return b == null ? REQUIRE_NONE : b; - if (b == null) - return a; - - return switch (b) - { - case REQUIRE_NONE -> a; - case REQUIRE_INTEGRAL -> a == REQUIRE_CONFIDENTIAL ? REQUIRE_CONFIDENTIAL : REQUIRE_INTEGRAL; - case REQUIRE_CONFIDENTIAL -> REQUIRE_CONFIDENTIAL; - }; - } - } - enum Authentication { REQUIRE_NONE, @@ -82,9 +60,9 @@ static Authentication combine(Authentication a, Authentication b) boolean isForbidden(); /** - * @return The {@link Transport} criteria applied by this {@code Constraint}. + * @return {@code True} if the transport must be confidential. */ - Transport getTransport(); + boolean isConfidential(); /** * @return The {@link Authentication} criteria applied by this {@code Constraint}. @@ -105,7 +83,7 @@ class Builder { private String _name; private boolean _forbidden; - private Transport _transport; + private boolean _confidential; private Authentication _authentication; private Set _roles; @@ -115,7 +93,7 @@ public Builder() Builder(Constraint constraint) { _forbidden = constraint.isForbidden(); - _transport = constraint.getTransport(); + _confidential = constraint.isConfidential(); _authentication = constraint.getAuthentication(); _roles = constraint.getRoles(); } @@ -142,15 +120,15 @@ public boolean isForbidden() return _forbidden; } - public Builder transport(Transport transport) + public Builder confidential(boolean confidential) { - _transport = transport; + _confidential = confidential; return this; } - public Transport getTransport() + public boolean isConfidential() { - return _transport; + return _confidential; } public Builder authentication(Authentication authentication) @@ -184,16 +162,15 @@ public Set getRoles() public Constraint build() { - return from(_name, _forbidden, _transport, _authentication, _roles); + return from(_name, _forbidden, _confidential, _authentication, _roles); } } - Constraint NONE = from(false, Transport.REQUIRE_NONE, Authentication.REQUIRE_NONE); - Constraint FORBIDDEN = from(true, null, null); - Constraint INTEGRAL = from(false, Transport.REQUIRE_INTEGRAL, null); - Constraint CONFIDENTIAL = from(false, Transport.REQUIRE_CONFIDENTIAL, null); - Constraint AUTHENTICATED = from(false, null, Authentication.REQUIRE); - Constraint AUTHENTICATED_KNOWN_ROLE = from(false, null, Authentication.REQUIRE_KNOWN_ROLE); + Constraint NONE = from(false, false, Authentication.REQUIRE_NONE); + Constraint FORBIDDEN = from(true, false, null); + Constraint CONFIDENTIAL = from(false, true, null); + Constraint AUTHENTICATED = from(false, false, Authentication.REQUIRE); + Constraint AUTHENTICATED_KNOWN_ROLE = from(false, false, Authentication.REQUIRE_KNOWN_ROLE); static Constraint combine(Constraint a, Constraint b) { @@ -210,29 +187,29 @@ else if (b.getRoles() != null || b.getRoles() != null) return from( a.isForbidden() || b.isForbidden(), - Transport.combine(a.getTransport(), b.getTransport()), + a.isConfidential() || b.isConfidential(), Authentication.combine(a.getAuthentication(), b.getAuthentication()), roles); } static Constraint from(String... roles) { - return from(false, null, Authentication.REQUIRE_SPECIFIC_ROLE, roles); + return from(false, false, Authentication.REQUIRE_SPECIFIC_ROLE, roles); } - static Constraint from(boolean forbidden, Transport transport, Authentication authentication, String... roles) + static Constraint from(boolean forbidden, boolean confidential, Authentication authentication, String... roles) { - return from(forbidden, transport, authentication, (roles == null || roles.length == 0) + return from(forbidden, confidential, authentication, (roles == null || roles.length == 0) ? Collections.emptySet() : new HashSet<>(Arrays.stream(roles).toList())); } - static Constraint from(boolean forbidden, Transport transport, Authentication authentication, Set roles) + static Constraint from(boolean forbidden, boolean confidential, Authentication authentication, Set roles) { - return from(null, forbidden, transport, authentication, roles); + return from(null, forbidden, confidential, authentication, roles); } - static Constraint from(String name, boolean forbidden, Transport transport, Authentication authentication, Set roles) + static Constraint from(String name, boolean forbidden, boolean confidential, Authentication authentication, Set roles) { Set roleSet = roles == null ? Collections.emptySet() @@ -253,9 +230,9 @@ public boolean isForbidden() } @Override - public Transport getTransport() + public boolean isConfidential() { - return transport == null ? Transport.REQUIRE_NONE : transport; + return confidential; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java index 4d123d1d7e83..ad7b39168009 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultAuthenticatorFactory.java @@ -17,7 +17,6 @@ import org.eclipse.jetty.security.Authenticator.AuthConfiguration; import org.eclipse.jetty.security.authentication.BasicAuthenticator; -import org.eclipse.jetty.security.authentication.ClientCertAuthenticator; import org.eclipse.jetty.security.authentication.ConfigurableSpnegoAuthenticator; import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.security.authentication.DigestAuthenticator; @@ -27,10 +26,7 @@ import org.eclipse.jetty.security.authentication.SslClientCertAuthenticator; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * The Default Authenticator Factory. @@ -38,8 +34,8 @@ *
  • {@link BasicAuthenticator}
  • *
  • {@link DigestAuthenticator}
  • *
  • {@link FormAuthenticator}
  • - *
  • {@link ClientCertAuthenticator}
  • *
  • {@link SslClientCertAuthenticator}
  • + *
  • {@link ConfigurableSpnegoAuthenticator}
  • * * All authenticators derived from {@link LoginAuthenticator} are * wrapped with a {@link DeferredAuthentication} @@ -54,46 +50,30 @@ */ public class DefaultAuthenticatorFactory implements Authenticator.Factory { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultAuthenticatorFactory.class); - LoginService _loginService; @Override - public Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration, IdentityService identityService, LoginService loginService) + public Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration) { String auth = configuration.getAuthMethod(); Authenticator authenticator = null; - if (Constraint.__BASIC_AUTH.equalsIgnoreCase(auth)) + if (Authenticator.BASIC_AUTH.equalsIgnoreCase(auth)) authenticator = new BasicAuthenticator(); - else if (Constraint.__DIGEST_AUTH.equalsIgnoreCase(auth)) + else if (Authenticator.DIGEST_AUTH.equalsIgnoreCase(auth)) authenticator = new DigestAuthenticator(); - else if (Constraint.__FORM_AUTH.equalsIgnoreCase(auth)) + else if (Authenticator.FORM_AUTH.equalsIgnoreCase(auth)) authenticator = new FormAuthenticator(); - else if (Constraint.__SPNEGO_AUTH.equalsIgnoreCase(auth)) + else if (Authenticator.SPNEGO_AUTH.equalsIgnoreCase(auth)) authenticator = new ConfigurableSpnegoAuthenticator(); - else if (Constraint.__NEGOTIATE_AUTH.equalsIgnoreCase(auth)) // see Bug #377076 - authenticator = new ConfigurableSpnegoAuthenticator(Constraint.__NEGOTIATE_AUTH); - if (Constraint.__CERT_AUTH.equalsIgnoreCase(auth) || Constraint.__CERT_AUTH2.equalsIgnoreCase(auth)) + else if (Authenticator.NEGOTIATE_AUTH.equalsIgnoreCase(auth)) // see Bug #377076 + authenticator = new ConfigurableSpnegoAuthenticator(Authenticator.NEGOTIATE_AUTH); + if (Authenticator.CERT_AUTH.equalsIgnoreCase(auth)) { Collection sslContextFactories = server.getBeans(SslContextFactory.class); if (sslContextFactories.size() != 1) - { - if (sslContextFactories.size() > 1) - { - LOG.info("Multiple SslContextFactory instances discovered. Directly configure a SslClientCertAuthenticator to use one."); - } - else - { - LOG.debug("No SslContextFactory instances discovered. Directly configure a SslClientCertAuthenticator to use one."); - } - authenticator = new ClientCertAuthenticator(); - } - else - { - authenticator = new SslClientCertAuthenticator(sslContextFactories.iterator().next()); - } + throw new IllegalStateException("SslClientCertAuthenticator requires a single SslContextFactory instances."); + authenticator = new SslClientCertAuthenticator(sslContextFactories.iterator().next()); } return authenticator; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java index 4ba81c2bd587..fe340352fd8a 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/DefaultIdentityService.java @@ -38,9 +38,9 @@ public Association associate(UserIdentity user) } @Override - public Association associate(UserIdentity user, Token token) + public Association associate(UserIdentity user, RunAsToken runAsToken) { - if (token instanceof RoleRunAsToken roleRunAsToken) + if (runAsToken instanceof RoleRunAsToken roleRunAsToken) { String oldAssociate = runAsRole.get(); runAsRole.set(roleRunAsToken.getRunAsRole()); @@ -58,7 +58,7 @@ public void logout(UserIdentity user) } @Override - public Token newRunAsToken(String roleName) + public RunAsToken newRunAsToken(String roleName) { return new RoleRunAsToken(roleName); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index fcc0bd68b10c..4432ebfa188e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -40,10 +40,10 @@ public interface IdentityService * Associate a runas Token with the current user and thread. * * @param user The UserIdentity - * @param token The runAsToken to associate, obtained from {@link #newRunAsToken(String)}. + * @param runAsToken The runAsToken to associate, obtained from {@link #newRunAsToken(String)}. * @return A {@link Closeable} that, when closed, will disassociate the token and restore any prior associations. */ - Association associate(UserIdentity user, Token token); + Association associate(UserIdentity user, RunAsToken runAsToken); void logout(UserIdentity user); @@ -62,9 +62,9 @@ public interface IdentityService * Create a new RunAsToken from a runAsName (normally a role). * * @param roleName a role name - * @return A token that can be passed to {@link #associate(UserIdentity, Token)}. + * @return A token that can be passed to {@link #associate(UserIdentity, RunAsToken)}. */ - Token newRunAsToken(String roleName); + RunAsToken newRunAsToken(String roleName); UserIdentity getSystemUserIdentity(); @@ -72,7 +72,7 @@ interface Association extends AutoCloseable { } - interface Token + interface RunAsToken { } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 649e09ea0241..7bebff977f67 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -50,10 +50,10 @@ * Select and apply an {@link Authenticator} to a request. *

    * The Authenticator may either be directly set on the handler - * or will be create during {@link #start()} with a call to + * or it will be created during {@link #start()} with a call to * either the default or set AuthenticatorFactory. *

    - * SecurityHandler has a set of initparameters that are used by the + * SecurityHandler has a set of parameters that are used by the * Authentication.Configuration. At startup, any context init parameters * that start with "org.eclipse.jetty.security." that do not have * values in the SecurityHandler init parameters, are copied. @@ -65,7 +65,6 @@ public abstract class SecurityHandler extends Handler.Wrapper implements AuthCon private static final Logger LOG = LoggerFactory.getLogger(SecurityHandler.class); private static final List __knownAuthenticatorFactories = new ArrayList<>(); - private boolean _checkWelcomeFiles = false; private Authenticator _authenticator; private Authenticator.Factory _authenticatorFactory; private String _realmName; @@ -327,7 +326,7 @@ else if (_loginService.getIdentityService() != _identityService) if (_authenticatorFactory != null) { Authenticator authenticator = _authenticatorFactory.getAuthenticator(getServer(), context, - this, _identityService, _loginService); + this); if (authenticator != null) { @@ -342,7 +341,7 @@ else if (_loginService.getIdentityService() != _identityService) for (Authenticator.Factory factory : getKnownAuthenticatorFactories()) { Authenticator authenticator = factory.getAuthenticator(getServer(), context, - this, _identityService, _loginService); + this); if (authenticator != null) { @@ -432,7 +431,7 @@ public boolean handle(Request request, Response response, Callback callback) thr } // Check data constraints - if (!checkUserData(pathInContext, request, response, callback, constraint)) + if (!checkTransport(pathInContext, request, response, callback, constraint)) return true; // is Auth mandatory? @@ -463,7 +462,7 @@ public boolean handle(Request request, Response response, Callback callback) thr { if (authMandatory) { - boolean authorized = checkAuthorization(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); + boolean authorized = checkAuthentication(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); if (!authorized) { Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!role"); @@ -558,17 +557,12 @@ public void logout(Authentication.User user) protected abstract Constraint getConstraint(String pathInContext, Request request); - protected boolean checkUserData(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException + protected boolean checkTransport(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException { - Constraint.Transport dataConstraint = constraint.getTransport(); - if (dataConstraint == null || dataConstraint == Constraint.Transport.REQUIRE_NONE) + if (request.isSecure() || !constraint.isConfidential()) return true; HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); - - if (request.isSecure()) - return true; - if (httpConfig.getSecurePort() > 0) { //Redirect to secure port @@ -587,7 +581,7 @@ protected boolean checkUserData(String pathInContext, Request request, Response return false; } - protected boolean checkAuthorization(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) + protected boolean checkAuthentication(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) { Constraint.Authentication authentication = constraint.getAuthentication(); if (authentication == null) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java deleted file mode 100644 index adfea3b58fc0..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import java.util.Set; - -import org.eclipse.jetty.security.Authenticator.AuthConfiguration; - -/** - * A wrapper for {@link AuthConfiguration}. This allows you create a new AuthConfiguration which can - * override a method to change a value from an another instance of AuthConfiguration. - */ -public class WrappedAuthConfiguration implements AuthConfiguration -{ - private final AuthConfiguration _configuration; - - public WrappedAuthConfiguration(AuthConfiguration configuration) - { - _configuration = configuration; - } - - @Override - public String getAuthMethod() - { - return _configuration.getAuthMethod(); - } - - @Override - public String getRealmName() - { - return _configuration.getRealmName(); - } - - @Override - public String getParameter(String param) - { - return _configuration.getParameter(param); - } - - @Override - public Set getParameterNames() - { - return _configuration.getParameterNames(); - } - - @Override - public LoginService getLoginService() - { - return _configuration.getLoginService(); - } - - @Override - public IdentityService getIdentityService() - { - return _configuration.getIdentityService(); - } - - @Override - public boolean isSessionRenewedOnAuthentication() - { - return _configuration.isSessionRenewedOnAuthentication(); - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index b41fe67cfb7e..337c15d3bd19 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -20,13 +20,13 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.security.Constraint; public class BasicAuthenticator extends LoginAuthenticator { @@ -45,7 +45,7 @@ public void setCharset(Charset charset) @Override public String getAuthMethod() { - return Constraint.__BASIC_AUTH; + return Authenticator.BASIC_AUTH; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java deleted file mode 100644 index de923088e912..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ClientCertAuthenticator.java +++ /dev/null @@ -1,361 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security.authentication; - -import java.security.KeyStore; -import java.security.Principal; -import java.security.cert.CRL; -import java.security.cert.X509Certificate; -import java.util.Base64; -import java.util.Collection; - -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.security.Authentication; -import org.eclipse.jetty.security.ServerAuthException; -import org.eclipse.jetty.security.UserAuthentication; -import org.eclipse.jetty.security.UserIdentity; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.util.security.CertificateUtils; -import org.eclipse.jetty.util.security.CertificateValidator; -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.util.security.Password; - -/** - * @deprecated Prefer using {@link SslClientCertAuthenticator} - */ -@Deprecated -public class ClientCertAuthenticator extends LoginAuthenticator -{ - /** - * String name of keystore password property. - */ - private static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password"; - - /** - * Truststore path - */ - private String _trustStorePath; - /** - * Truststore provider name - */ - private String _trustStoreProvider; - /** - * Truststore type - */ - private String _trustStoreType = "PKCS12"; - /** - * Truststore password - */ - private transient Password _trustStorePassword; - - /** - * Set to true if SSL certificate validation is required - */ - private boolean _validateCerts; - /** - * Path to file that contains Certificate Revocation List - */ - private String _crlPath; - /** - * Maximum certification path length (n - number of intermediate certs, -1 for unlimited) - */ - private int _maxCertPathLength = -1; - /** - * CRL Distribution Points (CRLDP) support - */ - private boolean _enableCRLDP = false; - /** - * On-Line Certificate Status Protocol (OCSP) support - */ - private boolean _enableOCSP = false; - /** - * Location of OCSP Responder - */ - private String _ocspResponderURL; - - public ClientCertAuthenticator() - { - super(); - } - - @Override - public String getAuthMethod() - { - return Constraint.__CERT_AUTH; - } - - @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException - { - if (!mandatory) - return new DeferredAuthentication(this); - - X509Certificate[] certs = (X509Certificate[])req.getAttribute("jakarta.servlet.request.X509Certificate"); - - try - { - // Need certificates. - if (certs != null && certs.length > 0) - { - - if (_validateCerts) - { - KeyStore trustStore = getKeyStore( - _trustStorePath, _trustStoreType, _trustStoreProvider, - _trustStorePassword == null ? null : _trustStorePassword.toString()); - Collection crls = loadCRL(_crlPath); - CertificateValidator validator = new CertificateValidator(trustStore, crls); - validator.validate(certs); - } - - for (X509Certificate cert : certs) - { - if (cert == null) - continue; - - Principal principal = cert.getSubjectDN(); - if (principal == null) - principal = cert.getIssuerDN(); - final String username = principal == null ? "clientcert" : principal.getName(); - - // TODO: investigate if using a raw byte[] is better vs older char[] - final char[] credential = Base64.getEncoder().encodeToString(cert.getSignature()).toCharArray(); - - UserIdentity user = login(username, credential, req, res); - if (user != null) - { - return new UserAuthentication(getAuthMethod(), user); - } - } - } - - if (!DeferredAuthentication.isDeferred(res)) - { - Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); - return Authentication.SEND_FAILURE; - } - - return Authentication.UNAUTHENTICATED; - } - catch (Exception e) - { - throw new ServerAuthException(e.getMessage()); - } - } - - /** - * Loads keystore using an input stream or a file path in the same - * order of precedence. - * - * Required for integrations to be able to override the mechanism - * used to load a keystore in order to provide their own implementation. - * - * @param storePath path of keystore file - * @param storeType keystore type - * @param storeProvider keystore provider - * @param storePassword keystore password - * @return created keystore - * @throws Exception if unable to get keystore - */ - protected KeyStore getKeyStore(String storePath, String storeType, String storeProvider, String storePassword) throws Exception - { - try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) - { - return CertificateUtils.getKeyStore(resourceFactory.newResource(storePath), storeType, storeProvider, storePassword); - } - } - - /** - * Loads certificate revocation list (CRL) from a file. - * - * Required for integrations to be able to override the mechanism used to - * load CRL in order to provide their own implementation. - * - * @param crlPath path of certificate revocation list file - * @return a (possibly empty) collection view of java.security.cert.CRL objects initialized with the data from the - * input stream. - * @throws Exception if unable to load CRL - */ - protected Collection loadCRL(String crlPath) throws Exception - { - return CertificateUtils.loadCRL(crlPath); - } - - /** - * @return true if SSL certificate has to be validated - */ - public boolean isValidateCerts() - { - return _validateCerts; - } - - /** - * @param validateCerts true if SSL certificates have to be validated - */ - public void setValidateCerts(boolean validateCerts) - { - _validateCerts = validateCerts; - } - - /** - * @return The file name or URL of the trust store location - */ - public String getTrustStore() - { - return _trustStorePath; - } - - /** - * @param trustStorePath The file name or URL of the trust store location - */ - public void setTrustStore(String trustStorePath) - { - _trustStorePath = trustStorePath; - } - - /** - * @return The provider of the trust store - */ - public String getTrustStoreProvider() - { - return _trustStoreProvider; - } - - /** - * @param trustStoreProvider The provider of the trust store - */ - public void setTrustStoreProvider(String trustStoreProvider) - { - _trustStoreProvider = trustStoreProvider; - } - - /** - * @return The type of the trust store (default "PKCS12") - */ - public String getTrustStoreType() - { - return _trustStoreType; - } - - /** - * @param trustStoreType The type of the trust store - */ - public void setTrustStoreType(String trustStoreType) - { - _trustStoreType = trustStoreType; - } - - /** - * @param password The password for the trust store - */ - public void setTrustStorePassword(String password) - { - _trustStorePassword = Password.getPassword(PASSWORD_PROPERTY, password, null); - } - - /** - * Get the crlPath. - * - * @return the crlPath - */ - public String getCrlPath() - { - return _crlPath; - } - - /** - * Set the crlPath. - * - * @param crlPath the crlPath to set - */ - public void setCrlPath(String crlPath) - { - _crlPath = crlPath; - } - - /** - * @return Maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public int getMaxCertPathLength() - { - return _maxCertPathLength; - } - - /** - * @param maxCertPathLength maximum number of intermediate certificates in - * the certification path (-1 for unlimited) - */ - public void setMaxCertPathLength(int maxCertPathLength) - { - _maxCertPathLength = maxCertPathLength; - } - - /** - * @return true if CRL Distribution Points support is enabled - */ - public boolean isEnableCRLDP() - { - return _enableCRLDP; - } - - /** - * Enables CRL Distribution Points Support - * - * @param enableCRLDP true - turn on, false - turns off - */ - public void setEnableCRLDP(boolean enableCRLDP) - { - _enableCRLDP = enableCRLDP; - } - - /** - * @return true if On-Line Certificate Status Protocol support is enabled - */ - public boolean isEnableOCSP() - { - return _enableOCSP; - } - - /** - * Enables On-Line Certificate Status Protocol support - * - * @param enableOCSP true - turn on, false - turn off - */ - public void setEnableOCSP(boolean enableOCSP) - { - _enableOCSP = enableOCSP; - } - - /** - * @return Location of the OCSP Responder - */ - public String getOcspResponderURL() - { - return _ocspResponderURL; - } - - /** - * Set the location of the OCSP Responder. - * - * @param ocspResponderURL location of the OCSP Responder - */ - public void setOcspResponderURL(String ocspResponderURL) - { - _ocspResponderURL = ocspResponderURL; - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index 796c0a7ed0f3..5f08a943dcb2 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -21,6 +21,7 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.ConfigurableSpnegoLoginService; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.SpnegoUserIdentity; @@ -31,7 +32,6 @@ import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +52,7 @@ public class ConfigurableSpnegoAuthenticator extends LoginAuthenticator public ConfigurableSpnegoAuthenticator() { - this(Constraint.__SPNEGO_AUTH); + this(Authenticator.SPNEGO_AUTH); } /** diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index f8c17784d786..0faeeedb2002 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -27,6 +27,7 @@ import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; @@ -36,7 +37,6 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.security.Credential; import org.eclipse.jetty.util.thread.AutoLock; import org.slf4j.Logger; @@ -93,7 +93,7 @@ public void setMaxNonceAge(long maxNonceAgeInMillis) @Override public String getAuthMethod() { - return Constraint.__DIGEST_AUTH; + return Authenticator.DIGEST_AUTH; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index c2b11fed3245..5bbc97f8b604 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -22,6 +22,7 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -33,7 +34,6 @@ import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,7 +120,7 @@ public void setConfiguration(AuthConfiguration configuration) @Override public String getAuthMethod() { - return Constraint.__FORM_AUTH; + return Authenticator.FORM_AUTH; } private void setLoginPage(String path) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java index b97d1930be15..db8171b773a8 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -29,7 +29,6 @@ import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.SecureRequestCustomizer.SslSessionData; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; /** @@ -52,7 +51,7 @@ public SslClientCertAuthenticator(SslContextFactory sslContextFactory) @Override public String getAuthMethod() { - return Constraint.__CERT_AUTH; + return Authenticator.CERT_AUTH; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java index 1b49fccc3e48..17ee2d04aad1 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/RoleRunAsToken.java @@ -18,7 +18,7 @@ /** * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ */ -public class RoleRunAsToken implements IdentityService.Token +public class RoleRunAsToken implements IdentityService.RunAsToken { private final String _runAsRole; diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 3d2410925eab..1e9f3eee1a9c 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -123,7 +123,6 @@ public void testForbidden() throws Exception @Test public void testUserData() throws Exception { - _securityHandler.add("/integral/*", Constraint.INTEGRAL); _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); String response; @@ -131,16 +130,6 @@ public void testUserData() throws Exception assertThat(response, containsString("HTTP/1.1 200 OK")); assertThat(response, containsString("You are OK")); - response = _connector.getResponse("GET /ctx/integral/info HTTP/1.0\r\n\r\n"); - assertThat(response, containsString("HTTP/1.1 302 Found")); - assertThat(response, containsString("Location: BWTP://")); - assertThat(response, containsString(":9999")); - assertThat(response, not(containsString("You are OK"))); - - response = _connectorS.getResponse("GET /ctx/integral/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); - assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("UNAUTHENTICATED is not OK")); - response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 302 Found")); assertThat(response, containsString("Location: BWTP://")); From 22fe002472ca3e2450c5797eacf11c32192531ce Mon Sep 17 00:00:00 2001 From: gregw Date: Sat, 4 Mar 2023 06:40:47 +0100 Subject: [PATCH 017/129] WIP --- .../security/AbstractUserAuthentication.java | 32 ----- .../eclipse/jetty/security/Authenticator.java | 7 +- .../jetty/security/SecurityHandler.java | 6 +- .../authentication/FormAuthenticator.java | 124 +----------------- .../SslClientCertAuthenticator.java | 2 - .../internal/DefaultUserIdentity.java | 4 - .../security/BasicAuthenticatorTest.java | 6 +- .../jetty/security/FormAuthenticatorTest.java | 8 +- .../jetty/security/SecurityHandlerTest.java | 16 +-- 9 files changed, 27 insertions(+), 178 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index 725e1fbc6593..56d0a661fb53 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -52,41 +52,9 @@ public UserIdentity getUserIdentity() @Override public boolean isUserInRole(String role) { - /* TODO move to somewhere in ee - //Servlet Spec 3.1 pg 125 if testing special role ** - if ("**".equals(role.trim())) - { - //if ** is NOT a declared role name, the we return true - //as the user is authenticated. If ** HAS been declared as a - //role name, then we have to check if the user has that role - if (!declaredRolesContains("**")) - return true; - else - return _userIdentity.isUserInRole(role); - } - */ - return _userIdentity.isUserInRole(role); } - /* TODO remove this - public boolean declaredRolesContains(String roleName) - { - SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); - if (security == null) - return false; - - if (security instanceof ConstraintAware) - { - xxx; Set declaredRoles = ((ConstraintAware)security).getRoles(); - return (declaredRoles != null) && declaredRoles.contains(roleName); - } - - return false; - } - - */ - @Override public Authentication logout(Request request) { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 2d534a51d8be..014fd5f771e7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -58,11 +58,8 @@ public interface Authenticator * Called prior to validateRequest. The authenticator can * manipulate the request to update it with information that * can be inspected prior to validateRequest being called. - * The primary purpose of this method is to satisfy the Servlet - * Spec 3.1 section 13.6.3 on handling Form authentication - * where the http method of the original request causing authentication - * is not the same as the http method resulting from the redirect - * after authentication. + * This may be restore method or content from a previous request + * that was challenged. * * @param request the request to prepare for authentication */ diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 7bebff977f67..72c889312e01 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -685,12 +685,12 @@ public Mapped() { } - public Constraint add(String pathSpec, Constraint constraint) + public Constraint put(String pathSpec, Constraint constraint) { - return add(PathSpec.from(pathSpec), constraint); + return put(PathSpec.from(pathSpec), constraint); } - public Constraint add(PathSpec pathSpec, Constraint constraint) + public Constraint put(PathSpec pathSpec, Constraint constraint) { Set roles = constraint.getRoles(); if (roles != null) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 5bbc97f8b604..d6632e9cd469 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -186,13 +186,12 @@ public void logout(Request request) @Override public Request prepareRequest(Request request) { - //if this is a request resulting from a redirect after auth is complete - //(ie its from a redirect to the original request uri) then due to - //browser handling of 302 redirects, the method may not be the same as - //that of the original request. Replace the method and original post - //params (if it was a post). - // - //See Servlet Spec 3.1 sec 13.6.3 + // if this is a request resulting from a redirect after auth is complete + // (ie its from a redirect to the original request uri) then due to + // browser handling of 302 redirects, the method may not be the same as + // that of the original request. Replace the method and original post + // params (if it was a post). + Session session = request.getSession(false); if (session == null) return request; // couldn't be authenticated yet @@ -302,15 +301,6 @@ public Authentication validateRequest(Request req, Response res, Callback callba LOG.debug("auth failed {}->403", username); Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); } - //TODO need to reinstate forward - /* else if (_dispatch) - { - LOG.debug("auth failed {}=={}", username, _formErrorPage); - RequestDispatcher dispatcher = servletApiRequest.getRequestDispatcher(_formErrorPage); - res.setHeader(HttpHeader.CACHE_CONTROL.asString(), HttpHeaderValue.NO_CACHE.asString()); - res.getHeaders().addDateField(HttpHeader.EXPIRES.asString(), 1); - dispatcher.forward(new FormRequest(req), new FormResponse(res)); - }*/ else { LOG.debug("auth failed {}->{}", username, _formErrorPage); @@ -350,8 +340,8 @@ public Authentication validateRequest(Request req, Response res, Callback callba if (jPost != null) { // TODO: how to do this + // TODO Should this be done here or is it in prepare request? LOG.debug("auth rePOST {}->{}", authentication, jUri); - // servletApiRequest.setContentParameters(jPost); } } session.removeAttribute(__J_URI); @@ -397,20 +387,8 @@ public Authentication validateRequest(Request req, Response res, Callback callba } // send the the challenge - //TODO reinstate use of dispatch - /* if (_dispatch) - { - LOG.debug("challenge {}=={}", session.getId(), _formLoginPage); - RequestDispatcher dispatcher = servletApiRequest.getRequestDispatcher(_formLoginPage); - res.setHeader(HttpHeader.CACHE_CONTROL.asString(), HttpHeaderValue.NO_CACHE.asString()); - res.setDateHeader(HttpHeader.EXPIRES.asString(), 1); - dispatcher.forward(new FormRequest(req), new FormResponse(res)); - } - else - {*/ LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); - //} return Authentication.SEND_CONTINUE; } @@ -431,94 +409,6 @@ public boolean isLoginOrErrorPage(String pathInContext) { return pathInContext != null && (pathInContext.equals(_formErrorPath) || pathInContext.equals(_formLoginPath)); } - - //TODO reinstate use of forward dispatch - /* - protected static class FormRequest extends HttpServletRequestWrapper - { - public FormRequest(HttpServletRequest request) - { - super(request); - } - - @Override - public long getDateHeader(String name) - { - if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) - return -1; - return super.getDateHeader(name); - } - - @Override - public String getHeader(String name) - { - if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) - return null; - return super.getHeader(name); - } - - @Override - public Enumeration getHeaderNames() - { - return Collections.enumeration(Collections.list(super.getHeaderNames())); - } - - @Override - public Enumeration getHeaders(String name) - { - if (name.toLowerCase(Locale.ENGLISH).startsWith("if-")) - return Collections.enumeration(Collections.emptyList()); - return super.getHeaders(name); - } - } - - protected static class FormResponse extends HttpServletResponseWrapper - { - public FormResponse(HttpServletResponse response) - { - super(response); - } - - @Override - public void addDateHeader(String name, long date) - { - if (notIgnored(name)) - super.addDateHeader(name, date); - } - - @Override - public void addHeader(String name, String value) - { - if (notIgnored(name)) - super.addHeader(name, value); - } - - @Override - public void setDateHeader(String name, long date) - { - if (notIgnored(name)) - super.setDateHeader(name, date); - } - - @Override - public void setHeader(String name, String value) - { - if (notIgnored(name)) - super.setHeader(name, value); - } - - private boolean notIgnored(String name) - { - if (HttpHeader.CACHE_CONTROL.is(name) || - HttpHeader.PRAGMA.is(name) || - HttpHeader.ETAG.is(name) || - HttpHeader.EXPIRES.is(name) || - HttpHeader.LAST_MODIFIED.is(name) || - HttpHeader.AGE.is(name)) - return false; - return true; - } - }*/ /** * This Authentication represents a just completed Form authentication. diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java index db8171b773a8..2074fb883573 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -60,8 +60,6 @@ public Authentication validateRequest(Request req, Response res, Callback callba if (!mandatory) return new DeferredAuthentication(this); - //TODO this seems fragile, to rely on this name - //X509Certificate[] certs = (X509Certificate[])req.getAttribute("jakarta.servlet.request.X509Certificate"); SslSessionData sslSessionData = (SslSessionData)req.getAttribute(SecureRequestCustomizer.DEFAULT_SSL_SESSION_DATA_ATTRIBUTE); if (sslSessionData == null) { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java index 198d684118b4..d278e37fb6b6 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/internal/DefaultUserIdentity.java @@ -53,10 +53,6 @@ public boolean isUserInRole(String role) if (DefaultIdentityService.isRoleAssociated(role)) return true; - //Servlet Spec 3.1, pg 125 - if ("*".equals(role)) - return false; - for (String r : _roles) { if (r.equals(role)) diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index ca370701d943..cd11c6ad9f6a 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -96,9 +96,9 @@ public boolean isSecure() _securityHandler.setHandler(new OkHandler()); - _securityHandler.add("/admin/*", Constraint.from("admin")); - _securityHandler.add("/any/*", Constraint.AUTHENTICATED); - _securityHandler.add("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); + _securityHandler.put("/admin/*", Constraint.from("admin")); + _securityHandler.put("/any/*", Constraint.AUTHENTICATED); + _securityHandler.put("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); _securityHandler.setAuthenticator(new BasicAuthenticator()); _server.start(); } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index d35d58210a10..bb64f276ff85 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -100,10 +100,10 @@ public boolean isSecure() _securityHandler.setHandler(new OkHandler()); - _securityHandler.add("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed - _securityHandler.add("/any/*", Constraint.AUTHENTICATED); - _securityHandler.add("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); - _securityHandler.add("/admin/*", Constraint.from("admin")); + _securityHandler.put("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed + _securityHandler.put("/any/*", Constraint.AUTHENTICATED); + _securityHandler.put("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); + _securityHandler.put("/admin/*", Constraint.from("admin")); _securityHandler.setAuthenticator(new FormAuthenticator("/login", "/error", false)); _server.start(); } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 1e9f3eee1a9c..8f8898ccee51 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -108,7 +108,7 @@ public void testNoConstraints() throws Exception @Test public void testForbidden() throws Exception { - _securityHandler.add("/secret/*", Constraint.FORBIDDEN); + _securityHandler.put("/secret/*", Constraint.FORBIDDEN); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); @@ -123,7 +123,7 @@ public void testForbidden() throws Exception @Test public void testUserData() throws Exception { - _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); + _securityHandler.put("/confidential/*", Constraint.CONFIDENTIAL); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); @@ -136,7 +136,7 @@ public void testUserData() throws Exception assertThat(response, containsString(":9999")); assertThat(response, not(containsString("You are OK"))); - response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); assertThat(response, containsString("UNAUTHENTICATED is not OK")); } @@ -144,9 +144,9 @@ public void testUserData() throws Exception @Test public void testCombinedForbiddenConfidential() throws Exception { - _securityHandler.add("/*", Constraint.NONE); - _securityHandler.add("/confidential/*", Constraint.CONFIDENTIAL); - _securityHandler.add("*.hidden", Constraint.FORBIDDEN); + _securityHandler.put("/*", Constraint.NONE); + _securityHandler.put("/confidential/*", Constraint.CONFIDENTIAL); + _securityHandler.put("*.hidden", Constraint.FORBIDDEN); String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); @@ -163,11 +163,11 @@ public void testCombinedForbiddenConfidential() throws Exception assertThat(response, containsString(":9999")); assertThat(response, not(containsString("You are OK"))); - response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); assertThat(response, containsString("UNAUTHENTICATED is not OK")); - response = _connectorS.getResponse("GET /ctx/confidential/info.hidden HTTP/1.0\r\nX-Forwarded-Proto: https\r\n\r\n"); + response = _connectorS.getResponse("GET /ctx/confidential/info.hidden HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); assertThat(response, not(containsString("You are OK"))); } From 804ece1507ea03337e47f0713271bb71c3b54f7d Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 5 Mar 2023 05:22:35 +0100 Subject: [PATCH 018/129] WIP Signed-off-by: gregw --- .../org/eclipse/jetty/security/UserStore.java | 9 +- .../jetty/security/jaas/JAASLoginService.java | 308 +++++++ .../jetty/security/jaas/JAASPrincipal.java | 63 ++ .../eclipse/jetty/security/jaas/JAASRole.java | 33 + .../security/jaas/JAASUserPrincipal.java | 68 ++ .../jaas/PropertyUserStoreManager.java | 94 +++ .../callback/AbstractCallbackHandler.java | 51 ++ .../jaas/callback/DefaultCallbackHandler.java | 74 ++ .../jaas/callback/ObjectCallback.java | 44 + .../callback/RequestParameterCallback.java | 50 ++ .../jaas/callback/ServletRequestCallback.java | 38 + .../security/jaas/callback/package-info.java | 18 + .../jetty/security/jaas/package-info.java | 18 + .../jaas/spi/AbstractDatabaseLoginModule.java | 157 ++++ .../jaas/spi/AbstractLoginModule.java | 290 +++++++ .../jaas/spi/DataSourceLoginModule.java | 83 ++ .../security/jaas/spi/JDBCLoginModule.java | 102 +++ .../security/jaas/spi/LdapLoginModule.java | 756 ++++++++++++++++++ .../jaas/spi/PropertyFileLoginModule.java | 143 ++++ .../jetty/security/jaas/spi/package-info.java | 18 + 20 files changed, 2412 insertions(+), 5 deletions(-) create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASPrincipal.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASRole.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASUserPrincipal.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/PropertyUserStoreManager.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/AbstractCallbackHandler.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ObjectCallback.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestParameterCallback.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/package-info.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/package-info.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/DataSourceLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/JDBCLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/package-info.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java index cc3a7391e992..0124204c565d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/UserStore.java @@ -34,16 +34,15 @@ public class UserStore extends ContainerLifeCycle protected class User { protected UserPrincipal _userPrincipal; - protected List _rolePrincipals = Collections.emptyList(); + protected List _rolePrincipals; protected User(String username, Credential credential, String[] roles) { _userPrincipal = new UserPrincipal(username, credential); - _rolePrincipals = Collections.emptyList(); - - if (roles != null) - _rolePrincipals = Arrays.stream(roles).map(RolePrincipal::new).collect(Collectors.toList()); + _rolePrincipals = (roles == null || roles.length == 0) + ? Collections.emptyList() + : Arrays.stream(roles).map(RolePrincipal::new).collect(Collectors.toList()); } protected UserPrincipal getUserPrincipal() diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java new file mode 100644 index 000000000000..8c1a0f1a88f9 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java @@ -0,0 +1,308 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.Configuration; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.jaas.callback.DefaultCallbackHandler; +import org.eclipse.jetty.util.ArrayUtil; +import org.eclipse.jetty.util.Loader; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * JAASLoginService + * + * + * Implementation of jetty's LoginService that works with JAAS for + * authorization and authentication. + */ +public class JAASLoginService extends ContainerLifeCycle implements LoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(JAASLoginService.class); + + public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.ee9.jaas.JAASRole"; + public static final String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME}; + public static final ThreadLocal INSTANCE = new ThreadLocal<>(); + + protected String[] _roleClassNames = DEFAULT_ROLE_CLASS_NAMES; + protected String _callbackHandlerClass; + protected String _realmName; + protected String _loginModuleName; + protected JAASUserPrincipal _defaultUser = new JAASUserPrincipal(null, null, null); + protected IdentityService _identityService; + protected Configuration _configuration; + + public JAASLoginService() + { + } + + /** + * @param name the name of the realm + */ + public JAASLoginService(String name) + { + this(); + _realmName = name; + _loginModuleName = name; + } + + /** + * Get the name of the realm. + * + * @return name or null if not set. + */ + @Override + public String getName() + { + return _realmName; + } + + /** + * Set the name of the realm + * + * @param name a String value + */ + public void setName(String name) + { + _realmName = name; + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() + { + return _configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) + { + _configuration = configuration; + } + + /** + * Get the identityService. + * + * @return the identityService + */ + @Override + public IdentityService getIdentityService() + { + return _identityService; + } + + /** + * Set the identityService. + * + * @param identityService the identityService to set + */ + @Override + public void setIdentityService(IdentityService identityService) + { + _identityService = identityService; + } + + /** + * Set the name to use to index into the config + * file of LoginModules. + * + * @param name a String value + */ + public void setLoginModuleName(String name) + { + _loginModuleName = name; + } + + public void setCallbackHandlerClass(String classname) + { + _callbackHandlerClass = classname; + } + + public void setRoleClassNames(String[] classnames) + { + if (classnames == null || classnames.length == 0) + { + _roleClassNames = DEFAULT_ROLE_CLASS_NAMES; + return; + } + + _roleClassNames = ArrayUtil.addToArray(classnames, DEFAULT_ROLE_CLASS_NAME, String.class); + } + + public String[] getRoleClassNames() + { + return _roleClassNames; + } + + @Override + protected void doStart() throws Exception + { + if (_identityService == null) + _identityService = new DefaultIdentityService(); // TODO really? Should get from SecurityHandler + addBean(new PropertyUserStoreManager()); + super.doStart(); + } + + @Override + public UserIdentity login(final String username, final Object credentials, final Request request) + { + try + { + CallbackHandler callbackHandler = null; + if (_callbackHandlerClass == null) + callbackHandler = new DefaultCallbackHandler(); + else + { + Class clazz = Loader.loadClass(_callbackHandlerClass); + callbackHandler = (CallbackHandler)clazz.getDeclaredConstructor().newInstance(); + } + + if (callbackHandler instanceof DefaultCallbackHandler) + { + DefaultCallbackHandler dch = (DefaultCallbackHandler)callbackHandler; + if (request instanceof HttpServletRequest httpServletRequest) + dch.setRequest(httpServletRequest); + dch.setCredential(credentials); + dch.setUserName(username); + } + + //set up the login context + Subject subject = new Subject(); + INSTANCE.set(this); + LoginContext loginContext = + (_configuration == null ? new LoginContext(_loginModuleName, subject, callbackHandler) + : new LoginContext(_loginModuleName, subject, callbackHandler, _configuration)); + + loginContext.login(); + + //login success + JAASUserPrincipal userPrincipal = new JAASUserPrincipal(getUserName(callbackHandler), subject, loginContext); + subject.getPrincipals().add(userPrincipal); + + return _identityService.newUserIdentity(subject, userPrincipal, getGroups(subject)); + } + catch (FailedLoginException e) + { + if (LOG.isDebugEnabled()) + LOG.debug("Login failed", e); + } + catch (Exception e) + { + if (LOG.isDebugEnabled()) + LOG.debug("Login error", e); + } + finally + { + INSTANCE.remove(); + } + + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + // TODO optionally check user is still valid + return true; + } + + private String getUserName(CallbackHandler callbackHandler) throws IOException, UnsupportedCallbackException + { + NameCallback nameCallback = new NameCallback("foo"); + callbackHandler.handle(new Callback[]{nameCallback}); + return nameCallback.getName(); + } + + @Override + public void logout(UserIdentity user) + { + Set userPrincipals = user.getSubject().getPrincipals(JAASUserPrincipal.class); + LoginContext loginContext = userPrincipals.iterator().next().getLoginContext(); + try + { + loginContext.logout(); + } + catch (LoginException e) + { + LOG.warn("Failed to logout {}", user, e); + } + } + + /** + * Get all of the groups for the user. + * + * @param subject the Subject representing the user + * @return all the names of groups that the user is in, or 0 length array if none + */ + protected String[] getGroups(Subject subject) + { + Collection groups = new LinkedHashSet<>(); + for (Principal principal : subject.getPrincipals()) + { + if (isRoleClass(principal.getClass(), Arrays.asList(getRoleClassNames()))) + groups.add(principal.getName()); + } + + return groups.toArray(new String[groups.size()]); + } + + /** + * Check whether the class, its superclasses or any interfaces they implement + * is one of the classes that represents a role. + * + * @param clazz the class to check + * @param roleClassNames the list of classnames that represent roles + * @return true if the class is a role class + */ + private static boolean isRoleClass(Class clazz, List roleClassNames) + { + Class c = clazz; + + //add the class, its interfaces and superclasses to the list to test + List classnames = new ArrayList<>(); + while (c != null) + { + classnames.add(c.getName()); + Arrays.stream(c.getInterfaces()).map(Class::getName).forEach(classnames::add); + c = c.getSuperclass(); + } + + return roleClassNames.stream().anyMatch(classnames::contains); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASPrincipal.java new file mode 100644 index 000000000000..7b6d8a945718 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASPrincipal.java @@ -0,0 +1,63 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.io.Serializable; +import java.security.Principal; + +/** + * JAASPrincipal + *

    + * Impl class of Principal interface. + */ +public class JAASPrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = -5538962177019315479L; + + private final String _name; + + public JAASPrincipal(String userName) + { + this._name = userName; + } + + @Override + public boolean equals(Object p) + { + if (!(p instanceof JAASPrincipal)) + return false; + + return getName().equals(((JAASPrincipal)p).getName()); + } + + @Override + public int hashCode() + { + return getName().hashCode(); + } + + @Override + public String getName() + { + return this._name; + } + + @Override + public String toString() + { + return getName(); + } +} + + diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASRole.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASRole.java new file mode 100644 index 000000000000..dcf4caaae84a --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASRole.java @@ -0,0 +1,33 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +public class JAASRole extends JAASPrincipal +{ + private static final long serialVersionUID = 3465114254970134526L; + + public JAASRole(String name) + { + super(name); + } + + @Override + public boolean equals(Object o) + { + if (!(o instanceof JAASRole)) + return false; + + return getName().equals(((JAASRole)o).getName()); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASUserPrincipal.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASUserPrincipal.java new file mode 100644 index 000000000000..91cc02c4245b --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASUserPrincipal.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.security.Principal; +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; + +/** + * JAASUserPrincipal + *

    + * Implements the JAAS version of the + * org.eclipse.jetty.security.UserPrincipal interface. + */ +public class JAASUserPrincipal implements Principal +{ + private final String _name; + private final Subject _subject; + private final LoginContext _loginContext; + + public JAASUserPrincipal(String name, Subject subject, LoginContext loginContext) + { + this._name = name; + this._subject = subject; + this._loginContext = loginContext; + } + + /** + * Get the name identifying the user + */ + @Override + public String getName() + { + return _name; + } + + /** + * Provide access to the Subject + * + * @return subject + */ + public Subject getSubject() + { + return this._subject; + } + + LoginContext getLoginContext() + { + return this._loginContext; + } + + @Override + public String toString() + { + return getName(); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/PropertyUserStoreManager.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/PropertyUserStoreManager.java new file mode 100644 index 000000000000..aa617b44a751 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/PropertyUserStoreManager.java @@ -0,0 +1,94 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.eclipse.jetty.security.PropertyUserStore; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PropertyUserStoreManager + * + * Maintains a map of PropertyUserStores, keyed off the location of the property file containing + * the authentication and authorization information. + * + * This class is used to enable the PropertyUserStores to be cached and shared. This is essential + * for the PropertyFileLoginModules, whose lifecycle is controlled by the JAAS api and instantiated + * afresh whenever a user needs to be authenticated. Without this class, every PropertyFileLoginModule + * instantiation would re-read and reload in all the user information just to authenticate a single user. + */ +public class PropertyUserStoreManager extends AbstractLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(PropertyUserStoreManager.class); + /** + * Map of user authentication and authorization information loaded in from a property file. + * The map is keyed off the location of the file. + */ + private Map _propertyUserStores; + + public PropertyUserStore getPropertyUserStore(String file) + { + synchronized (this) + { + if (_propertyUserStores == null) + return null; + + return _propertyUserStores.get(file); + } + } + + public PropertyUserStore addPropertyUserStore(String file, PropertyUserStore store) + { + synchronized (this) + { + Objects.requireNonNull(_propertyUserStores); + PropertyUserStore existing = _propertyUserStores.get(file); + if (existing != null) + return existing; + + _propertyUserStores.put(file, store); + return store; + } + } + + @Override + protected void doStart() throws Exception + { + _propertyUserStores = new HashMap(); + super.doStart(); + } + + @Override + protected void doStop() throws Exception + { + for (Map.Entry entry : _propertyUserStores.entrySet()) + { + try + { + entry.getValue().stop(); + } + catch (Exception e) + { + LOG.warn("Error stopping PropertyUserStore at {}", entry.getKey(), e); + } + } + _propertyUserStores = null; + super.doStop(); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/AbstractCallbackHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/AbstractCallbackHandler.java new file mode 100644 index 000000000000..f6e26e1cae42 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/AbstractCallbackHandler.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.callback; + +import java.io.IOException; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.UnsupportedCallbackException; + +public abstract class AbstractCallbackHandler implements CallbackHandler +{ + protected String _userName; + protected Object _credential; + + public void setUserName(String userName) + { + _userName = userName; + } + + public String getUserName() + { + return _userName; + } + + public void setCredential(Object credential) + { + _credential = credential; + } + + public Object getCredential() + { + return _credential; + } + + @Override + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException + { + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java new file mode 100644 index 000000000000..9c01c7f0eca6 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java @@ -0,0 +1,74 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.callback; + +import java.io.IOException; +import java.util.Arrays; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +import jakarta.servlet.http.HttpServletRequest; + +/** + * DefaultCallbackHandler + * + * An implementation of the JAAS CallbackHandler. Users can provide + * their own implementation instead and set the name of its class on the JAASLoginService. + */ +public class DefaultCallbackHandler extends AbstractCallbackHandler +{ + private HttpServletRequest _request; + + public void setRequest(HttpServletRequest request) + { + _request = request; + } + + @Override + public void handle(Callback[] callbacks) + throws IOException, UnsupportedCallbackException + { + for (Callback callback : callbacks) + { + if (callback instanceof NameCallback) + { + ((NameCallback)callback).setName(getUserName()); + } + else if (callback instanceof ObjectCallback) + { + ((ObjectCallback)callback).setObject(getCredential()); + } + else if (callback instanceof PasswordCallback) + { + ((PasswordCallback)callback).setPassword(getCredential().toString().toCharArray()); + } + else if (callback instanceof RequestParameterCallback) + { + if (_request != null) + { + RequestParameterCallback rpc = (RequestParameterCallback)callback; + rpc.setParameterValues(Arrays.asList(_request.getParameterValues(rpc.getParameterName()))); + } + } + else if (callback instanceof ServletRequestCallback) + { + ((ServletRequestCallback)callback).setRequest(_request); + } + else + throw new UnsupportedCallbackException(callback); + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ObjectCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ObjectCallback.java new file mode 100644 index 000000000000..f48d0a817718 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ObjectCallback.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.callback; + +import javax.security.auth.callback.Callback; + +/** + * ObjectCallback + *

    + * Can be used as a LoginModule Callback to + * obtain a user's credential as an Object, rather than + * a char[], to which some credentials may not be able + * to be converted + */ +public class ObjectCallback implements Callback +{ + protected Object _object; + + public void setObject(Object o) + { + _object = o; + } + + public Object getObject() + { + return _object; + } + + public void clearObject() + { + _object = null; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestParameterCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestParameterCallback.java new file mode 100644 index 000000000000..4d0526b79fa7 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestParameterCallback.java @@ -0,0 +1,50 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.callback; + +import java.util.List; +import javax.security.auth.callback.Callback; + +/** + * RequestParameterCallback + *

    + * Allows a JAAS callback handler to access any parameter from the j_security_check FORM. + * This means that a LoginModule can access form fields other than the j_username and j_password + * fields, and use it, for example, to authenticate a user. + */ +public class RequestParameterCallback implements Callback +{ + private String _paramName; + private List _paramValues; + + public void setParameterName(String name) + { + _paramName = name; + } + + public String getParameterName() + { + return _paramName; + } + + public void setParameterValues(List values) + { + _paramValues = values; + } + + public List getParameterValues() + { + return _paramValues; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java new file mode 100644 index 000000000000..5de80d564945 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.callback; + +import javax.security.auth.callback.Callback; + +import jakarta.servlet.ServletRequest; + +/** + * ServletRequestCallback + * + * Provides access to the request associated with the authentication. + */ +public class ServletRequestCallback implements Callback +{ + protected ServletRequest _request; + + public void setRequest(ServletRequest request) + { + _request = request; + } + + public ServletRequest getRequest() + { + return _request; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/package-info.java new file mode 100644 index 000000000000..0a75459b5627 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/package-info.java @@ -0,0 +1,18 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty Jaas : Jaas Callbacks + */ +package org.eclipse.jetty.security.jaas.callback; + diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/package-info.java new file mode 100644 index 000000000000..bc33f13cf966 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/package-info.java @@ -0,0 +1,18 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty Jaas : Support for Jaas + */ +package org.eclipse.jetty.security.jaas; + diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java new file mode 100644 index 000000000000..918ea2d0439f --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java @@ -0,0 +1,157 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; + +import org.eclipse.jetty.security.UserPrincipal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * AbstractDatabaseLoginModule + * + *

    + * Abstract base class for LoginModules that interact with a + * database to retrieve authentication and authorization information. + * Used by the JDBCLoginModule and DataSourceLoginModule. + *

    + */ +public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule +{ + private static final Logger LOG = LoggerFactory.getLogger(AbstractDatabaseLoginModule.class); + + private String userQuery; + private String rolesQuery; + private String dbUserTable; + private String dbUserTableUserField; + private String dbUserTableCredentialField; + private String dbUserRoleTable; + private String dbUserRoleTableUserField; + private String dbUserRoleTableRoleField; + + /** + * @return a java.sql.Connection from the database + * @throws Exception if unable to get the connection + */ + public abstract Connection getConnection() throws Exception; + + public class JDBCUser extends JAASUser + { + public JDBCUser(UserPrincipal user) + { + super(user); + } + + @Override + public List doFetchRoles() + throws Exception + { + return getRoles(getUserName()); + } + } + + /** + * Load info from database + * + * @param userName user info to load + * @throws Exception if unable to get the user info + */ + @Override + public JAASUser getUser(String userName) + throws Exception + { + try (Connection connection = getConnection()) + { + + //query for credential + String dbCredential = null; + try (PreparedStatement statement = connection.prepareStatement(userQuery)) + { + statement.setString(1, userName); + try (ResultSet results = statement.executeQuery()) + { + if (results.next()) + { + dbCredential = results.getString(1); + } + } + } + + if (dbCredential == null) + return null; + + return new JDBCUser(new UserPrincipal(userName, Credential.getCredential(dbCredential))); + } + } + + public List getRoles(String userName) + throws Exception + { + List roles = new ArrayList(); + + try (Connection connection = getConnection()) + { + //query for role names + + try (PreparedStatement statement = connection.prepareStatement(rolesQuery)) + { + statement.setString(1, userName); + try (ResultSet results = statement.executeQuery()) + { + while (results.next()) + { + String roleName = results.getString(1); + roles.add(roleName); + } + } + } + } + + return roles; + } + + @Override + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map sharedState, + Map options) + { + super.initialize(subject, callbackHandler, sharedState, options); + + //get the user credential query out of the options + dbUserTable = (String)options.get("userTable"); + dbUserTableUserField = (String)options.get("userField"); + dbUserTableCredentialField = (String)options.get("credentialField"); + + userQuery = "select " + dbUserTableCredentialField + " from " + dbUserTable + " where " + dbUserTableUserField + "=?"; + + //get the user roles query out of the options + dbUserRoleTable = (String)options.get("userRoleTable"); + dbUserRoleTableUserField = (String)options.get("userRoleUserField"); + dbUserRoleTableRoleField = (String)options.get("userRoleRoleField"); + + rolesQuery = "select " + dbUserRoleTableRoleField + " from " + dbUserRoleTable + " where " + dbUserRoleTableUserField + "=?"; + + if (LOG.isDebugEnabled()) + LOG.debug("userQuery = {} rolesQuery = {}", userQuery, rolesQuery); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java new file mode 100644 index 000000000000..68b1be6821db --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java @@ -0,0 +1,290 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.jaas.callback.ObjectCallback; + +/** + * AbstractLoginModule + * + * Abstract base class for all LoginModules. Subclasses should + * just need to implement getUserInfo method. + */ +public abstract class AbstractLoginModule implements LoginModule +{ + private CallbackHandler callbackHandler; + + private boolean authState = false; + private boolean commitState = false; + private JAASUser currentUser; + private Subject subject; + + public abstract static class JAASUser + { + private final UserPrincipal _user; + private List _roles; + + public JAASUser(UserPrincipal u) + { + _user = u; + } + + public String getUserName() + { + return _user.getName(); + } + + /** + * @param subject The subject + */ + public void setJAASInfo(Subject subject) + { + if (_user == null) + return; + + _user.configureSubject(subject); + if (_roles != null) + subject.getPrincipals().addAll(_roles); + } + + /** + * @param subject The subject + */ + public void unsetJAASInfo(Subject subject) + { + if (_user == null) + return; + _user.deconfigureSubject(subject); + if (_roles != null) + subject.getPrincipals().removeAll(_roles); + } + + public boolean checkCredential(Object suppliedCredential) + { + return _user.authenticate(suppliedCredential); + } + + public void fetchRoles() throws Exception + { + List rolenames = doFetchRoles(); + if (rolenames != null) + _roles = rolenames.stream().map(JAASRole::new).collect(Collectors.toList()); + } + + public abstract List doFetchRoles() throws Exception; + } + + public abstract JAASUser getUser(String username) throws Exception; + + public Subject getSubject() + { + return this.subject; + } + + public void setSubject(Subject s) + { + this.subject = s; + } + + public JAASUser getCurrentUser() + { + return this.currentUser; + } + + public void setCurrentUser(JAASUser u) + { + this.currentUser = u; + } + + public CallbackHandler getCallbackHandler() + { + return this.callbackHandler; + } + + public void setCallbackHandler(CallbackHandler h) + { + this.callbackHandler = h; + } + + public boolean isAuthenticated() + { + return this.authState; + } + + public boolean isCommitted() + { + return this.commitState; + } + + public void setAuthenticated(boolean authState) + { + this.authState = authState; + } + + public void setCommitted(boolean commitState) + { + this.commitState = commitState; + } + + @Override + public boolean abort() throws LoginException + { + this.currentUser = null; + return (isAuthenticated() && isCommitted()); + } + + /** + * @return true if committed, false if not (likely not authenticated) + * @throws LoginException if unable to commit + * @see LoginModule#commit() + */ + @Override + public boolean commit() throws LoginException + { + if (!isAuthenticated()) + { + currentUser = null; + setCommitted(false); + return false; + } + + setCommitted(true); + currentUser.setJAASInfo(subject); + return true; + } + + public Callback[] configureCallbacks() + { + Callback[] callbacks = new Callback[3]; + callbacks[0] = new NameCallback("Enter user name"); + callbacks[1] = new ObjectCallback(); + callbacks[2] = new PasswordCallback("Enter password", false); //only used if framework does not support the ObjectCallback + return callbacks; + } + + public boolean isIgnored() + { + return false; + } + + /** + * @return true if is authenticated, false otherwise + * @throws LoginException if unable to login + * @see LoginModule#login() + */ + @Override + public boolean login() throws LoginException + { + try + { + if (isIgnored()) + return false; + + if (callbackHandler == null) + throw new LoginException("No callback handler"); + + Callback[] callbacks = configureCallbacks(); + callbackHandler.handle(callbacks); + + String webUserName = ((NameCallback)callbacks[0]).getName(); + Object webCredential = null; + + webCredential = ((ObjectCallback)callbacks[1]).getObject(); //first check if ObjectCallback has the credential + if (webCredential == null) + webCredential = ((PasswordCallback)callbacks[2]).getPassword(); //use standard PasswordCallback + + if ((webUserName == null) || (webCredential == null)) + { + setAuthenticated(false); + throw new FailedLoginException(); + } + + JAASUser user = getUser(webUserName); + + if (user == null) + { + setAuthenticated(false); + throw new FailedLoginException(); + } + + currentUser = user; + setAuthenticated(currentUser.checkCredential(webCredential)); + + if (isAuthenticated()) + { + currentUser.fetchRoles(); + return true; + } + else + throw new FailedLoginException(); + } + catch (IOException e) + { + throw new LoginException(e.toString()); + } + catch (UnsupportedCallbackException e) + { + throw new LoginException(e.toString()); + } + catch (Exception e) + { + if (e instanceof LoginException) + throw (LoginException)e; + throw new LoginException(e.toString()); + } + } + + /** + * @return true always + * @throws LoginException if unable to logout + * @see LoginModule#logout() + */ + @Override + public boolean logout() throws LoginException + { + this.currentUser.unsetJAASInfo(this.subject); + this.currentUser = null; + return true; + } + + /** + * @param subject the subject + * @param callbackHandler the callback handler + * @param sharedState the shared state map + * @param options the option map + * @see LoginModule#initialize(Subject, CallbackHandler, Map, Map) + */ + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, + Map sharedState, Map options) + { + this.callbackHandler = callbackHandler; + this.subject = subject; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/DataSourceLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/DataSourceLoginModule.java new file mode 100644 index 000000000000..b4231b2d8ccc --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/DataSourceLoginModule.java @@ -0,0 +1,83 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.sql.Connection; +import java.util.Map; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.sql.DataSource; + +/** + * DataSourceLoginModule + * + * A LoginModule that uses a DataSource to retrieve user authentication + * and authorisation information. + * + * @see JDBCLoginModule + */ +public class DataSourceLoginModule extends AbstractDatabaseLoginModule +{ + + private String dbJNDIName; + private DataSource dataSource; + + /** + * Init LoginModule. + *

    + * Called once by JAAS after new instance created. + * + * @param subject the subject + * @param callbackHandler the callback handler + * @param sharedState the shared state map + * @param options the option map + */ + @Override + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map sharedState, + Map options) + { + try + { + super.initialize(subject, callbackHandler, sharedState, options); + + //get the datasource jndi name + dbJNDIName = (String)options.get("dbJNDIName"); + + InitialContext ic = new InitialContext(); + dataSource = (DataSource)ic.lookup("java:comp/env/" + dbJNDIName); + } + catch (NamingException e) + { + throw new IllegalStateException(e.toString()); + } + } + + /** + * Get a connection from the DataSource + * + * @return the connection for the datasource + * @throws Exception if unable to get the connection + * @see AbstractDatabaseLoginModule#getConnection() + */ + @Override + public Connection getConnection() + throws Exception + { + return dataSource.getConnection(); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/JDBCLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/JDBCLoginModule.java new file mode 100644 index 000000000000..3d0bfeae15a0 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/JDBCLoginModule.java @@ -0,0 +1,102 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.Map; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; + +import org.eclipse.jetty.util.Loader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

    JAAS LoginModule to retrieve user information from + * a database and authenticate the user.

    + *

    Notes

    + *

    This version uses plain old JDBC connections NOT DataSources.

    + */ +public class JDBCLoginModule extends AbstractDatabaseLoginModule +{ + private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginModule.class); + + private String dbDriver; + private String dbUrl; + private String dbUserName; + private String dbPassword; + + /** + * Get a connection from the DriverManager + * + * @return the connection for this datasource + * @throws Exception if unable to get the connection + */ + @Override + public Connection getConnection() + throws Exception + { + if (!((dbDriver != null) && (dbUrl != null))) + throw new IllegalStateException("Database connection information not configured"); + + if (LOG.isDebugEnabled()) + LOG.debug("Connecting using dbDriver={} dbUserName={}, dbPassword={}", dbDriver, dbUserName, dbUrl); + + return DriverManager.getConnection(dbUrl, + dbUserName, + dbPassword); + } + + /** + * Init LoginModule. + *

    + * Called once by JAAS after new instance created. + * + * @param subject the subject + * @param callbackHandler the callback handler + * @param sharedState the shared state map + * @param options the options map + */ + @Override + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map sharedState, + Map options) + { + try + { + super.initialize(subject, callbackHandler, sharedState, options); + + //get the jdbc username/password, jdbc url out of the options + dbDriver = (String)options.get("dbDriver"); + dbUrl = (String)options.get("dbUrl"); + dbUserName = (String)options.get("dbUserName"); + dbPassword = (String)options.get("dbPassword"); + + if (dbUserName == null) + dbUserName = ""; + + if (dbPassword == null) + dbPassword = ""; + + if (dbDriver != null) + Loader.loadClass(dbDriver).getDeclaredConstructor().newInstance(); + } + catch (Exception e) + { + throw new IllegalStateException(e.toString()); + } + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java new file mode 100644 index 000000000000..2ed6bfb7b9c5 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java @@ -0,0 +1,756 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Hashtable; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import javax.naming.AuthenticationException; +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.security.auth.Subject; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginException; + +import org.eclipse.jetty.ee9.jaas.callback.ObjectCallback; +import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.util.TypeUtil; +import org.eclipse.jetty.util.security.Credential; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A LdapLoginModule for use with JAAS setups + *

    + * The jvm should be started with the following parameter: + *

    + * -Djava.security.auth.login.config=etc/ldap-loginModule.conf
    + * 
    + * and an example of the ldap-loginModule.conf would be: + *
    + * ldaploginmodule {
    + *    org.eclipse.jetty.server.server.plus.jaas.spi.LdapLoginModule required
    + *    debug="true"
    + *    useLdaps="false"
    + *    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
    + *    hostname="ldap.example.com"
    + *    port="389"
    + *    bindDn="cn=Directory Manager"
    + *    bindPassword="directory"
    + *    authenticationMethod="simple"
    + *    forceBindingLogin="false"
    + *    userBaseDn="ou=people,dc=alcatel"
    + *    userRdnAttribute="uid"
    + *    userIdAttribute="uid"
    + *    userPasswordAttribute="userPassword"
    + *    userObjectClass="inetOrgPerson"
    + *    roleBaseDn="ou=groups,dc=example,dc=com"
    + *    roleNameAttribute="cn"
    + *    roleMemberAttribute="uniqueMember"
    + *    roleObjectClass="groupOfUniqueNames";
    + *    };
    + * 
    + */ +public class LdapLoginModule extends AbstractLoginModule +{ + private static final Logger LOG = LoggerFactory.getLogger(LdapLoginModule.class); + + /** + * hostname of the ldap server + */ + private String _hostname; + + /** + * port of the ldap server + */ + private int _port; + + /** + * Context.SECURITY_AUTHENTICATION + */ + private String _authenticationMethod; + + /** + * Context.INITIAL_CONTEXT_FACTORY + */ + private String _contextFactory; + + /** + * root DN used to connect to + */ + private String _bindDn; + + /** + * password used to connect to the root ldap context + */ + private String _bindPassword; + + /** + * object class of a user + */ + private String _userObjectClass = "inetOrgPerson"; + + /** + * attribute that the principal is located + */ + private String _userRdnAttribute = "uid"; + + /** + * attribute that the principal is located + */ + private String _userIdAttribute = "cn"; + + /** + * name of the attribute that a users password is stored under + *

    + * NOTE: not always accessible, see force binding login + */ + private String _userPasswordAttribute = "userPassword"; + + /** + * base DN where users are to be searched from + */ + private String _userBaseDn; + + /** + * base DN where role membership is to be searched from + */ + private String _roleBaseDn; + + /** + * object class of roles + */ + private String _roleObjectClass = "groupOfUniqueNames"; + + /** + * name of the attribute that a username would be under a role class + */ + private String _roleMemberAttribute = "uniqueMember"; + + /** + * the name of the attribute that a role would be stored under + */ + private String _roleNameAttribute = "roleName"; + + private boolean _debug; + + /** + * if the getUserInfo can pull a password off of the user then + * password comparison is an option for authn, to force binding + * login checks, set this to true + */ + private boolean _forceBindingLogin = false; + + /** + * When true changes the protocol to ldaps + */ + private boolean _useLdaps = false; + + private DirContext _rootContext; + + public class LDAPUser extends JAASUser + { + Attributes attributes; + + public LDAPUser(UserPrincipal user, Attributes attributes) + { + super(user); + this.attributes = attributes; + } + + @Override + public List doFetchRoles() throws Exception + { + return getUserRoles(_rootContext, getUserName(), attributes); + } + } + + public class LDAPBindingUser extends JAASUser + { + DirContext _context; + String _userDn; + + public LDAPBindingUser(UserPrincipal user, DirContext context, String userDn) + { + super(user); + _context = context; + _userDn = userDn; + } + + @Override + public List doFetchRoles() throws Exception + { + return getUserRolesByDn(_context, _userDn); + } + } + + /** + * get the available information about the user + *

    + * for this LoginModule, the credential can be null which will result in a + * binding ldap authentication scenario + *

    + * roles are also an optional concept if required + * + * @param username the user name + * @return the userinfo for the username + * @throws Exception if unable to get the user info + */ + @Override + public JAASUser getUser(String username) throws Exception + { + Attributes attributes = getUserAttributes(username); + String pwdCredential = getUserCredentials(attributes); + + if (pwdCredential == null) + return null; + + pwdCredential = convertCredentialLdapToJetty(pwdCredential); + Credential credential = Credential.getCredential(pwdCredential); + return new LDAPUser(new UserPrincipal(username, credential), attributes); + } + + protected String doRFC2254Encoding(String inputString) + { + StringBuffer buf = new StringBuffer(inputString.length()); + for (int i = 0; i < inputString.length(); i++) + { + char c = inputString.charAt(i); + switch (c) + { + case '\\': + buf.append("\\5c"); + break; + case '*': + buf.append("\\2a"); + break; + case '(': + buf.append("\\28"); + break; + case ')': + buf.append("\\29"); + break; + case '\0': + buf.append("\\00"); + break; + default: + buf.append(c); + break; + } + } + return buf.toString(); + } + + /** + * attempts to get the users LDAP attributes from the users context + *

    + * NOTE: this is not an user authenticated operation + * + * @return the {@link Attributes} from the user + */ + private Attributes getUserAttributes(String username) throws LoginException + { + SearchResult result = findUser(username); + Attributes attributes = result.getAttributes(); + return attributes; + } + + private String getUserCredentials(Attributes attributes) throws LoginException + { + String ldapCredential = null; + + Attribute attribute = attributes.get(_userPasswordAttribute); + if (attribute != null) + { + try + { + byte[] value = (byte[])attribute.get(); + + ldapCredential = new String(value); + } + catch (NamingException e) + { + LOG.debug("no password available under attribute: {}", _userPasswordAttribute); + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("user cred is: {}", ldapCredential); + + return ldapCredential; + } + + /** + * attempts to get the users roles from the root context + *

    + * NOTE: this is not an user authenticated operation + */ + private List getUserRoles(DirContext dirContext, String username, Attributes attributes) throws LoginException, NamingException + { + String rdnValue = username; + Attribute attribute = attributes.get(_userRdnAttribute); + if (attribute != null) + { + try + { + rdnValue = (String)attribute.get(); // switch to the value stored in the _userRdnAttribute if we can + } + catch (NamingException ignored) + { + } + } + + String filter = "({0}={1})"; + + Object[] filterArguments = new Object[]{ + _userRdnAttribute, + rdnValue + }; + + SearchResult searchResult = findUser(dirContext, filter, filterArguments); + + return getUserRolesByDn(dirContext, searchResult.getNameInNamespace()); + } + + private List getUserRolesByDn(DirContext dirContext, String userDn) throws NamingException + { + List roleList = new ArrayList<>(); + + if (dirContext == null || _roleBaseDn == null || _roleMemberAttribute == null || _roleObjectClass == null) + { + return roleList; + } + + SearchControls ctls = new SearchControls(); + ctls.setDerefLinkFlag(true); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + ctls.setReturningAttributes(new String[]{_roleNameAttribute}); + + String filter = "(&(objectClass={0})({1}={2}))"; + Object[] filterArguments = {_roleObjectClass, _roleMemberAttribute, userDn}; + NamingEnumeration results = dirContext.search(_roleBaseDn, filter, filterArguments, ctls); + + if (LOG.isDebugEnabled()) + LOG.debug("Found user roles?: {}", results.hasMoreElements()); + + while (results.hasMoreElements()) + { + SearchResult result = results.nextElement(); + + Attributes attributes = result.getAttributes(); + + if (attributes == null) + { + continue; + } + + Attribute roleAttribute = attributes.get(_roleNameAttribute); + + if (roleAttribute == null) + { + continue; + } + + NamingEnumeration roles = roleAttribute.getAll(); + while (roles.hasMore()) + { + roleList.add(roles.next().toString()); + } + } + + return roleList; + } + + /** + * since ldap uses a context bind for valid authentication checking, we override login() + *

    + * if credentials are not available from the users context or if we are forcing the binding check + * then we try a binding authentication check, otherwise if we have the users encoded password then + * we can try authentication via that mechanic + * + * @return true if authenticated, false otherwise + * @throws LoginException if unable to login + */ + @Override + public boolean login() throws LoginException + { + try + { + if (getCallbackHandler() == null) + { + throw new LoginException("No callback handler"); + } + + Callback[] callbacks = configureCallbacks(); + getCallbackHandler().handle(callbacks); + + String webUserName = ((NameCallback)callbacks[0]).getName(); + Object webCredential = ((ObjectCallback)callbacks[1]).getObject(); + + if (webUserName == null || webCredential == null) + { + setAuthenticated(false); + return isAuthenticated(); + } + + boolean authed = false; + + if (_forceBindingLogin) + { + authed = bindingLogin(webUserName, webCredential); + } + else + { + // This sets read and the credential + JAASUser userInfo = getUser(webUserName); + + if (userInfo == null) + { + setAuthenticated(false); + return false; + } + + setCurrentUser(userInfo); + + if (webCredential instanceof String) + authed = credentialLogin(Credential.getCredential((String)webCredential)); + else + authed = credentialLogin(webCredential); + } + + //only fetch roles if authenticated + if (authed) + getCurrentUser().fetchRoles(); + + return authed; + } + catch (UnsupportedCallbackException e) + { + throw new LoginException("Error obtaining callback information."); + } + catch (IOException e) + { + if (_debug) + LOG.info("Login failure", e); + throw new LoginException("IO Error performing login."); + } + catch (AuthenticationException e) + { + if (_debug) + LOG.info("Login failure", e); + return false; + } + catch (LoginException e) + { + throw e; + } + catch (Exception e) + { + if (_debug) + LOG.info("Login failure", e); + throw new LoginException("Error obtaining user info"); + } + } + + /** + * password supplied authentication check + * + * @param webCredential the web credential + * @return true if authenticated + * @throws LoginException if unable to login + */ + protected boolean credentialLogin(Object webCredential) throws LoginException + { + setAuthenticated(getCurrentUser().checkCredential(webCredential)); + return isAuthenticated(); + } + + /** + * binding authentication check + * This method of authentication works only if the user branch of the DIT (ldap tree) + * has an ACI (access control instruction) that allow the access to any user or at least + * for the user that logs in. + * + * @param username the user name + * @param password the password + * @return true always + * @throws LoginException if unable to bind the login + */ + public boolean bindingLogin(String username, Object password) throws LoginException + { + SearchResult searchResult = findUser(username); + + String userDn = searchResult.getNameInNamespace(); + + LOG.info("Attempting authentication: {}", userDn); + + Hashtable environment = getEnvironment(); + + if (userDn == null || "".equals(userDn)) + { + throw new FailedLoginException("username may not be empty"); + } + environment.put(Context.SECURITY_PRINCIPAL, userDn); + // RFC 4513 section 6.3.1, protect against ldap server implementations that allow successful binding on empty passwords + if (password == null || "".equals(password)) + { + throw new FailedLoginException("password may not be empty"); + } + environment.put(Context.SECURITY_CREDENTIALS, password); + + try + { + DirContext dirContext = new InitialDirContext(environment); + setCurrentUser(new LDAPBindingUser(new UserPrincipal(username, null), dirContext, userDn)); + setAuthenticated(true); + return true; + } + catch (AuthenticationException e) + { + throw new FailedLoginException(e.getMessage()); + } + catch (NamingException e) + { + throw new FailedLoginException(e.getMessage()); + } + } + + private SearchResult findUser(String username) throws LoginException + { + String filter = "(&(objectClass={0})({1}={2}))"; + + if (LOG.isDebugEnabled()) + LOG.debug("Searching for user {} with filter: \'{}\' from base dn: {}", username, filter, _userBaseDn); + + Object[] filterArguments = new Object[]{ + _userObjectClass, + _userIdAttribute, + username + }; + + return findUser(_rootContext, filter, filterArguments); + } + + private SearchResult findUser(DirContext dirContext, String filter, Object[] filterArguments) throws LoginException + { + SearchControls ctls = new SearchControls(); + ctls.setDerefLinkFlag(true); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + NamingEnumeration results; + try + { + results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls); + } + catch (NamingException ex) + { + throw new FailedLoginException(ex.getMessage()); + } + + if (LOG.isDebugEnabled()) + LOG.debug("Found user?: {}", results.hasMoreElements()); + + if (!results.hasMoreElements()) + throw new FailedLoginException("User not found."); + + SearchResult searchResult = (SearchResult)results.nextElement(); + if (results.hasMoreElements()) + throw new FailedLoginException("Search result contains ambiguous entries"); + + return searchResult; + } + + /** + * Init LoginModule. + *

    + * Called once by JAAS after new instance is created. + * + * @param subject the subect + * @param callbackHandler the callback handler + * @param sharedState the shared state map + * @param options the option map + */ + @Override + public void initialize(Subject subject, + CallbackHandler callbackHandler, + Map sharedState, + Map options) + { + super.initialize(subject, callbackHandler, sharedState, options); + + _hostname = (String)options.get("hostname"); + _port = Integer.parseInt((String)options.get("port")); + _contextFactory = (String)options.get("contextFactory"); + _bindDn = (String)options.get("bindDn"); + _bindPassword = (String)options.get("bindPassword"); + _authenticationMethod = (String)options.get("authenticationMethod"); + + _userBaseDn = (String)options.get("userBaseDn"); + + _roleBaseDn = (String)options.get("roleBaseDn"); + + if (options.containsKey("forceBindingLogin")) + { + _forceBindingLogin = Boolean.parseBoolean((String)options.get("forceBindingLogin")); + } + + if (options.containsKey("useLdaps")) + { + _useLdaps = Boolean.parseBoolean((String)options.get("useLdaps")); + } + + _userObjectClass = getOption(options, "userObjectClass", _userObjectClass); + _userRdnAttribute = getOption(options, "userRdnAttribute", _userRdnAttribute); + _userIdAttribute = getOption(options, "userIdAttribute", _userIdAttribute); + _userPasswordAttribute = getOption(options, "userPasswordAttribute", _userPasswordAttribute); + _roleObjectClass = getOption(options, "roleObjectClass", _roleObjectClass); + _roleMemberAttribute = getOption(options, "roleMemberAttribute", _roleMemberAttribute); + _roleNameAttribute = getOption(options, "roleNameAttribute", _roleNameAttribute); + _debug = Boolean.parseBoolean(String.valueOf(getOption(options, "debug", Boolean.toString(_debug)))); + + try + { + _rootContext = new InitialDirContext(getEnvironment()); + } + catch (NamingException ex) + { + throw new IllegalStateException("Unable to establish root context", ex); + } + } + + @Override + public boolean commit() throws LoginException + { + try + { + _rootContext.close(); + } + catch (NamingException e) + { + throw new LoginException("error closing root context: " + e.getMessage()); + } + + return super.commit(); + } + + @Override + public boolean abort() throws LoginException + { + try + { + _rootContext.close(); + } + catch (NamingException e) + { + throw new LoginException("error closing root context: " + e.getMessage()); + } + + return super.abort(); + } + + private String getOption(Map options, String key, String defaultValue) + { + Object value = options.get(key); + + if (value == null) + { + return defaultValue; + } + + return (String)value; + } + + /** + * get the context for connection + * + * @return the environment details for the context + */ + public Hashtable getEnvironment() + { + Properties env = new Properties(); + + env.put(Context.INITIAL_CONTEXT_FACTORY, _contextFactory); + + if (_hostname != null) + { + env.put(Context.PROVIDER_URL, (_useLdaps ? "ldaps://" : "ldap://") + _hostname + (_port == 0 ? "" : ":" + _port) + "/"); + } + + if (_authenticationMethod != null) + { + env.put(Context.SECURITY_AUTHENTICATION, _authenticationMethod); + } + + if (_bindDn != null) + { + env.put(Context.SECURITY_PRINCIPAL, _bindDn); + } + + if (_bindPassword != null) + { + env.put(Context.SECURITY_CREDENTIALS, _bindPassword); + } + + return env; + } + + public static String convertCredentialLdapToJetty(String encryptedPassword) + { + if (encryptedPassword == null) + { + return null; + } + + if (encryptedPassword.toUpperCase(Locale.ENGLISH).startsWith("{MD5}")) + { + String src = encryptedPassword.substring("{MD5}".length(), encryptedPassword.length()); + return "MD5:" + base64ToHex(src); + } + + if (encryptedPassword.toUpperCase(Locale.ENGLISH).startsWith("{CRYPT}")) + { + return "CRYPT:" + encryptedPassword.substring("{CRYPT}".length(), encryptedPassword.length()); + } + + return encryptedPassword; + } + + private static String base64ToHex(String src) + { + byte[] bytes = Base64.getDecoder().decode(src); + return TypeUtil.toString(bytes, 16); + } + + private static String hexToBase64(String src) + { + byte[] bytes = TypeUtil.fromHexString(src); + return Base64.getEncoder().encodeToString(bytes); + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java new file mode 100644 index 000000000000..8b5c8bd26a65 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java @@ -0,0 +1,143 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; + +import org.eclipse.jetty.ee9.jaas.JAASLoginService; +import org.eclipse.jetty.ee9.jaas.PropertyUserStoreManager; +import org.eclipse.jetty.ee9.security.PropertyUserStore; +import org.eclipse.jetty.ee9.security.RolePrincipal; +import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.resource.ResourceFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * PropertyFileLoginModule + */ +public class PropertyFileLoginModule extends AbstractLoginModule +{ + public static final String DEFAULT_FILENAME = "realm.properties"; + private static final Logger LOG = LoggerFactory.getLogger(PropertyFileLoginModule.class); + + private PropertyUserStore _store; + + /** + * Use a PropertyUserStore to read the authentication and authorizaton information contained in + * the file named by the option "file". + * + * @param subject the subject + * @param callbackHandler the callback handler + * @param sharedState the shared state map + * @param options the options map + * @see javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, + * Map) + */ + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) + { + super.initialize(subject, callbackHandler, sharedState, options); + setupPropertyUserStore(options); + } + + /** + * Get an existing, or create a new PropertyUserStore to read the + * authentication and authorization information from the file named by + * the option "file". + * + * @param options configuration options + */ + private void setupPropertyUserStore(Map options) + { + String filename = (String)options.get("file"); + filename = (filename == null ? DEFAULT_FILENAME : filename); + + PropertyUserStoreManager mgr = JAASLoginService.INSTANCE.get().getBean(PropertyUserStoreManager.class); + if (mgr == null) + throw new IllegalStateException("No PropertyUserStoreManager"); + + _store = mgr.getPropertyUserStore(filename); + if (_store == null) + { + int refreshInterval = 0; + String tmp = (String)options.get("refreshInterval"); + if (tmp != null) + { + try + { + refreshInterval = Integer.parseInt(tmp); + } + catch (NumberFormatException e) + { + LOG.warn("'refreshInterval' is not an integer"); + } + } + else + { + tmp = (String)options.get("hotReload"); + if (tmp != null) + { + LOG.warn("Use 'refreshInterval' boolean property instead of 'hotReload'"); + refreshInterval = Boolean.parseBoolean(tmp) ? 1 : 0; + } + } + PropertyUserStore newStore = new PropertyUserStore(); + ResourceFactory resourceFactory = ResourceFactory.of(newStore); + Resource config = resourceFactory.newResource(filename); + newStore.setConfig(config); + newStore.setRefreshInterval(refreshInterval); + _store = mgr.addPropertyUserStore(filename, newStore); + try + { + _store.start(); + } + catch (Exception e) + { + LOG.warn("Exception starting propertyUserStore {} ", config, e); + } + } + } + + /** + * @param userName the user name + * @throws Exception if unable to get the user information + */ + @Override + public JAASUser getUser(String userName) throws Exception + { + if (LOG.isDebugEnabled()) + LOG.debug("Checking PropertyUserStore {} for {}", _store.getConfig(), userName); + UserPrincipal up = _store.getUserPrincipal(userName); + if (up == null) + return null; + + List rps = _store.getRolePrincipals(userName); + List roles = rps == null ? Collections.emptyList() : rps.stream().map(RolePrincipal::getName).collect(Collectors.toList()); + return new JAASUser(up) + { + @Override + public List doFetchRoles() + { + return roles; + } + }; + } +} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/package-info.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/package-info.java new file mode 100644 index 000000000000..3f7441d92b05 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/package-info.java @@ -0,0 +1,18 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +/** + * Jetty Jaas : Various Jaas Implementations for Jetty + */ +package org.eclipse.jetty.security.jaas.spi; + From bc0547d97b4f2a709971279d70dc4bea1141908e Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 12 Mar 2023 21:33:37 +0100 Subject: [PATCH 019/129] WIP --- .../jetty/security/jaas/JAASLoginService.java | 4 +-- .../jaas/callback/DefaultCallbackHandler.java | 19 ++++++++------ ...uestCallback.java => RequestCallback.java} | 10 ++++---- .../jaas/spi/AbstractDatabaseLoginModule.java | 1 + .../jaas/spi/AbstractLoginModule.java | 1 + .../security/jaas/spi/LdapLoginModule.java | 4 +-- .../jaas/spi/PropertyFileLoginModule.java | 10 ++++---- .../org/eclipse/jetty/util/ExceptionUtil.java | 25 +++++++++++++++++++ 8 files changed, 53 insertions(+), 21 deletions(-) rename jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/{ServletRequestCallback.java => RequestCallback.java} (79%) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java index 8c1a0f1a88f9..eb24988e8f4b 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java @@ -36,6 +36,7 @@ import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.security.jaas.callback.DefaultCallbackHandler; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -196,8 +197,7 @@ public UserIdentity login(final String username, final Object credentials, final if (callbackHandler instanceof DefaultCallbackHandler) { DefaultCallbackHandler dch = (DefaultCallbackHandler)callbackHandler; - if (request instanceof HttpServletRequest httpServletRequest) - dch.setRequest(httpServletRequest); + dch.setRequest(request); dch.setCredential(credentials); dch.setUserName(username); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java index 9c01c7f0eca6..8d50a34a68cb 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/DefaultCallbackHandler.java @@ -14,13 +14,15 @@ package org.eclipse.jetty.security.jaas.callback; import java.io.IOException; -import java.util.Arrays; import javax.security.auth.callback.Callback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; -import jakarta.servlet.http.HttpServletRequest; +import org.eclipse.jetty.server.FormFields; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.ExceptionUtil; +import org.eclipse.jetty.util.Fields; /** * DefaultCallbackHandler @@ -30,9 +32,9 @@ */ public class DefaultCallbackHandler extends AbstractCallbackHandler { - private HttpServletRequest _request; + private Request _request; - public void setRequest(HttpServletRequest request) + public void setRequest(Request request) { _request = request; } @@ -60,12 +62,15 @@ else if (callback instanceof RequestParameterCallback) if (_request != null) { RequestParameterCallback rpc = (RequestParameterCallback)callback; - rpc.setParameterValues(Arrays.asList(_request.getParameterValues(rpc.getParameterName()))); + Fields queryFields = Request.extractQueryParameters(_request); + Fields formFields = ExceptionUtil.get(FormFields.from(_request)); + Fields fields = Fields.combine(queryFields, formFields); + rpc.setParameterValues(fields.getValues(rpc.getParameterName())); } } - else if (callback instanceof ServletRequestCallback) + else if (callback instanceof RequestCallback) { - ((ServletRequestCallback)callback).setRequest(_request); + ((RequestCallback)callback).setRequest(_request); } else throw new UnsupportedCallbackException(callback); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestCallback.java similarity index 79% rename from jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java rename to jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestCallback.java index 5de80d564945..b158228e07b7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/ServletRequestCallback.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/callback/RequestCallback.java @@ -15,23 +15,23 @@ import javax.security.auth.callback.Callback; -import jakarta.servlet.ServletRequest; +import org.eclipse.jetty.server.Request; /** * ServletRequestCallback * * Provides access to the request associated with the authentication. */ -public class ServletRequestCallback implements Callback +public class RequestCallback implements Callback { - protected ServletRequest _request; + protected Request _request; - public void setRequest(ServletRequest request) + public void setRequest(Request request) { _request = request; } - public ServletRequest getRequest() + public Request getRequest() { return _request; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java index 918ea2d0439f..4abfd7345b77 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractDatabaseLoginModule.java @@ -23,6 +23,7 @@ import javax.security.auth.callback.CallbackHandler; import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.util.security.Credential; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java index 68b1be6821db..318e835adc1e 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/AbstractLoginModule.java @@ -28,6 +28,7 @@ import javax.security.auth.spi.LoginModule; import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.jaas.JAASRole; import org.eclipse.jetty.security.jaas.callback.ObjectCallback; /** diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java index 2ed6bfb7b9c5..08f3f903889f 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/LdapLoginModule.java @@ -39,8 +39,8 @@ import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; -import org.eclipse.jetty.ee9.jaas.callback.ObjectCallback; -import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.jaas.callback.ObjectCallback; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.security.Credential; import org.slf4j.Logger; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java index 8b5c8bd26a65..596df94df1ca 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/spi/PropertyFileLoginModule.java @@ -20,11 +20,11 @@ import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; -import org.eclipse.jetty.ee9.jaas.JAASLoginService; -import org.eclipse.jetty.ee9.jaas.PropertyUserStoreManager; -import org.eclipse.jetty.ee9.security.PropertyUserStore; -import org.eclipse.jetty.ee9.security.RolePrincipal; -import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.security.PropertyUserStore; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.jaas.JAASLoginService; +import org.eclipse.jetty.security.jaas.PropertyUserStoreManager; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; import org.slf4j.Logger; diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ExceptionUtil.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ExceptionUtil.java index a86d3172b330..279e5136686c 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ExceptionUtil.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ExceptionUtil.java @@ -16,6 +16,8 @@ import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import org.eclipse.jetty.util.thread.Invocable; @@ -288,4 +290,27 @@ public static Throwable combine(Throwable t1, Throwable t2) private ExceptionUtil() { } + + /** + *

    Get from a {@link CompletableFuture} and convert any uncheck exceptions to {@link RuntimeException}.

    + * @param completableFuture The future to get from. + * @param The type of the {@code CompletableFuture} + * @return The value from calling {@link CompletableFuture#get()} + * @throws RuntimeException if the call to {@link CompletableFuture#get()} throws. + */ + public static T get(CompletableFuture completableFuture) + { + try + { + return completableFuture.get(); + } + catch (InterruptedException e) + { + throw new RuntimeException(e); + } + catch (ExecutionException e) + { + throw new RuntimeException(e.getCause()); + } + } } From a521f7cdd53b3be870d325e0d13098fac7bd08eb Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 13 Mar 2023 11:12:54 +0100 Subject: [PATCH 020/129] WIP on JAAS tests --- .../jetty/security/Authentication.java | 38 ++- .../jetty/security/jaas/JAASLoginService.java | 2 +- .../JAASLdapLoginServiceTest.java | 317 ++++++++++++++++++ .../JAASLoginServiceTest.java | 238 +++++++++++++ .../TestHandler.java | 102 ++++++ .../TestLoginModule.java | 59 ++++ .../spi/PropertyFileLoginModuleTest.java | 123 +++++++ .../src/test/resources/login.properties | 1 + 8 files changed, 877 insertions(+), 3 deletions(-) create mode 100644 jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLdapLoginServiceTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLoginServiceTest.java create mode 100644 jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestHandler.java create mode 100644 jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestLoginModule.java create mode 100644 jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/spi/PropertyFileLoginModuleTest.java create mode 100644 jetty-core/jetty-security/src/test/resources/login.properties diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java index 3e57f511826e..4ff3f448f8f9 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java @@ -13,6 +13,7 @@ package org.eclipse.jetty.security; +import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.QuietException; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -39,6 +40,39 @@ static void setAuthentication(Request request, Authentication authentication) request.setAttribute(Authentication.class.getName(), authentication); } + /** + * + * @param request + * @param response + * @param callback + * @return + */ + static boolean authenticate(Request request, Response response, Callback callback) + { + Authentication authentication = getAuthentication(request); + + //if already authenticated, return true + if (authentication instanceof Authentication.User userAuthentication && userAuthentication.getUserIdentity().getUserPrincipal() != null) + return true; + + //do the authentication + if (authentication instanceof Authentication.Deferred deferred) + { + Authentication undeferred = deferred.authenticate(request, response, callback); + if (undeferred instanceof Authentication.ResponseSent) + return false; + + if (undeferred instanceof Authentication.User) + { + setAuthentication(request, undeferred); + return true; + } + } + + Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401); + return false; + } + class Failed extends QuietException.Exception { public Failed(String message) @@ -100,7 +134,6 @@ interface LogoutAuthentication extends Authentication */ interface Deferred extends LoginAuthentication, LogoutAuthentication { - /** * Authenticate if possible without sending a challenge. * This is used to check credentials that have been sent for @@ -118,7 +151,8 @@ interface Deferred extends LoginAuthentication, LogoutAuthentication * * @param request the request * @param response the response - * @return The new Authentication state. + * @return The new Authentication state, which may be {@link Authentication.ResponseSent} if the response + * has been generated and the {@code callback} called. */ Authentication authenticate(Request request, Response response, Callback callback); } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java index eb24988e8f4b..1f2d7bea0b00 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java @@ -54,7 +54,7 @@ public class JAASLoginService extends ContainerLifeCycle implements LoginService { private static final Logger LOG = LoggerFactory.getLogger(JAASLoginService.class); - public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.ee9.jaas.JAASRole"; + public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.security.jaas.JAASRole"; public static final String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME}; public static final ThreadLocal INSTANCE = new ThreadLocal<>(); diff --git a/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLdapLoginServiceTest.java b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLdapLoginServiceTest.java new file mode 100644 index 000000000000..9ec9a1c218b0 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLdapLoginServiceTest.java @@ -0,0 +1,317 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +/* TODO +import java.io.IOException; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag; +import javax.security.auth.login.Configuration; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.directory.server.annotations.CreateLdapServer; +import org.apache.directory.server.annotations.CreateTransport; +import org.apache.directory.server.core.annotations.ApplyLdifs; +import org.apache.directory.server.core.annotations.CreateDS; +import org.apache.directory.server.core.annotations.CreatePartition; +import org.apache.directory.server.core.integ.FrameworkRunner; +import org.apache.directory.server.ldap.LdapServer; +import org.eclipse.jetty.ee10.jaas.spi.LdapLoginModule; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee10.servlet.security.DefaultIdentityService; +import org.eclipse.jetty.ee10.servlet.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.startsWith; + +@RunWith(FrameworkRunner.class) +@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")}) +@CreateDS(allowAnonAccess = false, partitions = { + @CreatePartition(name = "Users Partition", suffix = "ou=people,dc=jetty,dc=org"), + @CreatePartition(name = "Groups Partition", suffix = "ou=groups,dc=jetty,dc=org") +}) +@ApplyLdifs({ + // Entry 1 + "dn: ou=people,dc=jetty,dc=org", + "objectClass: organizationalunit", + "objectClass: top", + "ou: people", + // Entry # 2 + "dn:uid=someone,ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: someone", + "sn: sn test", + "userPassword: complicatedpassword", + // Entry # 3 + "dn:uid=someoneelse,ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: someoneelse", + "sn: sn test", + "userPassword: verycomplicatedpassword", + // Entry 4 + "dn: ou=groups,dc=jetty,dc=org", + "objectClass: organizationalunit", + "objectClass: top", + "ou: groups", + // Entry 5 + "dn: ou=subdir,ou=people,dc=jetty,dc=org", + "objectClass: organizationalunit", + "objectClass: top", + "ou: subdir", + // Entry # 6 + "dn:uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: uniqueuser", + "sn: unique user", + "userPassword: hello123", + // Entry # 7 + "dn:uid=ambiguousone,ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: ambiguous1", + "sn: ambiguous user", + "userPassword: foobar", + // Entry # 8 + "dn:uid=ambiguousone,ou=subdir,ou=people,dc=jetty,dc=org", + "objectClass: inetOrgPerson", + "cn: ambiguous2", + "sn: ambiguous subdir user", + "userPassword: barfoo", + // Entry 9 + "dn: cn=developers,ou=groups,dc=jetty,dc=org", + "objectClass: groupOfUniqueNames", + "objectClass: top", + "ou: groups", + "description: People who try to build good software", + "uniquemember: uid=someone,ou=people,dc=jetty,dc=org", + "uniquemember: uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", + "cn: developers", + // Entry 10 + "dn: cn=admin,ou=groups,dc=jetty,dc=org", + "objectClass: groupOfUniqueNames", + "objectClass: top", + "ou: groups", + "description: People who try to run software build by developers", + "uniquemember: uid=someone,ou=people,dc=jetty,dc=org", + "uniquemember: uid=someoneelse,ou=people,dc=jetty,dc=org", + "uniquemember: uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", + "cn: admin" +}) +*/ + +public class JAASLdapLoginServiceTest +{ + /* TODO + public static class TestConfiguration extends Configuration + { + private boolean forceBindingLogin; + + public TestConfiguration(boolean forceBindingLogin) + { + this.forceBindingLogin = forceBindingLogin; + } + + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) + { + Map options = new HashMap<>(); + options.put("hostname", "localhost"); + options.put("port", Integer.toString(_ldapServer.getTransports()[0].getPort())); + options.put("contextFactory", "com.sun.jndi.ldap.LdapCtxFactory"); + options.put("bindDn", "uid=admin,ou=system"); + options.put("bindPassword", "secret"); + options.put("userBaseDn", "ou=people,dc=jetty,dc=org"); + options.put("roleBaseDn", "ou=groups,dc=jetty,dc=org"); + options.put("roleNameAttribute", "cn"); + options.put("forceBindingLogin", Boolean.toString(forceBindingLogin)); + AppConfigurationEntry entry = new AppConfigurationEntry(LdapLoginModule.class.getCanonicalName(), LoginModuleControlFlag.REQUIRED, options); + + return new AppConfigurationEntry[]{entry}; + } + } + + public static LdapServer getLdapServer() + { + return _ldapServer; + } + + public static void setLdapServer(LdapServer ldapServer) + { + _ldapServer = ldapServer; + } + + private static LdapServer _ldapServer; + private Server _server; + private LocalConnector _connector; + private ServletContextHandler _context; + + public void setUp() throws Exception + { + _server = new Server(); + _connector = new LocalConnector(_server); + _server.addConnector(_connector); + + _context = new ServletContextHandler(); + _context.setContextPath("/ctx"); + _server.setHandler(_context); + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + security.setAuthenticator(new BasicAuthenticator()); + _context.setSecurityHandler(security); + } + + private JAASLoginService jaasLoginService(String name) + { + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.ee10.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(new TestConfiguration(true)); + return ls; + } + + private String doLogin(String username, String password, List hasRoles, List hasntRoles) throws Exception + { + JAASLoginService ls = jaasLoginService("foo"); + _server.addBean(ls, true); + + _context.setServletHandler(new ServletHandler()); + ServletHolder holder = new ServletHolder(); + holder.setServlet(new TestServlet(hasRoles, hasntRoles)); + _context.getServletHandler().addServletWithMapping(holder, "/"); + + _server.start(); + + return _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString((username + ":" + password).getBytes(ISO_8859_1)) + "\n\n"); + } + + @Test + public void testLdapUserIdentity() throws Exception + { + setUp(); + _context.setServletHandler(new ServletHandler()); + ServletHolder holder = new ServletHolder(); + holder.setServlet(new TestServlet(Arrays.asList("developers", "admin"), Arrays.asList("blabla"))); + _context.getServletHandler().addServletWithMapping(holder, "/"); + + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.ee10.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(new TestConfiguration(false)); + + _server.addBean(ls, true); + _server.start(); + + String response = _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("someone:complicatedpassword".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + + _server.stop(); + + _context.setServletHandler(new ServletHandler()); + holder = new ServletHolder(); + holder.setServlet(new TestServlet(Arrays.asList("admin"), Arrays.asList("developers, blabla"))); + _context.getServletHandler().addServletWithMapping(holder, "/"); + + _server.start(); + + response = _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("someoneelse:verycomplicatedpassword".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + } + + @Test + public void testLdapUserIdentityBindingLogin() throws Exception + { + setUp(); + _context.setServletHandler(new ServletHandler()); + ServletHolder holder = new ServletHolder(); + holder.setServlet(new TestServlet(Arrays.asList("developers", "admin"), Arrays.asList("blabla"))); + _context.getServletHandler().addServletWithMapping(holder, "/"); + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.ee10.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(new TestConfiguration(true)); + _server.addBean(ls, true); + _server.start(); + + + String response = _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("someone:complicatedpassword".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + + _server.stop(); + _context.setServletHandler(new ServletHandler()); + _context.addServlet(new HttpServlet() + { + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + //check authentication status + if (req.getUserPrincipal() == null) + req.authenticate(resp); + } + + }, "/"); + _server.start(); + + //TODO this test shows response already committed! + response = _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("someone:wrongpassword".getBytes(ISO_8859_1)) + "\n\n"); + System.err.println(response); + assertThat(response, startsWith("HTTP/1.1 " + HttpServletResponse.SC_UNAUTHORIZED)); + } + + @Test + public void testLdapBindingSubdirUniqueUserName() throws Exception + { + setUp(); + String response = doLogin("uniqueuser", "hello123", Arrays.asList("developers", "admin"), Arrays.asList("blabla")); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + } + + //TODO test is failing, needs more work + @Test + public void testLdapBindingAmbiguousUserName() throws Exception + { + setUp(); + String response = doLogin("ambiguousone", "foobar", null, null); + assertThat(response, startsWith("HTTP/1.1 " + HttpServletResponse.SC_UNAUTHORIZED)); + } + + //TODO test is failing, needs more work + @Test + public void testLdapBindingSubdirAmbiguousUserName() throws Exception + { + setUp(); + String response = doLogin("ambiguousone", "barfoo", null, null); + assertThat(response, startsWith("HTTP/1.1 " + HttpServletResponse.SC_UNAUTHORIZED)); + } + + */ +} diff --git a/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLoginServiceTest.java b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLoginServiceTest.java new file mode 100644 index 000000000000..53f1a9d968bd --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/JAASLoginServiceTest.java @@ -0,0 +1,238 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +/* TODO +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.security.ConstraintMapping; +import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee10.servlet.security.DefaultIdentityService; +import org.eclipse.jetty.ee10.servlet.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.security.Constraint; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertEquals; +*/ + +/** + * JAASLoginServiceTest + */ +public class JAASLoginServiceTest +{ + interface SomeRole + { + + } +/* TODO + public class TestRole implements Principal, SomeRole + { + String _name; + + public TestRole(String name) + { + _name = name; + } + + public String getName() + { + return _name; + } + } + + public class AnotherTestRole extends TestRole + { + public AnotherTestRole(String name) + { + super(name); + } + } + + public class NotTestRole implements Principal + { + String _name; + + public NotTestRole(String n) + { + _name = n; + } + + public String getName() + { + return _name; + } + } + + public static class TestServlet extends HttpServlet + { + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + resp.setStatus(200); + resp.setContentType("text/plain"); + resp.getWriter().println("All OK"); + resp.getWriter().println("requestURI=" + req.getRequestURI()); + } + } + + private Server _server; + private LocalConnector _connector; + private ServletContextHandler _context; + + @BeforeEach + public void setUp() throws Exception + { + _server = new Server(); + _connector = new LocalConnector(_server); + _server.addConnector(_connector); + + _context = new ServletContextHandler(); + _context.setContextPath("/ctx"); + _context.addServlet(new TestServlet(), "/"); + _server.setHandler(_context); + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + security.setAuthenticator(new BasicAuthenticator()); + Constraint constraint = new Constraint("All", "users"); + constraint.setAuthenticate(true); + ConstraintMapping mapping = new ConstraintMapping(); + mapping.setPathSpec("/jaspi/*"); + mapping.setConstraint(constraint); + security.addConstraintMapping(mapping); + _context.setSecurityHandler(security); + } + + @AfterEach + public void tearDown() throws Exception + { + _server.stop(); + } + + @Test + public void testServletRequestCallback() throws Exception + { + Configuration config = new Configuration() + { + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) + { + return new AppConfigurationEntry[] { + new AppConfigurationEntry(TestLoginModule.class.getCanonicalName(), + LoginModuleControlFlag.REQUIRED, + Collections.emptyMap()) + }; + } + }; + + //Test with the DefaultCallbackHandler + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.ee10.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(config); + _server.addBean(ls, true); + _server.start(); + + String response = _connector.getResponse("GET /ctx/jaspi/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("aaardvaark:aaa".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + + _server.stop(); + _server.removeBean(ls); + + //Test with the fallback CallbackHandler + ls = new JAASLoginService("foo"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(config); + _server.addBean(ls, true); + _server.start(); + + response = _connector.getResponse("GET /ctx/jaspi/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("aaardvaark:aaa".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + } + + @Test + public void testLoginServiceRoles() throws Exception + { + JAASLoginService ls = new JAASLoginService("foo"); + + //test that we always add in the DEFAULT ROLE CLASSNAME + ls.setRoleClassNames(new String[]{"arole", "brole"}); + String[] roles = ls.getRoleClassNames(); + assertEquals(3, roles.length); + assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, roles[2]); + + ls.setRoleClassNames(new String[]{}); + assertEquals(1, ls.getRoleClassNames().length); + assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, ls.getRoleClassNames()[0]); + + ls.setRoleClassNames(null); + assertEquals(1, ls.getRoleClassNames().length); + assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, ls.getRoleClassNames()[0]); + + //test a custom role class where some of the roles are subclasses of it + ls.setRoleClassNames(new String[]{TestRole.class.getName()}); + Subject subject = new Subject(); + subject.getPrincipals().add(new NotTestRole("w")); + subject.getPrincipals().add(new TestRole("x")); + subject.getPrincipals().add(new TestRole("y")); + subject.getPrincipals().add(new AnotherTestRole("z")); + + String[] groups = ls.getGroups(subject); + assertThat(Arrays.asList(groups), containsInAnyOrder("x", "y", "z")); + + //test a custom role class + ls.setRoleClassNames(new String[]{AnotherTestRole.class.getName()}); + Subject subject2 = new Subject(); + subject2.getPrincipals().add(new NotTestRole("w")); + subject2.getPrincipals().add(new TestRole("x")); + subject2.getPrincipals().add(new TestRole("y")); + subject2.getPrincipals().add(new AnotherTestRole("z")); + String[] s2groups = ls.getGroups(subject2); + assertThat(s2groups, is(notNullValue())); + assertThat(Arrays.asList(s2groups), containsInAnyOrder("z")); + + //test a custom role class that implements an interface + ls.setRoleClassNames(new String[]{SomeRole.class.getName()}); + Subject subject3 = new Subject(); + subject3.getPrincipals().add(new NotTestRole("w")); + subject3.getPrincipals().add(new TestRole("x")); + subject3.getPrincipals().add(new TestRole("y")); + subject3.getPrincipals().add(new AnotherTestRole("z")); + String[] s3groups = ls.getGroups(subject3); + assertThat(s3groups, is(notNullValue())); + assertThat(Arrays.asList(s3groups), containsInAnyOrder("x", "y", "z")); + + //test a class that doesn't match + ls.setRoleClassNames(new String[]{NotTestRole.class.getName()}); + Subject subject4 = new Subject(); + subject4.getPrincipals().add(new TestRole("x")); + subject4.getPrincipals().add(new TestRole("y")); + subject4.getPrincipals().add(new AnotherTestRole("z")); + assertEquals(0, ls.getGroups(subject4).length); + } + */ +} diff --git a/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestHandler.java b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestHandler.java new file mode 100644 index 000000000000..7a834952de99 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestHandler.java @@ -0,0 +1,102 @@ + +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.util.List; + +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.HttpException; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; + +public class TestHandler extends Handler.Abstract +{ + private List _hasRoles; + private List _hasntRoles; + + public TestHandler(List hasRoles, List hasntRoles) + { + _hasRoles = hasRoles; + _hasntRoles = hasntRoles; + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + if (_hasRoles == null && _hasntRoles == null) + { + try + { + // TODO this is wrong + Authentication.authenticate(request, response, callback); + } + catch (Throwable e) + { + //TODO: an Exception should only be thrown here if the response has + //not been set, but currently it seems that the ServletException is thrown + //anyway by ServletContextRequest.ServletApiRequest.authenticate. + } + } + else + { + testHasRoles(request, response); + testHasntRoles(request, response); + + response.setStatus(200); + response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain"); + Content.Sink.write(response, true, "All OK\nrequestURI=" + request.getHttpURI(), callback); + } + return true; + } + + private void testHasRoles(Request request, Response response) + { + if (_hasRoles != null) + { + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication userAuthentication) + { + for (String role : _hasRoles) + { + if (!userAuthentication.isUserInRole(role)) + throw new BadMessageException(HttpStatus.FORBIDDEN_403, "! in role " + role); + } + } + } + } + + private void testHasntRoles(Request request, Response response) + { + if (_hasntRoles != null) + { + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication userAuthentication) + { + for (String role : _hasntRoles) + { + if (userAuthentication.isUserInRole(role)) + throw new HttpException.RuntimeException(500, "in role " + role); + } + } + } + } +} \ No newline at end of file diff --git a/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestLoginModule.java b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestLoginModule.java new file mode 100644 index 000000000000..a61727aab559 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/TestLoginModule.java @@ -0,0 +1,59 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas; + +import java.util.Collections; +import java.util.List; +import javax.security.auth.callback.Callback; +import javax.security.auth.login.LoginException; + +import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.jaas.callback.RequestCallback; +import org.eclipse.jetty.security.jaas.spi.AbstractLoginModule; +import org.eclipse.jetty.util.ArrayUtil; +import org.eclipse.jetty.util.security.Password; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class TestLoginModule extends AbstractLoginModule +{ + public RequestCallback _callback = new RequestCallback(); + + @Override + public JAASUser getUser(String username) throws Exception + { + return new JAASUser(new UserPrincipal(username, new Password("aaa"))) + { + @Override + public List doFetchRoles() throws Exception + { + return Collections.singletonList("users"); + } + }; + } + + @Override + public Callback[] configureCallbacks() + { + return ArrayUtil.addToArray(super.configureCallbacks(), _callback, Callback.class); + } + + @Override + public boolean login() throws LoginException + { + boolean result = super.login(); + assertNotNull(_callback.getRequest()); + return result; + } +} diff --git a/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/spi/PropertyFileLoginModuleTest.java b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/spi/PropertyFileLoginModuleTest.java new file mode 100644 index 000000000000..e38f1bc15d51 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org.eclipse.jetty.security.jaas/spi/PropertyFileLoginModuleTest.java @@ -0,0 +1,123 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.jaas.spi; + +import java.io.File; +import java.util.Base64; +import java.util.Collections; +import javax.security.auth.login.AppConfigurationEntry; +import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag; +import javax.security.auth.login.Configuration; + +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.PropertyUserStore; +import org.eclipse.jetty.security.jaas.JAASLoginService; +import org.eclipse.jetty.security.jaas.PropertyUserStoreManager; +import org.eclipse.jetty.server.LocalConnector; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static java.nio.charset.StandardCharsets.ISO_8859_1; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.startsWith; + +public class PropertyFileLoginModuleTest +{ + private Server _server; + private LocalConnector _connector; + + @BeforeEach + public void setUp() throws Exception + { + _server = new Server(); + + _connector = new LocalConnector(_server); + _server.addConnector(_connector); + + } + + @AfterEach + public void tearDown() throws Exception + { + _server.stop(); + } + + @Test + @Disabled //TODO + public void testPropertyFileLoginModule() throws Exception + { + //configure for PropertyFileLoginModule + File loginProperties = MavenTestingUtils.getTestResourceFile("login.properties"); + + Configuration testConfig = new Configuration() + { + @Override + public AppConfigurationEntry[] getAppConfigurationEntry(String name) + { + return new AppConfigurationEntry[]{new AppConfigurationEntry(PropertyFileLoginModule.class.getName(), + LoginModuleControlFlag.REQUIRED, + Collections.singletonMap("file", loginProperties.getAbsolutePath()))}; + } + }; + + ContextHandler context = new ContextHandler(); + context.setContextPath("/ctx"); + /* TODO + context.setHandler(new TestHandler(Arrays.asList("role1", "role2", "role3"), Arrays.asList("role4")), "/"); + _server.setHandler(context); + + ConstraintSecurityHandler security = new ConstraintSecurityHandler(); + security.setAuthenticator(new BasicAuthenticator()); + context.setSecurityHandler(security); + + */ + + JAASLoginService ls = new JAASLoginService("foo"); + ls.setCallbackHandlerClass("org.eclipse.jetty.ee10.jaas.callback.DefaultCallbackHandler"); + ls.setIdentityService(new DefaultIdentityService()); + ls.setConfiguration(testConfig); + _server.addBean(ls, true); + + _server.start(); + + //test that the manager is created when the JAASLoginService starts + PropertyUserStoreManager mgr = ls.getBean(PropertyUserStoreManager.class); + assertThat(mgr, notNullValue()); + + //test the PropertyFileLoginModule authentication and authorization + String response = _connector.getResponse("GET /ctx/test HTTP/1.0\n" + "Authorization: Basic " + + Base64.getEncoder().encodeToString("fred:pwd".getBytes(ISO_8859_1)) + "\n\n"); + assertThat(response, startsWith("HTTP/1.1 200 OK")); + + //Test that the PropertyUserStore is created by the PropertyFileLoginModule + PropertyUserStore store = mgr.getPropertyUserStore(loginProperties.getAbsolutePath()); + assertThat(store, is(notNullValue())); + assertThat(store.isRunning(), is(true)); + assertThat(store.isHotReload(), is(false)); + + //test that the PropertyUserStoreManager is stopped and all PropertyUserStores stopped + _server.stop(); + assertThat(mgr.isStopped(), is(true)); + assertThat(mgr.getPropertyUserStore(loginProperties.getAbsolutePath()), is(nullValue())); + assertThat(store.isStopped(), is(true)); + } +} diff --git a/jetty-core/jetty-security/src/test/resources/login.properties b/jetty-core/jetty-security/src/test/resources/login.properties new file mode 100644 index 000000000000..22a4bedc7b7b --- /dev/null +++ b/jetty-core/jetty-security/src/test/resources/login.properties @@ -0,0 +1 @@ +fred=pwd,role1,role2,role3 \ No newline at end of file From 2e4bcd565f4279422aed76ad8332c0ac6248deac Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 13 Mar 2023 19:18:44 +0100 Subject: [PATCH 021/129] WIP on major simplification --- .../security/AbstractUserAuthentication.java | 32 ++- .../jetty/security/Authentication.java | 203 ++++++------------ .../eclipse/jetty/security/Authenticator.java | 35 ++- .../security/LoggedOutAuthentication.java | 52 ----- .../jetty/security/SecurityHandler.java | 153 +++++-------- .../authentication/BasicAuthenticator.java | 11 +- .../ConfigurableSpnegoAuthenticator.java | 13 +- .../DeferredAuthentication.java | 41 +--- .../authentication/DigestAuthenticator.java | 9 +- .../authentication/FormAuthenticator.java | 24 ++- .../SslClientCertAuthenticator.java | 7 +- .../security/AuthenticationTestHandler.java | 158 ++++++++++++++ .../security/BasicAuthenticatorTest.java | 196 +++++++++++------ .../security/DefaultIdentityServiceTest.java | 8 +- .../jetty/security/FormAuthenticatorTest.java | 3 +- .../jetty/security/SecurityHandlerTest.java | 3 +- .../java/org/eclipse/jetty/util/Fields.java | 12 ++ 17 files changed, 504 insertions(+), 456 deletions(-) delete mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java create mode 100644 jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index 56d0a661fb53..559f8a9442dc 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -16,8 +16,11 @@ import java.io.Serializable; import org.eclipse.jetty.security.Authentication.User; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.security.authentication.LoginAuthenticator; import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; /** * AbstractUserAuthentication @@ -56,20 +59,41 @@ public boolean isUserInRole(String role) } @Override - public Authentication logout(Request request) + public void logout(Request request) { SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); if (security != null) { security.logout(this); Authenticator authenticator = security.getAuthenticator(); - if (authenticator instanceof LoginAuthenticator) + + Authentication authentication = null; + if (authenticator instanceof LoginAuthenticator loginAuthenticator) { ((LoginAuthenticator)authenticator).logout(request); - return new LoggedOutAuthentication((LoginAuthenticator)authenticator); + authentication = new LoggedOutAuthentication(loginAuthenticator); } + Authentication.setAuthentication(request, authentication); + } + } + + private static class LoggedOutAuthentication extends DeferredAuthentication + { + public LoggedOutAuthentication(LoginAuthenticator authenticator) + { + super(authenticator); } - return Authentication.UNAUTHENTICATED; + @Override + public Authentication.User authenticate(Request request) + { + return null; + } + + @Override + public Authentication authenticate(Request request, Response response, Callback callback) + { + return null; + } } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java index 4ff3f448f8f9..284fcdebd1be 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java @@ -13,8 +13,10 @@ package org.eclipse.jetty.security; +import org.eclipse.jetty.http.HttpException; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.QuietException; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.util.Callback; @@ -40,36 +42,84 @@ static void setAuthentication(Request request, Authentication authentication) request.setAttribute(Authentication.class.getName(), authentication); } - /** - * - * @param request - * @param response - * @param callback - * @return - */ - static boolean authenticate(Request request, Response response, Callback callback) + static Authentication.User authenticate(Request request) { Authentication authentication = getAuthentication(request); //if already authenticated, return true - if (authentication instanceof Authentication.User userAuthentication && userAuthentication.getUserIdentity().getUserPrincipal() != null) - return true; + if (authentication instanceof Authentication.User user) + return user; + + //do the authentication + if (authentication instanceof DeferredAuthentication deferred) + { + Authentication.User undeferred = deferred.authenticate(request); + if (undeferred != null) + { + setAuthentication(request, undeferred); + return undeferred; + } + } + return null; + } + + static Authentication.User authenticate(Request request, Response response, Callback callback) + { + Authentication authentication = getAuthentication(request); + + //if already authenticated, return true + if (authentication instanceof Authentication.User user) + return user; //do the authentication - if (authentication instanceof Authentication.Deferred deferred) + if (authentication instanceof DeferredAuthentication deferred) { Authentication undeferred = deferred.authenticate(request, response, callback); if (undeferred instanceof Authentication.ResponseSent) - return false; + return null; - if (undeferred instanceof Authentication.User) + if (undeferred instanceof Authentication.User user) { setAuthentication(request, undeferred); - return true; + return user; } } + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); + return null; + } + + static Authentication.User login(String username, String password, Request request, Response response) + { + Authentication authentication = getAuthentication(request); - Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401); + //if already authenticated, return true + if (authentication instanceof Authentication.User) + throw new HttpException.RuntimeException(HttpStatus.INTERNAL_SERVER_ERROR_500, "Already authenticated"); + + //do the authentication + if (authentication instanceof DeferredAuthentication deferred) + { + Authentication.User undeferred = deferred.login(username, password, request, response); + if (undeferred != null) + { + setAuthentication(request, undeferred); + return undeferred; + } + } + + return null; + } + + static boolean logout(Request request) + { + Authentication authentication = getAuthentication(request); + + //if already authenticated, return true + if (authentication instanceof Authentication.User userAuthentication) + { + userAuthentication.logout(request); + return true; + } return false; } @@ -84,77 +134,21 @@ public Failed(String message) /** * A successful Authentication with User information. */ - interface User extends LogoutAuthentication + interface User extends Authentication { String getAuthMethod(); UserIdentity getUserIdentity(); boolean isUserInRole(String role); - } - - /** - * An authentication that is capable of performing a programmatic login - * operation. - */ - interface LoginAuthentication extends Authentication - { - - /** - * Login with the LOGIN authenticator - * - * @param username the username - * @param password the password - * @param request the request - * @return The new Authentication state - */ - Authentication login(String username, Object password, Request request, Response response); - } - - /** - * An authentication that is capable of performing a programmatic - * logout operation. - */ - interface LogoutAuthentication extends Authentication - { /** * Remove any user information that may be present in the request * such that a call to getUserPrincipal/getRemoteUser will return null. * * @param request the request - * @return NoAuthentication if we successfully logged out - */ - Authentication logout(Request request); - } - - /** - * A deferred authentication with methods to progress - * the authentication process. - */ - interface Deferred extends LoginAuthentication, LogoutAuthentication - { - /** - * Authenticate if possible without sending a challenge. - * This is used to check credentials that have been sent for - * non-mandatory authentication. - * - * @param request the request - * @return The new Authentication state. - */ - Authentication authenticate(Request request); - - /** - * Authenticate and possibly send a challenge. - * This is used to initiate authentication for previously - * non-mandatory authentication. - * - * @param request the request - * @param response the response - * @return The new Authentication state, which may be {@link Authentication.ResponseSent} if the response - * has been generated and the {@code callback} called. */ - Authentication authenticate(Request request, Response response, Callback callback); + void logout(Request request); } /** @@ -167,69 +161,12 @@ interface ResponseSent extends Authentication { } - /** - * An Authentication Challenge has been sent. - */ - interface Challenge extends ResponseSent - { - } - - /** - * An Authentication Failure has been sent. - */ - interface Failure extends ResponseSent - { - } - - interface SendSuccess extends ResponseSent - { - } - - /** - * After a logout, the authentication reverts to a state - * where it is possible to programmatically log in again. - */ - interface NonAuthenticated extends LoginAuthentication - { - } - - /** - * Unauthenticated state. - *

    - * This convenience instance is for non mandatory authentication where credentials - * have been presented and checked, but failed authentication. - */ - Authentication UNAUTHENTICATED = - new Authentication() - { - @Override - public String toString() - { - return "UNAUTHENTICATED"; - } - }; - - /** - * Authentication not checked - *

    - * This convenience instance us for non mandatory authentication when no - * credentials are present to be checked. - */ - Authentication NOT_CHECKED = new Authentication() - { - @Override - public String toString() - { - return "NOT CHECKED"; - } - }; - /** * Authentication challenge sent. *

    * This convenience instance is for when an authentication challenge has been sent. */ - Authentication SEND_CONTINUE = new Challenge() + Authentication CHALLENGE = new ResponseSent() { @Override public String toString() @@ -243,7 +180,7 @@ public String toString() *

    * This convenience instance is for when an authentication failure has been sent. */ - Authentication SEND_FAILURE = new Failure() + Authentication SEND_FAILURE = new ResponseSent() { @Override public String toString() @@ -251,7 +188,7 @@ public String toString() return "FAILURE"; } }; - Authentication SEND_SUCCESS = new SendSuccess() + Authentication SEND_SUCCESS = new ResponseSent() { @Override public String toString() diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 014fd5f771e7..93ae930d4a31 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -42,6 +42,7 @@ public interface Authenticator String NEGOTIATE_AUTH = "NEGOTIATE"; String OPENID_AUTH = "OPENID"; + /** * Configure the Authenticator * @@ -68,37 +69,33 @@ default Request prepareRequest(Request request) return request; } + /** + * Get an {@link Constraint.Authentication} applicable to the path for + * this authenticator. This is typically used to vary protection on special URIs known to a + * specific {@link Authenticator} (e.g. /j_security_check for + * the {@link org.eclipse.jetty.security.authentication.FormAuthenticator}. + * @param pathInContext The pathInContext to potentially constrain. + * @param existing The existing authentication constraint for the pathInContext determined independently of {@link Authenticator} + * @return The {@link Constraint.Authentication} to apply. + */ + default Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) + { + return existing == null ? Constraint.Authentication.REQUIRE_NONE : existing; + } + /** * Validate a request * * @param request The request * @param response The response * @param callback the callback to use for writing a response - * @param mandatory True if authentication is mandatory. * @return An Authentication. If Authentication is successful, this will be a {@link User}. If a response has * been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will * implement {@link Authentication.ResponseSent}. If Authentication is not mandatory, then a * {@link Authentication.Deferred} may be returned. * @throws ServerAuthException if unable to validate request */ - Authentication validateRequest(Request request, Response response, Callback callback, boolean mandatory) throws ServerAuthException; - - /** - * is response secure - * - * @param request the request - * @param response the response - * @param callback the callback to write a response - * @param mandatory if security is mandatory - * @param validatedUser the user that was validated - * @return true if response is secure - * @throws ServerAuthException if unable to test response - */ - @Deprecated - default boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, User validatedUser) throws ServerAuthException - { - return true; - } + Authentication validateRequest(Request request, Response response, Callback callback) throws ServerAuthException; /** * Authenticator Configuration diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java deleted file mode 100644 index 592d5a8eeb90..000000000000 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoggedOutAuthentication.java +++ /dev/null @@ -1,52 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.security; - -import org.eclipse.jetty.security.authentication.LoginAuthenticator; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; - -/** - * LoggedOutAuthentication - * - * An Authentication indicating that a user has been previously, but is not currently logged in, - * but may be capable of logging in after a call to Request.login(String,String) - */ -public class LoggedOutAuthentication implements Authentication.NonAuthenticated -{ - private LoginAuthenticator _authenticator; - - public LoggedOutAuthentication(LoginAuthenticator authenticator) - { - _authenticator = authenticator; - } - - @Override - public Authentication login(String username, Object password, Request request, Response response) - { - if (username == null) - return null; - - UserIdentity identity = _authenticator.login(username, password, request, response); - if (identity != null) - { - IdentityService identityService = _authenticator.getLoginService().getIdentityService(); - UserAuthentication authentication = new UserAuthentication("API", identity); - if (identityService != null) - identityService.associate(identity); - return authentication; - } - return null; - } -} diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 72c889312e01..c2baa852e9ca 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -13,7 +13,6 @@ package org.eclipse.jetty.security; -import java.io.IOException; import java.security.Principal; import java.util.ArrayList; import java.util.Collections; @@ -31,6 +30,7 @@ import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.security.Authenticator.AuthConfiguration; import org.eclipse.jetty.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.authentication.LoginAuthenticator; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; @@ -73,6 +73,7 @@ public abstract class SecurityHandler extends Handler.Wrapper implements AuthCon private LoginService _loginService; private IdentityService _identityService; private boolean _renewSession = true; + DeferredAuthentication _deferredAuthentication; static { @@ -363,6 +364,11 @@ else if (_realmName != null) throw new IllegalStateException("No Authenticator"); } + if (_authenticator instanceof LoginAuthenticator loginAuthenticator) + { + _deferredAuthentication = new DeferredAuthentication(loginAuthenticator); + addBean(_deferredAuthentication); + } super.doStart(); } @@ -382,6 +388,11 @@ protected void doStop() throws Exception _loginService = null; } + if (_deferredAuthentication != null) + { + removeBean(_deferredAuthentication); + _deferredAuthentication = null; + } super.doStop(); } @@ -410,19 +421,11 @@ public boolean handle(Request request, Response response, Callback callback) thr Handler next = getHandler(); if (next == null) return false; - - Authenticator authenticator = _authenticator; - if (authenticator != null) - request = authenticator.prepareRequest(request); String pathInContext = Request.getPathInContext(request); Constraint constraint = getConstraint(pathInContext, request); - if (constraint == null) - { - //don't need to do any security work, let other handlers do the processing - return next.handle(request, response, callback); - } + constraint = Constraint.NONE; if (constraint.isForbidden()) { @@ -431,101 +434,53 @@ public boolean handle(Request request, Response response, Callback callback) thr } // Check data constraints - if (!checkTransport(pathInContext, request, response, callback, constraint)) - return true; - - // is Auth mandatory? - boolean authMandatory = constraint.getAuthentication() != null && constraint.getAuthentication() != Constraint.Authentication.REQUIRE_NONE; - if (authMandatory && authenticator == null) + if (constraint.isConfidential() && !request.isSecure()) { - LOG.warn("No authenticator for: {}", constraint); - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); + redirectToSecure(request, response, callback); return true; } - // check authentication + // Determine Constraint.Authentication + Constraint.Authentication constraintAuthentication = constraint.getAuthentication(); + constraintAuthentication = _authenticator.getConstraintAuthentication(pathInContext, constraintAuthentication); + boolean mustValidate = constraintAuthentication != Constraint.Authentication.REQUIRE_NONE; + try { - Authentication authentication = org.eclipse.jetty.security.Authentication.getAuthentication(request); - if (authentication == null || authentication == org.eclipse.jetty.security.Authentication.NOT_CHECKED) - authentication = authenticator == null - ? org.eclipse.jetty.security.Authentication.UNAUTHENTICATED - : authenticator.validateRequest(request, response, callback, authMandatory); + Authentication authentication = mustValidate ? _authenticator.validateRequest(request, response, callback) : null; if (authentication instanceof Authentication.ResponseSent) return true; - if (authentication instanceof Authentication.User userAuth) + if (isNotAuthorized(constraint, authentication)) { - org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); - try (AutoCloseable association = _identityService.associate(userAuth.getUserIdentity())) - { - if (authMandatory) - { - boolean authorized = checkAuthentication(Request.getPathInContext(request), request, response, constraint, userAuth.getUserIdentity()); - if (!authorized) - { - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!role"); - return true; - } - } - - //process the request by other handlers - boolean processed = next.handle(request, response, callback); - - // TODO this looks wrong as in way too late - if (processed && authenticator != null) - authenticator.secureResponse(request, response, callback, authMandatory, userAuth); - return processed; - } + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!authorized"); + return true; } - if (authentication instanceof DeferredAuthentication deferred) - { - org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); + if (authentication == null) + authentication = _deferredAuthentication; - boolean handled; - try - { - //process the request by other handlers - handled = next.handle(request, response, callback); + Authentication.setAuthentication(request, authentication); + IdentityService.Association association = authentication instanceof Authentication.User user + ? _identityService.associate(user.getUserIdentity()) + : null; - if (handled && authenticator != null) - { - Authentication auth = org.eclipse.jetty.security.Authentication.getAuthentication(request); - if (auth instanceof Authentication.User userAuth) - authenticator.secureResponse(request, response, callback, authMandatory, userAuth); - else - authenticator.secureResponse(request, response, callback, authMandatory, null); - } - return handled; - } - finally - { - IdentityService.Association association = deferred.getAssociation(); - if (association != null) - association.close(); - } + try + { + //process the request by other handlers + return next.handle(_authenticator.prepareRequest(request), response, callback); } - - if (authMandatory) + finally { - Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401, "unauthenticated"); - return true; + if (association == null && authentication instanceof DeferredAuthentication deferred) + association = deferred.getAssociation(); + if (association != null) + association.close(); } - - org.eclipse.jetty.security.Authentication.setAuthentication(request, authentication); - - //process the request by other handlers - boolean handled = next.handle(request, response, callback); - - if (handled && authenticator != null) - authenticator.secureResponse(request, response, callback, authMandatory, null); - return handled; } catch (ServerAuthException e) { - // jaspi 3.8.3 send HTTP 500 internal server error, with message from AuthException Response.writeError(request, response, callback, HttpStatus.INTERNAL_SERVER_ERROR_500, e.getMessage()); return true; } @@ -557,11 +512,8 @@ public void logout(Authentication.User user) protected abstract Constraint getConstraint(String pathInContext, Request request); - protected boolean checkTransport(String pathInContext, Request request, Response response, Callback callback, Constraint constraint) throws IOException + protected void redirectToSecure(Request request, Response response, Callback callback) { - if (request.isSecure() || !constraint.isConfidential()) - return true; - HttpConfiguration httpConfig = request.getConnectionMetaData().getHttpConfiguration(); if (httpConfig.getSecurePort() > 0) { @@ -578,37 +530,32 @@ protected boolean checkTransport(String pathInContext, Request request, Response { Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!Secure"); } - return false; } - protected boolean checkAuthentication(String pathInContext, Request request, Response response, Constraint constraint, UserIdentity userIdentity) + protected boolean isNotAuthorized(Constraint constraint, Authentication authentication) { - Constraint.Authentication authentication = constraint.getAuthentication(); - if (authentication == null) - return true; + UserIdentity userIdentity = authentication instanceof Authentication.User user ? user.getUserIdentity() : null; return switch (constraint.getAuthentication()) { - case REQUIRE_NONE -> true; - - case REQUIRE -> userIdentity.getUserPrincipal() != null; - + case REQUIRE_NONE -> false; + case REQUIRE -> userIdentity == null || userIdentity.getUserPrincipal() == null; case REQUIRE_KNOWN_ROLE -> { - if (userIdentity.getUserPrincipal() != null) + if (userIdentity != null && userIdentity.getUserPrincipal() != null) for (String role : getKnownRoles()) if (userIdentity.isUserInRole(role)) - yield true; - yield false; + yield false; + yield true; } case REQUIRE_SPECIFIC_ROLE -> { - if (userIdentity.getUserPrincipal() != null) + if (userIdentity != null && userIdentity.getUserPrincipal() != null) for (String role : constraint.getRoles()) if (userIdentity.isUserInRole(role)) - yield true; - yield false; + yield false; + yield true; } }; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java index 337c15d3bd19..d519c3f60299 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/BasicAuthenticator.java @@ -49,13 +49,10 @@ public String getAuthMethod() } @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException { String credentials = req.getHeaders().get(HttpHeader.AUTHORIZATION); - if (!mandatory) - return new DeferredAuthentication(this); - if (credentials != null) { int space = credentials.indexOf(' '); @@ -83,8 +80,8 @@ public Authentication validateRequest(Request req, Response res, Callback callba } } - if (DeferredAuthentication.isDeferred(res)) - return Authentication.UNAUTHENTICATED; + if (res.isCommitted()) + return null; String value = "basic realm=\"" + _loginService.getName() + "\""; Charset charset = getCharset(); @@ -92,7 +89,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba value += ", charset=\"" + charset.name() + "\""; res.getHeaders().put(HttpHeader.WWW_AUTHENTICATE.asString(), value); Response.writeError(req, res, callback, HttpStatus.UNAUTHORIZED_401); - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } public static String authorization(String user, String password) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index 5f08a943dcb2..93ed3c3186be 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -108,11 +108,8 @@ public UserIdentity login(String username, Object password, Request request, Res } @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException { - if (!mandatory) - return new DeferredAuthentication(this); - String header = req.getHeaders().get(HttpHeader.AUTHORIZATION); String spnegoToken = getSpnegoToken(header); Session httpSession = req.getSession(false); @@ -145,12 +142,12 @@ public Authentication validateRequest(Request req, Response res, Callback callba else { if (DeferredAuthentication.isDeferred(res)) - return Authentication.UNAUTHENTICATED; + return null; if (LOG.isDebugEnabled()) LOG.debug("Sending intermediate challenge"); SpnegoUserPrincipal principal = (SpnegoUserPrincipal)identity.getUserPrincipal(); sendChallenge(req, res, callback, principal.getEncodedToken()); - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } } // No token from the client; check if the client has logged in @@ -177,12 +174,12 @@ else if (httpSession != null) } if (DeferredAuthentication.isDeferred(res)) - return Authentication.UNAUTHENTICATED; + return null; if (LOG.isDebugEnabled()) LOG.debug("Sending initial challenge"); sendChallenge(req, res, callback, null); - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } private void sendChallenge(Request req, Response res, Callback callback, String token) throws ServerAuthException diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 464fe4bffd5d..38e2624a9762 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -21,9 +21,7 @@ import org.eclipse.jetty.http.HttpFields.Mutable; import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.IdentityService; -import org.eclipse.jetty.security.LoggedOutAuthentication; import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -33,7 +31,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class DeferredAuthentication implements Authentication.Deferred +public class DeferredAuthentication implements Authentication { private static final Logger LOG = LoggerFactory.getLogger(DeferredAuthentication.class); protected final LoginAuthenticator _authenticator; @@ -46,21 +44,20 @@ public DeferredAuthentication(LoginAuthenticator authenticator) this._authenticator = authenticator; } - @Override - public Authentication authenticate(Request request) + public Authentication.User authenticate(Request request) { try { - Authentication authentication = _authenticator.validateRequest(request, __deferredResponse, null, true); - if (authentication != null && (authentication instanceof Authentication.User) && !(authentication instanceof Authentication.ResponseSent)) + Authentication authentication = _authenticator.validateRequest(request, __deferredResponse, null); + if (authentication instanceof Authentication.User user) { LoginService loginService = _authenticator.getLoginService(); IdentityService identityService = loginService.getIdentityService(); if (identityService != null) - _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + _association = identityService.associate(user.getUserIdentity()); - return authentication; + return user; } } catch (ServerAuthException e) @@ -68,10 +65,9 @@ public Authentication authenticate(Request request) LOG.debug("Unable to authenticate {}", request, e); } - return this; + return null; } - @Override public Authentication authenticate(Request request, Response response, Callback callback) { try @@ -79,7 +75,7 @@ public Authentication authenticate(Request request, Response response, Callback LoginService loginService = _authenticator.getLoginService(); IdentityService identityService = loginService.getIdentityService(); - Authentication authentication = _authenticator.validateRequest(request, response, callback, true); + Authentication authentication = _authenticator.validateRequest(request, response, callback); if (authentication instanceof Authentication.User && identityService != null) _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); return authentication; @@ -88,11 +84,10 @@ public Authentication authenticate(Request request, Response response, Callback { LOG.debug("Unable to authenticate {}", request, e); } - return this; + return null; } - @Override - public Authentication login(String username, Object password, Request request, Response response) + public Authentication.User login(String username, Object password, Request request, Response response) { if (username == null) return null; @@ -109,20 +104,6 @@ public Authentication login(String username, Object password, Request request, R return null; } - @Override - public Authentication logout(Request request) - { - SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); - if (security != null) - { - security.logout(null); - _authenticator.logout(request); - return new LoggedOutAuthentication(_authenticator); - } - - return Authentication.UNAUTHENTICATED; - } - public IdentityService.Association getAssociation() { return _association; @@ -182,7 +163,7 @@ public void write(boolean last, ByteBuffer content, Callback callback) @Override public boolean isCommitted() { - return false; + return true; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java index 0faeeedb2002..687e3fd61f1d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DigestAuthenticator.java @@ -97,11 +97,8 @@ public String getAuthMethod() } @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException { - if (!mandatory) - return new DeferredAuthentication(this); - String credentials = req.getHeaders().get(HttpHeader.AUTHORIZATION); boolean stale = false; @@ -184,10 +181,10 @@ else if (n == 0) ", stale=" + stale); Response.writeError(req, res, callback, HttpStatus.UNAUTHORIZED_401); - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } - return Authentication.UNAUTHENTICATED; + return null; } @Override diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index d6632e9cd469..659ef0a6d9c0 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -23,6 +23,7 @@ import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.Constraint; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -211,6 +212,7 @@ public Request prepareRequest(Request request) if (LOG.isDebugEnabled()) LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); + // TODO do this same as resetting the method Fields fields = (Fields)session.removeAttribute(__J_POST); if (fields != null) request.setAttribute(FormFields.class.getName(), fields); @@ -246,16 +248,20 @@ protected String encodeURL(String url) } @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) + { + if (isJSecurityCheck(pathInContext)) + return Constraint.Authentication.REQUIRE; + if (isLoginOrErrorPage(pathInContext)) + return Constraint.Authentication.REQUIRE_NONE; + return existing; + } + + @Override + public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException { String pathInContext = Request.getPathInContext(req); boolean jSecurityCheck = isJSecurityCheck(pathInContext); - mandatory |= jSecurityCheck; - if (!mandatory) - return new DeferredAuthentication(this); - - if (isLoginOrErrorPage(pathInContext) && !DeferredAuthentication.isDeferred(res)) - return new DeferredAuthentication(this); // Handle a request for authentication. if (jSecurityCheck) @@ -358,7 +364,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba if (DeferredAuthentication.isDeferred(res)) { LOG.debug("auth deferred {}", session == null ? null : session.getId()); - return Authentication.UNAUTHENTICATED; + return null; } // remember the current URI @@ -389,7 +395,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba // send the the challenge LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } public boolean isJSecurityCheck(String uri) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java index 2074fb883573..28cbd4906b45 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/SslClientCertAuthenticator.java @@ -55,11 +55,8 @@ public String getAuthMethod() } @Override - public Authentication validateRequest(Request req, Response res, Callback callback, boolean mandatory) throws ServerAuthException + public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException { - if (!mandatory) - return new DeferredAuthentication(this); - SslSessionData sslSessionData = (SslSessionData)req.getAttribute(SecureRequestCustomizer.DEFAULT_SSL_SESSION_DATA_ATTRIBUTE); if (sslSessionData == null) { @@ -117,7 +114,7 @@ public Authentication validateRequest(Request req, Response res, Callback callba return Authentication.SEND_FAILURE; } - return Authentication.UNAUTHENTICATED; + return null; } catch (Exception e) { diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java new file mode 100644 index 000000000000..5aa327975329 --- /dev/null +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java @@ -0,0 +1,158 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.internal.DefaultUserIdentity; +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Fields; + +public class AuthenticationTestHandler extends Handler.Abstract +{ + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + Fields parameters = Request.extractQueryParameters(request); + List actions = parameters.getValues("action"); + Deque usernames = new LinkedList<>(parameters.getValuesOrEmpty("username")); + Deque passwords = new LinkedList<>(parameters.getValuesOrEmpty("password")); + + StringBuilder out = new StringBuilder(); + if (actions != null) + { + for (String action : actions) + { + switch (action) + { + case "authenticate" -> + { + Authentication.User user = Authentication.authenticate(request); + out.append(user == null ? "-" : user.getUserIdentity().getUserPrincipal()); + } + + case "challenge" -> + { + Authentication.User user = Authentication.authenticate(request, response, callback); + if (user == null) + return true; + out.append(user.getUserIdentity().getUserPrincipal()); + } + + case "login" -> + { + Authentication.User user = Authentication.login(usernames.pop(), passwords.pop(), request, response); + out.append(user == null ? "-" : user.getUserIdentity().getUserPrincipal()); + } + + case "logout" -> out.append(Authentication.logout(request)); + + case "thread" -> out.append(TestIdentityService.USER_IDENTITY.get()); + + default -> out.append("???"); + } + + out.append(','); + } + } + + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication user) + out.append(user.getUserIdentity().getUserPrincipal()).append(" is OK"); + else if (authentication instanceof DeferredAuthentication) + out.append("Deferred"); + else if (authentication == null) + out.append("Who are you?"); + else + out.append(authentication).append(" is not OK"); + + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/plain"); + Content.Sink.write(response, true, out.toString(), callback); + return true; + } + + public static class TestIdentityService extends DefaultIdentityService + { + public static final ThreadLocal USER_IDENTITY = new ThreadLocal<>(); + + @Override + public Association associate(UserIdentity user) + { + USER_IDENTITY.set(user == null ? null : user.getUserPrincipal().getName()); + return () -> USER_IDENTITY.set(null); + } + + @Override + public void logout(UserIdentity user) + { + USER_IDENTITY.set(null); + } + } + + static class CustomLoginService implements LoginService + { + private final IdentityService identityService; + + public CustomLoginService(IdentityService identityService) + { + this.identityService = identityService; + } + + @Override + public String getName() + { + return "name"; + } + + @Override + public UserIdentity login(String username, Object credentials, Request request) + { + if ("admin".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); + if ("user".equals(username) && "password".equals(credentials)) + return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); + return null; + } + + @Override + public boolean validate(UserIdentity user) + { + return false; + } + + @Override + public IdentityService getIdentityService() + { + return identityService; + } + + @Override + public void setIdentityService(IdentityService service) + { + } + + @Override + public void logout(UserIdentity user) + { + } + } +} diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java index cd11c6ad9f6a..2a818d45eca7 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/BasicAuthenticatorTest.java @@ -13,29 +13,29 @@ package org.eclipse.jetty.security; +import java.util.Arrays; + import org.eclipse.jetty.http.HttpScheme; +import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.io.Content; import org.eclipse.jetty.security.authentication.BasicAuthenticator; -import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.ForwardedRequestCustomizer; -import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.session.SimpleSessionHandler; -import org.eclipse.jetty.util.Callback; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; public class BasicAuthenticatorTest @@ -51,7 +51,7 @@ public void configureServer() throws Exception { _server = new Server(); - _server.addBean(new CustomLoginService(new DefaultIdentityService())); + _server.addBean(new AuthenticationTestHandler.CustomLoginService(new AuthenticationTestHandler.TestIdentityService())); HttpConnectionFactory http = new HttpConnectionFactory(); HttpConfiguration httpConfiguration = http.getHttpConfiguration(); @@ -94,12 +94,12 @@ public boolean isSecure() _securityHandler = new SecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); - _securityHandler.setHandler(new OkHandler()); - _securityHandler.put("/admin/*", Constraint.from("admin")); _securityHandler.put("/any/*", Constraint.AUTHENTICATED); _securityHandler.put("/known/*", Constraint.AUTHENTICATED_KNOWN_ROLE); _securityHandler.setAuthenticator(new BasicAuthenticator()); + + _securityHandler.setHandler(new AuthenticationTestHandler()); _server.start(); } @@ -119,15 +119,20 @@ public void testBasic() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Deferred")); + + response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("wrong", "user"))); + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("Deferred")); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("wrong", "user"))); assertThat(response, containsString("HTTP/1.1 401 Unauthorized")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); assertThat(response, containsString("HTTP/1.1 200 OK")); @@ -139,7 +144,7 @@ public void testBasic() throws Exception response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); + assertThat(response, containsString("!authorized")); assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("admin", "password"))); @@ -148,73 +153,122 @@ public void testBasic() throws Exception response = _connector.getResponse("GET /ctx/known/user HTTP/1.0\r\nAuthorization: %s\r\n\r\n".formatted(BasicAuthenticator.authorization("user", "password"))); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); + assertThat(response, containsString("!authorized")); assertThat(response, not(containsString("OK"))); } - public static class OkHandler extends Handler.Abstract + @Test + public void testDeferredAuthenticate() throws Exception { - @Override - public boolean handle(Request request, Response response, Callback callback) throws Exception - { - Authentication authentication = Authentication.getAuthentication(request); - if (authentication instanceof UserAuthentication user) - Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); - else if (authentication instanceof Authentication.Deferred) - Content.Sink.write(response, true, "Somebody might be OK", callback); - else if (authentication == null) - Content.Sink.write(response, true, "You are OK", callback); - else - Content.Sink.write(response, true, authentication + " is not OK", callback); - return true; - } + HttpTester.Response response; + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=authenticate HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("-", "Deferred")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=authenticate HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "wrong")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("-", "Deferred")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=authenticate HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "user is OK")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/any/user?action=logout&action=authenticate HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("true", "-", "Deferred")); } - private static class CustomLoginService implements LoginService + @Test + public void testDeferredAuthenticateOrChallenge() throws Exception { - private final IdentityService identityService; - - public CustomLoginService(IdentityService identityService) - { - this.identityService = identityService; - } - - @Override - public String getName() - { - return "name"; - } - - @Override - public UserIdentity login(String username, Object credentials, Request request) - { - if ("admin".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); - if ("user".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - return false; - } - - @Override - public IdentityService getIdentityService() - { - return identityService; - } + HttpTester.Response response; + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=challenge HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(401)); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=challenge HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "wrong")))); + assertThat(response.getStatus(), equalTo(401)); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=challenge HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "user is OK")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/any/user?action=logout&action=challenge HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(403)); + } - @Override - public void setIdentityService(IdentityService service) - { - } + @Test + public void testLogin() throws Exception + { + HttpTester.Response response; + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=login&username=user&password=wrong HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("-", "Deferred")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=login&username=user&password=password HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "user is OK")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=login&username=user&password=password&action=logout&action=login&username=admin&password=password HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "true", "admin", "admin is OK")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/any/user?action=login&username=admin&password=password HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(500)); + } - @Override - public void logout(UserIdentity user) - { - } + @Test + public void testIdentity() throws Exception + { + HttpTester.Response response; + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/some/thing?action=thread HTTP/1.0\r\n\r\n")); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("null", "Deferred")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/any/user?action=thread HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "user is OK")); + + response = HttpTester.parseResponse(_connector.getResponse( + "GET /ctx/any/user?action=thread&action=logout&action=thread HTTP/1.0\r\nAuthorization: %s\r\n\r\n" + .formatted(BasicAuthenticator.authorization("user", "password")))); + assertThat(response.getStatus(), equalTo(200)); + assertThat(Arrays.stream(response.getContent().split(",")).toList(), + contains("user", "true", "null", "Deferred")); } } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java index 86811af49e7f..cb11a2ba3613 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/DefaultIdentityServiceTest.java @@ -69,15 +69,9 @@ public String getAuthMethod() } @Override - public Authentication validateRequest(Request request, Response response, Callback callback, boolean mandatory) throws ServerAuthException + public Authentication validateRequest(Request request, Response response, Callback callback) throws ServerAuthException { return null; } - - @Override - public boolean secureResponse(Request request, Response response, Callback callback, boolean mandatory, Authentication.User validatedUser) throws ServerAuthException - { - return false; - } } } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index bb64f276ff85..c72dadf9a0cf 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -16,6 +16,7 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.security.authentication.FormAuthenticator; import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; @@ -333,7 +334,7 @@ public boolean handle(Request request, Response response, Callback callback) thr Authentication authentication = Authentication.getAuthentication(request); if (authentication instanceof Authentication.User user) Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); - else if (authentication instanceof Authentication.Deferred) + else if (authentication instanceof DeferredAuthentication) Content.Sink.write(response, true, "Somebody might be OK", callback); else if (authentication == null) Content.Sink.write(response, true, "You are OK", callback); diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 8f8898ccee51..8467b71f1570 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -16,6 +16,7 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.ForwardedRequestCustomizer; import org.eclipse.jetty.server.Handler; @@ -180,7 +181,7 @@ public boolean handle(Request request, Response response, Callback callback) thr Authentication authentication = Authentication.getAuthentication(request); if (authentication instanceof UserAuthentication user) Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); - else if (authentication instanceof Authentication.Deferred) + else if (authentication instanceof DeferredAuthentication) Content.Sink.write(response, true, "Somebody might be OK", callback); else if (authentication == null) Content.Sink.write(response, true, "You are OK", callback); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java index b045fe7820e7..6212fb21e2f7 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java @@ -147,6 +147,18 @@ public List getValues(String name) return field.getValues(); } + /** + * @param name the field name + * @return the values of the field with the given name, or empty list if no such field exists + */ + public List getValuesOrEmpty(String name) + { + Field field = get(name); + if (field == null) + return Collections.emptyList(); + return field.getValues(); + } + /** *

    Inserts or replaces the given name/value pair as a single-valued {@link Field}.

    * From adb84c47434a2e26530b1d4d4c23421befbbf121 Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 13 Mar 2023 22:46:56 +0100 Subject: [PATCH 022/129] WIP on major simplification --- .../eclipse/jetty/security/Authenticator.java | 29 ++- .../jetty/security/SecurityHandler.java | 5 +- .../authentication/FormAuthenticator.java | 185 +++++++----------- .../security/AuthenticationTestHandler.java | 20 +- .../jetty/security/FormAuthenticatorTest.java | 109 ++--------- .../jetty/security/SecurityHandlerTest.java | 47 ++--- 6 files changed, 137 insertions(+), 258 deletions(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 93ae930d4a31..93e27f73e492 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -56,15 +56,14 @@ public interface Authenticator String getAuthMethod(); /** - * Called prior to validateRequest. The authenticator can - * manipulate the request to update it with information that - * can be inspected prior to validateRequest being called. + * Called after to validateRequest. * This may be restore method or content from a previous request * that was challenged. * - * @param request the request to prepare for authentication + * @param request the request to prepare for handling + * @param authentication The authentication for the request */ - default Request prepareRequest(Request request) + default Request prepareRequest(Request request, Authentication authentication) { return request; } @@ -187,4 +186,24 @@ interface Factory { Authenticator getAuthenticator(Server server, Context context, AuthConfiguration configuration); } + + class Null implements Authenticator + { + @Override + public void setConfiguration(AuthConfiguration configuration) + { + } + + @Override + public String getAuthMethod() + { + return null; + } + + @Override + public Authentication validateRequest(Request request, Response response, Callback callback) throws ServerAuthException + { + return null; + } + } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index c2baa852e9ca..2277ff6b0bd8 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -356,6 +356,9 @@ else if (_loginService.getIdentityService() != _identityService) } } + if (_authenticator == null) + setAuthenticator(new Authenticator.Null()); + if (_authenticator != null) _authenticator.setConfiguration(this); else if (_realmName != null) @@ -469,7 +472,7 @@ public boolean handle(Request request, Response response, Callback callback) thr try { //process the request by other handlers - return next.handle(_authenticator.prepareRequest(request), response, callback); + return next.handle(_authenticator.prepareRequest(request, authentication), response, callback); } finally { diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 659ef0a6d9c0..eb73f111ae8a 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -15,11 +15,9 @@ import java.util.concurrent.ExecutionException; -import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.security.Authenticator; @@ -33,7 +31,6 @@ import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Fields; -import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -185,46 +182,43 @@ public void logout(Request request) } @Override - public Request prepareRequest(Request request) + public Request prepareRequest(Request request, Authentication authentication) { // if this is a request resulting from a redirect after auth is complete // (ie its from a redirect to the original request uri) then due to // browser handling of 302 redirects, the method may not be the same as // that of the original request. Replace the method and original post // params (if it was a post). + if (authentication instanceof Authentication.User user) + { + Session session = request.getSession(false); - Session session = request.getSession(false); - if (session == null) - return request; // couldn't be authenticated yet - - String method = (String)session.getAttribute(__J_METHOD); - if (method == null) - return request; // No method so no wrapping required - - if (session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) - return request; // not authenticated yet - - HttpURI juri = (HttpURI)session.getAttribute(__J_URI); - if (juri == null || !juri.equals(request.getHttpURI())) - return request; //no original uri saved or this is not a request for it - - //restore the original request's method on this request - if (LOG.isDebugEnabled()) - LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); + HttpURI juri = (HttpURI)session.getAttribute(__J_URI); + HttpURI uri = request.getHttpURI(); + if ((uri.equals(juri))) + { + session.removeAttribute(__J_URI); - // TODO do this same as resetting the method - Fields fields = (Fields)session.removeAttribute(__J_POST); - if (fields != null) - request.setAttribute(FormFields.class.getName(), fields); + Fields fields = (Fields)session.removeAttribute(__J_POST); + if (fields != null) + request.setAttribute(FormFields.class.getName(), fields); - return new Request.Wrapper(request) - { - @Override - public String getMethod() - { - return method; + String method = (String)session.removeAttribute(__J_METHOD); + if (method != null && request.getMethod().equals(method)) + { + return new Request.Wrapper(request) + { + @Override + public String getMethod() + { + return method; + } + }; + } } - }; + } + + return request; } protected Fields getParameters(Request request) @@ -258,133 +252,89 @@ public Constraint.Authentication getConstraintAuthentication(String pathInContex } @Override - public Authentication validateRequest(Request req, Response res, Callback callback) throws ServerAuthException + public Authentication validateRequest(Request request, Response response, Callback callback) throws ServerAuthException { - String pathInContext = Request.getPathInContext(req); + String pathInContext = Request.getPathInContext(request); boolean jSecurityCheck = isJSecurityCheck(pathInContext); // Handle a request for authentication. if (jSecurityCheck) { - Fields parameters = getParameters(req); + Fields parameters = getParameters(request); final String username = parameters.getValue(__J_USERNAME); final String password = parameters.getValue(__J_PASSWORD); - UserIdentity user = login(username, password, req, res); + UserIdentity user = login(username, password, request, response); LOG.debug("jsecuritycheck {} {}", username, user); - Session session = req.getSession(false); if (user != null) { // Redirect to original request - String nuri; - FormAuthentication formAuth; - synchronized (session) - { - HttpURI savedURI = (HttpURI)session.getAttribute(__J_URI); - if (savedURI == null) - { - nuri = Request.getContextPath(req); - if (nuri.length() == 0) - nuri = "/"; - } - else - nuri = savedURI.asString(); - formAuth = new FormAuthentication(getAuthMethod(), user); - } - LOG.debug("authenticated {}->{}", formAuth, nuri); - - res.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); - //TODO yuck - should use Response the whole way - Response.sendRedirect(req, res, callback, encodeURL(nuri)); + Session session = request.getSession(false); + HttpURI savedURI = (HttpURI)session.getAttribute(__J_URI); + String originalURI = savedURI != null ? savedURI.asString() : Request.getContextPath(request); + if (originalURI == null) + originalURI = "/"; + FormAuthentication formAuth = new FormAuthentication(getAuthMethod(), user); + Response.sendRedirect(request, response, callback, encodeURL(originalURI)); return formAuth; } // not authenticated - if (LOG.isDebugEnabled()) - LOG.debug("Form authentication FAILED for {}", StringUtil.printable(username)); if (_formErrorPage == null) - { - LOG.debug("auth failed {}->403", username); - Response.writeError(req, res, callback, HttpStatus.FORBIDDEN_403); - } + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); else - { - LOG.debug("auth failed {}->{}", username, _formErrorPage); - Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formErrorPage))); - } + Response.sendRedirect(request, response, callback, encodeURL(URIUtil.addPaths(request.getContext().getContextPath(), _formErrorPage))); return Authentication.SEND_FAILURE; } // Look for cached authentication - Session session = req.getSession(false); + Session session = request.getSession(false); Authentication authentication = session == null ? null : (Authentication)session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); - if (authentication != null) + if (LOG.isDebugEnabled()) + LOG.debug("auth {}", authentication); + // Has authentication been revoked? + if (authentication instanceof User user && _loginService != null && !_loginService.validate(user.getUserIdentity())) { - // Has authentication been revoked? - if (authentication instanceof User && - _loginService != null && - !_loginService.validate(((User)authentication).getUserIdentity())) - { + if (LOG.isDebugEnabled()) LOG.debug("auth revoked {}", authentication); - session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); - } - else - { - synchronized (session) - { - HttpURI jUri = (HttpURI)session.getAttribute(__J_URI); - if (jUri != null) - { - //check if the request is for the same url as the original and restore - //params if it was a post - LOG.debug("auth retry {}->{}", authentication, jUri); - - if (jUri.equals(req.getHttpURI())) - { - Fields jPost = (Fields)session.getAttribute(__J_POST); - if (jPost != null) - { - // TODO: how to do this - // TODO Should this be done here or is it in prepare request? - LOG.debug("auth rePOST {}->{}", authentication, jUri); - } - } - session.removeAttribute(__J_URI); - session.removeAttribute(__J_METHOD); - session.removeAttribute(__J_POST); - } - } - LOG.debug("auth {}", authentication); - return authentication; - } + session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); + authentication = null; } + if (authentication != null) + return authentication; + // if we can't send challenge - if (DeferredAuthentication.isDeferred(res)) + if (response.isCommitted()) { LOG.debug("auth deferred {}", session == null ? null : session.getId()); return null; } // remember the current URI - session = (session != null ? session : req.getSession(true)); + session = (session != null ? session : request.getSession(true)); synchronized (session) { // But only if it is not set already, or we save every uri that leads to a login form redirect if (session.getAttribute(__J_URI) == null || _alwaysSaveUri) { - session.setAttribute(__J_URI, req.getHttpURI()); - if (!req.getMethod().equals(HttpMethod.GET.asString())) - session.setAttribute(__J_METHOD, req.getMethod()); + HttpURI juri = request.getHttpURI(); + session.setAttribute(__J_URI, juri); + if (!HttpMethod.GET.is(request.getMethod())) + session.setAttribute(__J_METHOD, request.getMethod()); - if (HttpMethod.POST.is(req.getMethod()) && MimeTypes.Type.FORM_ENCODED.is(req.getHeaders().get(HttpHeader.CONTENT_TYPE))) + if (HttpMethod.POST.is(request.getMethod())) { try { - session.setAttribute(__J_POST, FormFields.from(req).get()); + session.setAttribute(__J_POST, FormFields.from(request).get()); } - catch (InterruptedException | ExecutionException e) + catch (ExecutionException e) + { + throw new ServerAuthException(e.getCause()); + } + catch (InterruptedException e) { throw new ServerAuthException(e); } @@ -392,9 +342,10 @@ public Authentication validateRequest(Request req, Response res, Callback callba } } - // send the the challenge - LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); - Response.sendRedirect(req, res, callback, encodeURL(URIUtil.addPaths(req.getContext().getContextPath(), _formLoginPage))); + // send the challenge + if (LOG.isDebugEnabled()) + LOG.debug("challenge {}->{}", session.getId(), _formLoginPage); + Response.sendRedirect(request, response, callback, encodeURL(URIUtil.addPaths(request.getContext().getContextPath(), _formLoginPage))); return Authentication.CHALLENGE; } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java index 5aa327975329..0875e733fa85 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java @@ -21,6 +21,7 @@ import org.eclipse.jetty.io.Content; import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.security.internal.DefaultUserIdentity; +import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; @@ -68,6 +69,19 @@ public boolean handle(Request request, Response response, Callback callback) thr case "thread" -> out.append(TestIdentityService.USER_IDENTITY.get()); + case "session" -> out.append(request.getSession(true).getId()); + + case "form" -> + { + Fields fields = FormFields.from(request).get(); + String d = ""; + for (Fields.Field field : fields) + { + out.append(d).append(field.getName()).append(":").append(field.getValue()); + d = ","; + } + } + default -> out.append("???"); } @@ -76,12 +90,12 @@ public boolean handle(Request request, Response response, Callback callback) thr } Authentication authentication = Authentication.getAuthentication(request); - if (authentication instanceof UserAuthentication user) + if (authentication instanceof Authentication.User user) out.append(user.getUserIdentity().getUserPrincipal()).append(" is OK"); else if (authentication instanceof DeferredAuthentication) out.append("Deferred"); else if (authentication == null) - out.append("Who are you?"); + out.append("Unauthenticated"); else out.append(authentication).append(" is not OK"); @@ -136,7 +150,7 @@ public UserIdentity login(String username, Object credentials, Request request) @Override public boolean validate(UserIdentity user) { - return false; + return true; } @Override diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java index c72dadf9a0cf..3ef81a5d4800 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/FormAuthenticatorTest.java @@ -15,24 +15,16 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.io.Content; -import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.security.authentication.FormAuthenticator; -import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; -import org.eclipse.jetty.server.FormFields; import org.eclipse.jetty.server.ForwardedRequestCustomizer; -import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.session.SimpleSessionHandler; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.Fields; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -56,7 +48,7 @@ public void configureServer() throws Exception { _server = new Server(); - _server.addBean(new CustomLoginService(new DefaultIdentityService())); + _server.addBean(new AuthenticationTestHandler.CustomLoginService(new AuthenticationTestHandler.TestIdentityService())); HttpConnectionFactory http = new HttpConnectionFactory(); HttpConfiguration httpConfiguration = http.getHttpConfiguration(); @@ -99,7 +91,7 @@ public boolean isSecure() _securityHandler = new SecurityHandler.Mapped(); _sessionHandler.setHandler(_securityHandler); - _securityHandler.setHandler(new OkHandler()); + _securityHandler.setHandler(new AuthenticationTestHandler()); _securityHandler.put("/j_security_check", Constraint.AUTHENTICATED); // TODO this should not be needed _securityHandler.put("/any/*", Constraint.AUTHENTICATED); @@ -125,7 +117,7 @@ public void testLoginRedirect() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Deferred")); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 302 Found")); @@ -156,10 +148,10 @@ private static String sessionId(String response) public void testUseExistingSession() throws Exception { String response; - response = _connector.getResponse("GET /ctx/some/thing?createSession=true HTTP/1.0\r\n\r\n"); + response = _connector.getResponse("GET /ctx/some/thing?action=session HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); assertThat(response, containsString("Set-Cookie: JSESSIONID=")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Deferred")); String sessionId = sessionId(response); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); @@ -226,7 +218,7 @@ public void testLoginQuery() throws Exception response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); + assertThat(response, containsString("!authorized")); assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + unsafeSessionId + "\r\n\r\n"); @@ -270,7 +262,7 @@ public void testLoginForm() throws Exception response = _connector.getResponse("GET /ctx/admin/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, containsString("!role")); + assertThat(response, containsString("!authorized")); assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + unsafeSessionId + "\r\n\r\n"); @@ -286,7 +278,7 @@ public void testRedirectToPost() throws Exception String sessionId = "unknown"; response = _connector.getResponse(""" - POST /ctx/any/user HTTP/1.0\r + POST /ctx/any/user?action=form HTTP/1.0\r Host: host:8888\r Content-Length: 25\r Content-Type: application/x-www-form-urlencoded\r @@ -301,95 +293,18 @@ public void testRedirectToPost() throws Exception response = _connector.getResponse("GET /ctx/j_security_check?j_username=user&j_password=password HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 302 Found")); - assertThat(response, containsString("Location: http://host:8888/ctx/any/user")); + assertThat(response, containsString("Location: http://host:8888/ctx/any/user?action=form")); assertThat(response, containsString("Set-Cookie: JSESSIONID=")); String unsafeSessionId = sessionId; sessionId = sessionId(response); assertThat(sessionId, not(equalTo(unsafeSessionId))); - response = _connector.getResponse("GET /ctx/any/user HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); + response = _connector.getResponse("GET /ctx/any/user?action=form HTTP/1.0\r\nHost:host:8888\r\nCookie: JSESSIONID=" + sessionId + "\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); assertThat(response, not(containsString("Set-Cookie: JSESSIONID="))); - assertThat(response, containsString("name1: value1\r\n")); - assertThat(response, containsString("name2: value2\r\n")); + assertThat(response, containsString("name1:value1,")); + assertThat(response, containsString("name2:value2,")); assertThat(response, containsString("user is OK")); } - - public static class OkHandler extends Handler.Abstract - { - @Override - public boolean handle(Request request, Response response, Callback callback) throws Exception - { - if (Boolean.parseBoolean(Request.extractQueryParameters(request).getValue("createSession"))) - request.getSession(true); - - if (request.getMethod().equals("POST")) - { - Fields form = FormFields.from(request).get(); - for (Fields.Field field : form) - response.getHeaders().put(field.getName(), field.getValue()); - } - - Authentication authentication = Authentication.getAuthentication(request); - if (authentication instanceof Authentication.User user) - Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); - else if (authentication instanceof DeferredAuthentication) - Content.Sink.write(response, true, "Somebody might be OK", callback); - else if (authentication == null) - Content.Sink.write(response, true, "You are OK", callback); - else - Content.Sink.write(response, true, authentication + " is not OK", callback); - return true; - } - } - - private static class CustomLoginService implements LoginService - { - private final IdentityService identityService; - - public CustomLoginService(IdentityService identityService) - { - this.identityService = identityService; - } - - @Override - public String getName() - { - return "name"; - } - - @Override - public UserIdentity login(String username, Object credentials, Request request) - { - if ("admin".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); - if ("user".equals(username) && "password".equals(credentials)) - return new DefaultUserIdentity(null, new UserPrincipal("user", null), new String[]{"user"}); - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - return user instanceof DefaultUserIdentity; - } - - @Override - public IdentityService getIdentityService() - { - return identityService; - } - - @Override - public void setIdentityService(IdentityService service) - { - throw new UnsupportedOperationException(); - } - - @Override - public void logout(UserIdentity user) - { - } - } } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java index 8467b71f1570..3bae71dfce04 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/SecurityHandlerTest.java @@ -15,19 +15,14 @@ import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; -import org.eclipse.jetty.io.Content; -import org.eclipse.jetty.security.authentication.DeferredAuthentication; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.ForwardedRequestCustomizer; -import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.Callback; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -83,7 +78,7 @@ public boolean isSecure() _server.setHandler(contextHandler); _securityHandler = new SecurityHandler.Mapped(); contextHandler.setHandler(_securityHandler); - _securityHandler.setHandler(new OkHandler()); + _securityHandler.setHandler(new AuthenticationTestHandler()); _server.start(); } @@ -103,7 +98,7 @@ public void testNoConstraints() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Unauthenticated")); } @Test @@ -114,11 +109,11 @@ public void testForbidden() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Unauthenticated")); response = _connector.getResponse("GET /ctx/secret/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); } @Test @@ -129,17 +124,17 @@ public void testUserData() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("You are OK")); + assertThat(response, containsString("Unauthenticated")); response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 302 Found")); assertThat(response, containsString("Location: BWTP://")); assertThat(response, containsString(":9999")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("UNAUTHENTICATED is not OK")); + assertThat(response, containsString("Unauthenticated")); } @Test @@ -152,42 +147,24 @@ public void testCombinedForbiddenConfidential() throws Exception String response; response = _connector.getResponse("GET /ctx/some/thing HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("UNAUTHENTICATED is not OK")); + assertThat(response, containsString("Unauthenticated")); response = _connector.getResponse("GET /ctx/something.hidden HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); response = _connector.getResponse("GET /ctx/confidential/info HTTP/1.0\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 302 Found")); assertThat(response, containsString("Location: BWTP://")); assertThat(response, containsString(":9999")); - assertThat(response, not(containsString("You are OK"))); + assertThat(response, not(containsString("OK"))); response = _connectorS.getResponse("GET /ctx/confidential/info HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 200 OK")); - assertThat(response, containsString("UNAUTHENTICATED is not OK")); + assertThat(response, containsString("Unauthenticated")); response = _connectorS.getResponse("GET /ctx/confidential/info.hidden HTTP/1.0\r\nForwarded: proto=https\r\n\r\n"); assertThat(response, containsString("HTTP/1.1 403 Forbidden")); - assertThat(response, not(containsString("You are OK"))); - } - - public static class OkHandler extends Handler.Abstract - { - @Override - public boolean handle(Request request, Response response, Callback callback) throws Exception - { - Authentication authentication = Authentication.getAuthentication(request); - if (authentication instanceof UserAuthentication user) - Content.Sink.write(response, true, user.getUserIdentity().getUserPrincipal() + " is OK", callback); - else if (authentication instanceof DeferredAuthentication) - Content.Sink.write(response, true, "Somebody might be OK", callback); - else if (authentication == null) - Content.Sink.write(response, true, "You are OK", callback); - else - Content.Sink.write(response, true, authentication + " is not OK", callback); - return true; - } + assertThat(response, not(containsString("OK"))); } } From 7a3a2e040dc6fa654c191d76c43e72f8df7c304a Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 30 Mar 2023 13:41:42 +0900 Subject: [PATCH 023/129] Create OpenID module in jetty-core Signed-off-by: Lachlan Roberts --- jetty-core/jetty-openid/pom.xml | 73 ++ .../src/main/config/etc/jetty-ee10-openid.xml | 51 ++ .../src/main/config/modules/ee10-openid.mod | 50 ++ .../jetty-ee10-openid-baseloginservice.xml | 10 + .../src/main/java/module-info.java | 28 + .../ee10/security/openid/JwtDecoder.java | 101 +++ .../openid/OpenIdAuthConfiguration.java | 52 ++ .../security/openid/OpenIdAuthenticator.java | 756 ++++++++++++++++++ .../openid/OpenIdAuthenticatorFactory.java | 57 ++ .../security/openid/OpenIdConfiguration.java | 291 +++++++ .../security/openid/OpenIdCredentials.java | 213 +++++ .../security/openid/OpenIdLoginService.java | 167 ++++ .../security/openid/OpenIdUserIdentity.java | 51 ++ .../security/openid/OpenIdUserPrincipal.java | 45 ++ ...e10.servlet.security.Authenticator$Factory | 1 + .../ee10/security/openid/JwtDecoderTest.java | 117 +++ .../ee10/security/openid/JwtEncoder.java | 53 ++ .../openid/OpenIdAuthenticationTest.java | 254 ++++++ .../openid/OpenIdCredentialsTest.java | 40 + .../ee10/security/openid/OpenIdProvider.java | 384 +++++++++ .../security/openid/OpenIdReamNameTest.java | 184 +++++ .../test/resources/jetty-logging.properties | 3 + .../security/WrappedAuthConfiguration.java | 74 ++ jetty-core/pom.xml | 1 + 24 files changed, 3056 insertions(+) create mode 100644 jetty-core/jetty-openid/pom.xml create mode 100644 jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml create mode 100644 jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod create mode 100644 jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml create mode 100644 jetty-core/jetty-openid/src/main/java/module-info.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java create mode 100644 jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java create mode 100644 jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java create mode 100755 jetty-core/jetty-openid/src/test/resources/jetty-logging.properties create mode 100644 jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java diff --git a/jetty-core/jetty-openid/pom.xml b/jetty-core/jetty-openid/pom.xml new file mode 100644 index 000000000000..7b6a431956eb --- /dev/null +++ b/jetty-core/jetty-openid/pom.xml @@ -0,0 +1,73 @@ + + + org.eclipse.jetty + jetty-core + 12.0.0-SNAPSHOT + + + 4.0.0 + jetty-openid + EE10 :: OpenID + Jetty OpenID Connect Infrastructure + + + ${project.groupId}.openid + org.eclipse.jetty.security.openid.* + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + manifest + + + + osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" + osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.security.Authenticator$Factory + + + + + + + + + + + org.eclipse.jetty + jetty-server + + + org.eclipse.jetty + jetty-security + + + org.eclipse.jetty + jetty-client + + + org.eclipse.jetty + jetty-util-ajax + + + org.slf4j + slf4j-api + + + org.eclipse.jetty + jetty-slf4j-impl + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + diff --git a/jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml b/jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml new file mode 100644 index 000000000000..085915563ad7 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod b/jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod new file mode 100644 index 000000000000..d0779b6d3557 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod @@ -0,0 +1,50 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Adds OpenId Connect authentication to the server. + +[environment] +ee10 + +[depend] +ee10-security +client + +[lib] +lib/jetty-util-ajax-${jetty.version}.jar +lib/jetty-ee10-openid-${jetty.version}.jar + +[files] +basehome:modules/openid/jetty-ee10-openid-baseloginservice.xml|etc/jetty-ee10-openid-baseloginservice.xml + +[xml] +etc/jetty-ee10-openid-baseloginservice.xml +etc/jetty-ee10-openid.xml + +[ini-template] +## The OpenID Identity Provider's issuer ID (the entire URL *before* ".well-known/openid-configuration") +# jetty.openid.provider=https://id.example.com/ + +## The OpenID Identity Provider's authorization endpoint (optional if the metadata of the OP is accessible) +# jetty.openid.provider.authorizationEndpoint=https://id.example.com/authorization + +## The OpenID Identity Provider's token endpoint (optional if the metadata of the OP is accessible) +# jetty.openid.provider.tokenEndpoint=https://id.example.com/token + +## The Client Identifier +# jetty.openid.clientId=test1234 + +## The Client Secret +# jetty.openid.clientSecret=XT_Mafv_aUCGheuCaKY8P + +## Additional Scopes to Request +# jetty.openid.scopes=email,profile + +## Whether to Authenticate users not found by base LoginService +# jetty.openid.authenticateNewUsers=false + +## True if all certificates should be trusted by the default SslContextFactory +# jetty.openid.sslContextFactory.trustAll=false + +## What authentication method to use with the Token Endpoint (client_secret_post, client_secret_basic). +# jetty.openid.authMethod=client_secret_post diff --git a/jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml b/jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml new file mode 100644 index 000000000000..ed6e703732f4 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/jetty-core/jetty-openid/src/main/java/module-info.java b/jetty-core/jetty-openid/src/main/java/module-info.java new file mode 100644 index 000000000000..a735a9de65f4 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/module-info.java @@ -0,0 +1,28 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +import org.eclipse.jetty.ee10.security.openid.OpenIdAuthenticatorFactory; +import org.eclipse.jetty.security.Authenticator; + +module org.eclipse.jetty.security.openid +{ + requires org.eclipse.jetty.util.ajax; + + requires transitive org.eclipse.jetty.client; + requires transitive org.eclipse.jetty.security; + requires org.slf4j; + + exports org.eclipse.jetty.ee10.security.openid; + + provides Authenticator.Factory with OpenIdAuthenticatorFactory; +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java new file mode 100644 index 000000000000..0f86bfc60e4e --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java @@ -0,0 +1,101 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.Base64; +import java.util.Map; + +import org.eclipse.jetty.util.ajax.JSON; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Used to decode the ID Token from the base64 encrypted JSON Web Token (JWT). + */ +public class JwtDecoder +{ + private static final Logger LOG = LoggerFactory.getLogger(JwtDecoder.class); + + /** + * Decodes a JSON Web Token (JWT) into a Map of claims. + * + * @param jwt the JWT to decode. + * @return the map of claims encoded in the JWT. + */ + @SuppressWarnings("unchecked") + public static Map decode(String jwt) + { + if (LOG.isDebugEnabled()) + LOG.debug("decode {}", jwt); + + String[] sections = jwt.split("\\."); + if (sections.length != 3) + throw new IllegalArgumentException("JWT does not contain 3 sections"); + + Base64.Decoder decoder = Base64.getUrlDecoder(); + String jwtHeaderString = new String(decoder.decode(padJWTSection(sections[0])), StandardCharsets.UTF_8); + String jwtClaimString = new String(decoder.decode(padJWTSection(sections[1])), StandardCharsets.UTF_8); + String jwtSignature = sections[2]; + + JSON json = new JSON(); + + Object parsedJwtHeader = json.fromJSON(jwtHeaderString); + if (!(parsedJwtHeader instanceof Map)) + throw new IllegalStateException("Invalid JWT header"); + Map jwtHeader = (Map)parsedJwtHeader; + if (LOG.isDebugEnabled()) + LOG.debug("JWT Header: {}", jwtHeader); + + /* If the ID Token is received via direct communication between the Client + and the Token Endpoint (which it is in this flow), the TLS server validation + MAY be used to validate the issuer in place of checking the token signature. */ + if (LOG.isDebugEnabled()) + LOG.debug("JWT signature not validated {}", jwtSignature); + + Object parsedClaims = json.fromJSON(jwtClaimString); + if (!(parsedClaims instanceof Map)) + throw new IllegalStateException("Could not decode JSON for JWT claims."); + return (Map)parsedClaims; + } + + static byte[] padJWTSection(String unpaddedEncodedJwtSection) + { + // If already padded just use what we are given. + if (unpaddedEncodedJwtSection.endsWith("=")) + return unpaddedEncodedJwtSection.getBytes(); + + int length = unpaddedEncodedJwtSection.length(); + int remainder = length % 4; + + // A valid base-64-encoded string will have a remainder of 0, 2 or 3. Never 1! + if (remainder == 1) + throw new IllegalArgumentException("Not a valid Base64-encoded string"); + + byte[] paddedEncodedJwtSection; + if (remainder > 0) + { + int paddingNeeded = (4 - remainder) % 4; + paddedEncodedJwtSection = Arrays.copyOf(unpaddedEncodedJwtSection.getBytes(), length + paddingNeeded); + Arrays.fill(paddedEncodedJwtSection, length, paddedEncodedJwtSection.length, (byte)'='); + } + else + { + paddedEncodedJwtSection = unpaddedEncodedJwtSection.getBytes(); + } + + return paddedEncodedJwtSection; + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java new file mode 100644 index 000000000000..3d8f251b38b3 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java @@ -0,0 +1,52 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.WrappedAuthConfiguration; + +/** + *

    This class is used to wrap the {@link Authenticator.AuthConfiguration} given to the {@link OpenIdAuthenticator}.

    + *

    When {@link #getLoginService()} method is called, this implementation will always return an instance of + * {@link OpenIdLoginService}. This allows you to configure an {@link OpenIdAuthenticator} using a {@code null} + * LoginService or any alternative LoginService implementation which will be wrapped by the OpenIdLoginService

    + */ +public class OpenIdAuthConfiguration extends WrappedAuthConfiguration +{ + private final OpenIdLoginService _openIdLoginService; + + public OpenIdAuthConfiguration(OpenIdConfiguration openIdConfiguration, Authenticator.AuthConfiguration authConfiguration) + { + super(authConfiguration); + + LoginService loginService = authConfiguration.getLoginService(); + if (loginService instanceof OpenIdLoginService) + { + _openIdLoginService = (OpenIdLoginService)loginService; + } + else + { + _openIdLoginService = new OpenIdLoginService(openIdConfiguration, loginService); + if (loginService == null) + _openIdLoginService.setIdentityService(authConfiguration.getIdentityService()); + } + } + + @Override + public LoginService getLoginService() + { + return _openIdLoginService; + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java new file mode 100644 index 000000000000..62b6fa102f88 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java @@ -0,0 +1,756 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.ServerAuthException; +import org.eclipse.jetty.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.security.authentication.SessionAuthentication; +import org.eclipse.jetty.server.FormFields; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Session; +import org.eclipse.jetty.util.Blocker; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Fields; +import org.eclipse.jetty.util.MultiMap; +import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.UrlEncoded; +import org.eclipse.jetty.util.security.Constraint; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

    Implements authentication using OpenId Connect on top of OAuth 2.0. + * + *

    The OpenIdAuthenticator redirects unauthenticated requests to the OpenID Connect Provider. The End-User is + * eventually redirected back with an Authorization Code to the path set by {@link #setRedirectPath(String)} within the context. + * The Authorization Code is then used to authenticate the user through the {@link OpenIdCredentials} and {@link OpenIdLoginService}. + *

    + *

    + * Once a user is authenticated the OpenID Claims can be retrieved through an attribute on the session with the key {@link #CLAIMS}. + * The full response containing the OAuth 2.0 Access Token can be obtained with the session attribute {@link #RESPONSE}. + *

    + *

    {@link SessionAuthentication} is then used to wrap Authentication results so that they are associated with the session.

    + */ +public class OpenIdAuthenticator extends LoginAuthenticator +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdAuthenticator.class); + + public static final String CLAIMS = "org.eclipse.jetty.security.openid.claims"; + public static final String RESPONSE = "org.eclipse.jetty.security.openid.response"; + public static final String ISSUER = "org.eclipse.jetty.security.openid.issuer"; + public static final String REDIRECT_PATH = "org.eclipse.jetty.security.openid.redirect_path"; + public static final String LOGOUT_REDIRECT_PATH = "org.eclipse.jetty.security.openid.logout_redirect_path"; + public static final String ERROR_PAGE = "org.eclipse.jetty.security.openid.error_page"; + public static final String J_URI = "org.eclipse.jetty.security.openid.URI"; + public static final String J_POST = "org.eclipse.jetty.security.openid.POST"; + public static final String J_METHOD = "org.eclipse.jetty.security.openid.METHOD"; + public static final String J_SECURITY_CHECK = "/j_security_check"; + public static final String ERROR_PARAMETER = "error_description_jetty"; + private static final String CSRF_MAP = "org.eclipse.jetty.security.openid.csrf_map"; + + @Deprecated + public static final String CSRF_TOKEN = "org.eclipse.jetty.security.openid.csrf_token"; + + private final SecureRandom _secureRandom = new SecureRandom(); + private OpenIdConfiguration _openIdConfiguration; + private String _redirectPath; + private String _logoutRedirectPath; + private String _errorPage; + private String _errorPath; + private String _errorQuery; + private boolean _alwaysSaveUri; + + public OpenIdAuthenticator() + { + this(null, J_SECURITY_CHECK, null); + } + + public OpenIdAuthenticator(OpenIdConfiguration configuration) + { + this(configuration, J_SECURITY_CHECK, null); + } + + public OpenIdAuthenticator(OpenIdConfiguration configuration, String errorPage) + { + this(configuration, J_SECURITY_CHECK, errorPage); + } + + public OpenIdAuthenticator(OpenIdConfiguration configuration, String redirectPath, String errorPage) + { + this(configuration, redirectPath, errorPage, null); + } + + public OpenIdAuthenticator(OpenIdConfiguration configuration, String redirectPath, String errorPage, String logoutRedirectPath) + { + _openIdConfiguration = configuration; + setRedirectPath(redirectPath); + if (errorPage != null) + setErrorPage(errorPage); + if (logoutRedirectPath != null) + setLogoutRedirectPath(logoutRedirectPath); + } + + @Override + public void setConfiguration(AuthConfiguration authConfig) + { + if (_openIdConfiguration == null) + { + LoginService loginService = authConfig.getLoginService(); + if (!(loginService instanceof OpenIdLoginService)) + throw new IllegalArgumentException("invalid LoginService " + loginService); + this._openIdConfiguration = ((OpenIdLoginService)loginService).getConfiguration(); + } + + String redirectPath = authConfig.getParameter(REDIRECT_PATH); + if (redirectPath != null) + setRedirectPath(redirectPath); + + String error = authConfig.getParameter(ERROR_PAGE); + if (error != null) + setErrorPage(error); + + String logout = authConfig.getParameter(LOGOUT_REDIRECT_PATH); + if (logout != null) + setLogoutRedirectPath(logout); + + super.setConfiguration(new OpenIdAuthConfiguration(_openIdConfiguration, authConfig)); + } + + @Override + public String getAuthMethod() + { + return Constraint.__OPENID_AUTH; + } + + @Deprecated + public void setAlwaysSaveUri(boolean alwaysSave) + { + _alwaysSaveUri = alwaysSave; + } + + @Deprecated + public boolean isAlwaysSaveUri() + { + return _alwaysSaveUri; + } + + public void setRedirectPath(String redirectPath) + { + if (redirectPath == null) + { + LOG.warn("redirect path must not be null, defaulting to " + J_SECURITY_CHECK); + redirectPath = J_SECURITY_CHECK; + } + else if (!redirectPath.startsWith("/")) + { + LOG.warn("redirect path must start with /"); + redirectPath = "/" + redirectPath; + } + + _redirectPath = redirectPath; + } + + public void setLogoutRedirectPath(String logoutRedirectPath) + { + if (logoutRedirectPath == null) + { + LOG.warn("redirect path must not be null, defaulting to /"); + logoutRedirectPath = "/"; + } + else if (!logoutRedirectPath.startsWith("/")) + { + LOG.warn("redirect path must start with /"); + logoutRedirectPath = "/" + logoutRedirectPath; + } + + _logoutRedirectPath = logoutRedirectPath; + } + + public void setErrorPage(String path) + { + if (path == null || path.trim().length() == 0) + { + _errorPath = null; + _errorPage = null; + } + else + { + if (!path.startsWith("/")) + { + LOG.warn("error-page must start with /"); + path = "/" + path; + } + _errorPage = path; + _errorPath = path; + _errorQuery = ""; + + int queryIndex = _errorPath.indexOf('?'); + if (queryIndex > 0) + { + _errorPath = _errorPage.substring(0, queryIndex); + _errorQuery = _errorPage.substring(queryIndex + 1); + } + } + } + + @Override + public UserIdentity login(String username, Object credentials, Request request, Response response) + { + if (LOG.isDebugEnabled()) + LOG.debug("login {} {} {}", username, credentials, request); + + UserIdentity user = super.login(username, credentials, request, response); + if (user != null) + { + Session session = request.getSession(true); + Authentication cached = new SessionAuthentication(getAuthMethod(), user, credentials); + synchronized (session) + { + session.setAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE, cached); + session.setAttribute(CLAIMS, ((OpenIdCredentials)credentials).getClaims()); + session.setAttribute(RESPONSE, ((OpenIdCredentials)credentials).getResponse()); + session.setAttribute(ISSUER, _openIdConfiguration.getIssuer()); + } + } + return user; + } + + @Override + public void logout(Request request) + { + attemptLogoutRedirect(request, response); + super.logout(request); + Session session = request.getSession(false); + + if (session == null) + return; + + synchronized (session) + { + session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); + session.removeAttribute(CLAIMS); + session.removeAttribute(RESPONSE); + session.removeAttribute(ISSUER); + } + } + + /** + * This will attempt to redirect the request to the end_session_endpoint, and finally to the {@link #REDIRECT_PATH}. + * + * If end_session_endpoint is defined the request will be redirected to the end_session_endpoint, the optional + * post_logout_redirect_uri parameter will be set if {@link #REDIRECT_PATH} is non-null. + * + * If the end_session_endpoint is not defined then the request will be redirected to {@link #REDIRECT_PATH} if it is a + * non-null value, otherwise no redirection will be done. + * + * @param request the request to redirect. + */ + private void attemptLogoutRedirect(Request request, Response response) + { + try + { + String endSessionEndpoint = _openIdConfiguration.getEndSessionEndpoint(); + String redirectUri = null; + if (_logoutRedirectPath != null) + { + StringBuilder sb = new StringBuilder(128); + URIUtil.appendSchemeHostPort(sb, request.getHttpURI().getScheme(), Request.getServerName(request), Request.getServerPort(request)); + sb.append(Request.getContextPath(request)); + sb.append(_logoutRedirectPath); + redirectUri = sb.toString(); + } + + Session session = request.getSession(false); + if (endSessionEndpoint == null || session == null) + { + if (redirectUri != null) + sendRedirect(request, response, redirectUri); + return; + } + + Object openIdResponse = session.getAttribute(OpenIdAuthenticator.RESPONSE); + if (!(openIdResponse instanceof Map)) + { + if (redirectUri != null) + sendRedirect(request, response, redirectUri); + return; + } + + @SuppressWarnings("rawtypes") + String idToken = (String)((Map)openIdResponse).get("id_token"); + sendRedirect(request, response, endSessionEndpoint + + "?id_token_hint=" + UrlEncoded.encodeString(idToken, StandardCharsets.UTF_8) + + ((redirectUri == null) ? "" : "&post_logout_redirect_uri=" + UrlEncoded.encodeString(redirectUri, StandardCharsets.UTF_8))); + } + catch (Throwable t) + { + LOG.warn("failed to redirect to end_session_endpoint", t); + } + } + + private void sendRedirect(Request request, Response response, String location) throws IOException + { + try (Blocker.Callback callback = Blocker.callback()) + { + Response.sendRedirect(request, response, callback, location); + callback.block(); + } + } + + @Override + public Request prepareRequest(Request request) + { + //if this is a request resulting from a redirect after auth is complete + //(ie its from a redirect to the original request uri) then due to + //browser handling of 302 redirects, the method may not be the same as + //that of the original request. Replace the method and original post + //params (if it was a post). + // + //See Servlet Spec 3.1 sec 13.6.3 + Session session = request.getSession(false); + if (session == null) + return request; //not authenticated yet + + HttpURI juri; + String method; + synchronized (session) + { + if (session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) + return request; //not authenticated yet + + juri = (HttpURI)session.getAttribute(J_URI); + if (juri == null) + return request; //no original uri saved + + method = (String)session.getAttribute(J_METHOD); + if (method == null || method.length() == 0) + return request; //didn't save original request method + } + + if (!juri.equals(request.getHttpURI())) + return request; //this request is not for the same url as the original + + // Restore the original request's method on this request. + if (LOG.isDebugEnabled()) + LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); + + return new Request.Wrapper(request) + { + @Override + public String getMethod() + { + return method; + } + }; + } + + protected Fields getParameters(Request request) + { + try + { + Fields queryFields = Request.extractQueryParameters(request); + Fields formFields = FormFields.from(request).get(); + return Fields.combine(queryFields, formFields); + } + catch (InterruptedException | ExecutionException e) + { + throw new RuntimeException(e); + } + } + + @Override + public Authentication validateRequest(Request request, Response response, Callback cb, boolean mandatory) throws ServerAuthException + { + if (LOG.isDebugEnabled()) + LOG.debug("validateRequest({},{},{})", request, response, mandatory); + + String uri = request.getHttpURI().toString(); + if (uri == null) + uri = "/"; + + mandatory |= isJSecurityCheck(uri); + if (!mandatory) + return new DeferredAuthentication(this); + + if (isErrorPage(Request.getPathInContext(request)) && !DeferredAuthentication.isDeferred(response)) + return new DeferredAuthentication(this); + + try + { + // Get the Session. + Session session = request.getSession(true); + + // TODO: No session API to work this out? + /* + if (request.isRequestedSessionIdFromURL()) + { + sendError(req, res, cb, "Session ID must be a cookie to support OpenID authentication"); + return Authentication.SEND_FAILURE; + } + */ + + // Handle a request for authentication. + if (isJSecurityCheck(uri)) + { + Fields parameters = getParameters(request); + String authCode = parameters.getValue("code"); + if (authCode == null) + { + sendError(request, response, cb, "auth failed: no code parameter"); + return Authentication.SEND_FAILURE; + } + + String state = parameters.getValue("state"); + if (state == null) + { + sendError(request, response, cb, "auth failed: no state parameter"); + return Authentication.SEND_FAILURE; + } + + // Verify anti-forgery state token. + UriRedirectInfo uriRedirectInfo; + synchronized (session) + { + uriRedirectInfo = removeAndClearCsrfMap(session, state); + } + if (uriRedirectInfo == null) + { + sendError(request, response, cb, "auth failed: invalid state parameter"); + return Authentication.SEND_FAILURE; + } + + // Attempt to login with the provided authCode. + OpenIdCredentials credentials = new OpenIdCredentials(authCode, getRedirectUri(request)); + UserIdentity user = login(null, credentials, request, response); + if (user == null) + { + sendError(request, response, cb, null); + return Authentication.SEND_FAILURE; + } + + OpenIdAuthentication openIdAuth = new OpenIdAuthentication(getAuthMethod(), user); + if (LOG.isDebugEnabled()) + LOG.debug("authenticated {}->{}", openIdAuth, uriRedirectInfo.getUri()); + + // Save redirect info in session so original request can be restored after redirect. + synchronized (session) + { + session.setAttribute(J_URI, uriRedirectInfo.getUri()); + session.setAttribute(J_METHOD, uriRedirectInfo.getMethod()); + session.setAttribute(J_POST, uriRedirectInfo.getFormParameters()); + } + + // Redirect to the original URI. + response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); + int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() + ? HttpStatus.MOVED_TEMPORARILY_302 : HttpStatus.SEE_OTHER_303; + Response.sendRedirect(request, response, cb, redirectCode, uriRedirectInfo.getUri(), true); + return openIdAuth; + } + + // Look for cached authentication in the Session. + Authentication authentication = (Authentication)session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); + if (authentication != null) + { + // Has authentication been revoked? + if (authentication instanceof Authentication.User && _loginService != null && + !_loginService.validate(((Authentication.User)authentication).getUserIdentity())) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth revoked {}", authentication); + synchronized (session) + { + session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); + } + } + else + { + synchronized (session) + { + HttpURI jUri = (HttpURI)session.getAttribute(J_URI); + if (jUri != null) + { + // Check if the request is for the same url as the original and restore params if it was a post. + if (LOG.isDebugEnabled()) + LOG.debug("auth retry {}->{}", authentication, jUri); + + if (jUri.equals(request.getHttpURI())) + { + @SuppressWarnings("unchecked") + MultiMap jPost = (MultiMap)session.getAttribute(J_POST); + if (jPost != null) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth rePOST {}->{}", authentication, jUri); + // TODO: + // baseRequest.setContentParameters(jPost); + } + session.removeAttribute(J_URI); + session.removeAttribute(J_METHOD); + session.removeAttribute(J_POST); + } + } + } + } + if (LOG.isDebugEnabled()) + LOG.debug("auth {}", authentication); + return authentication; + } + + // If we can't send challenge. + if (DeferredAuthentication.isDeferred(response)) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth deferred {}", session.getId()); + return Authentication.UNAUTHENTICATED; + } + + // Send the the challenge. + String challengeUri = getChallengeUri(request); + if (LOG.isDebugEnabled()) + LOG.debug("challenge {}->{}", session.getId(), challengeUri); + int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() + ? HttpStatus.MOVED_TEMPORARILY_302 : HttpStatus.SEE_OTHER_303; + Response.sendRedirect(request, response, cb, redirectCode, challengeUri, true); + + return Authentication.SEND_CONTINUE; + } + catch (IOException e) + { + throw new ServerAuthException(e); + } + } + + /** + * Report an error case either by redirecting to the error page if it is defined, otherwise sending a 403 response. + * If the message parameter is not null, a query parameter with a key of {@link #ERROR_PARAMETER} and value of the error + * message will be logged and added to the error redirect URI if the error page is defined. + * @param request the request. + * @param response the response. + * @param message the reason for the error or null. + * @throws IOException if sending the error fails for any reason. + */ + private void sendError(Request request, Response response, Callback callback, String message) throws IOException + { + if (LOG.isDebugEnabled()) + LOG.debug("OpenId authentication FAILED: {}", message); + + if (_errorPage == null) + { + if (LOG.isDebugEnabled()) + LOG.debug("auth failed 403"); + if (response != null) + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403); + } + else + { + if (LOG.isDebugEnabled()) + LOG.debug("auth failed {}", _errorPage); + + String redirectUri = URIUtil.addPaths(httpServletRequest.getContextPath(), _errorPage); + if (message != null) + { + String query = URIUtil.addQueries(ERROR_PARAMETER + "=" + UrlEncoded.encodeString(message), _errorQuery); + redirectUri = URIUtil.addPathQuery(URIUtil.addPaths(httpServletRequest.getContextPath(), _errorPath), query); + } + + int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() + ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER; + Response.sendRedirect(request, response, callback, redirectCode, redirectUri, true); + } + } + + public boolean isJSecurityCheck(String uri) + { + int jsc = uri.indexOf(_redirectPath); + + if (jsc < 0) + return false; + int e = jsc + _redirectPath.length(); + if (e == uri.length()) + return true; + char c = uri.charAt(e); + return c == ';' || c == '#' || c == '/' || c == '?'; + } + + public boolean isErrorPage(String pathInContext) + { + return pathInContext != null && (pathInContext.equals(_errorPath)); + } + + private String getRedirectUri(Request request) + { + final StringBuffer redirectUri = new StringBuffer(128); + URIUtil.appendSchemeHostPort(redirectUri, request.getHttpURI().getScheme(), + Request.getServerName(request), Request.getServerPort(request)); + redirectUri.append(URIUtil.addPaths(request.getContext().getContextPath(), _redirectPath)); + return redirectUri.toString(); + } + + protected String getChallengeUri(Request request) + { + Session session = request.getSession(true); + String antiForgeryToken; + synchronized (session) + { + Map csrfMap = ensureCsrfMap(session); + antiForgeryToken = new BigInteger(130, _secureRandom).toString(32); + csrfMap.put(antiForgeryToken, new UriRedirectInfo(request)); + } + + // any custom scopes requested from configuration + StringBuilder scopes = new StringBuilder(); + for (String s : _openIdConfiguration.getScopes()) + { + scopes.append(" ").append(s); + } + + return _openIdConfiguration.getAuthEndpoint() + + "?client_id=" + UrlEncoded.encodeString(_openIdConfiguration.getClientId(), StandardCharsets.UTF_8) + + "&redirect_uri=" + UrlEncoded.encodeString(getRedirectUri(request), StandardCharsets.UTF_8) + + "&scope=openid" + UrlEncoded.encodeString(scopes.toString(), StandardCharsets.UTF_8) + + "&state=" + antiForgeryToken + + "&response_type=code"; + } + + @Override + public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, Authentication.User validatedUser) throws ServerAuthException + { + return req.isSecure(); + } + + private UriRedirectInfo removeAndClearCsrfMap(Session session, String csrf) + { + @SuppressWarnings("unchecked") + Map csrfMap = (Map)session.getAttribute(CSRF_MAP); + if (csrfMap == null) + return null; + + UriRedirectInfo uriRedirectInfo = csrfMap.get(csrf); + csrfMap.clear(); + return uriRedirectInfo; + } + + private Map ensureCsrfMap(Session session) + { + @SuppressWarnings("unchecked") + Map csrfMap = (Map)session.getAttribute(CSRF_MAP); + if (csrfMap == null) + { + csrfMap = new MRUMap(64); + session.setAttribute(CSRF_MAP, csrfMap); + } + return csrfMap; + } + + private static class MRUMap extends LinkedHashMap + { + private static final long serialVersionUID = 5375723072014233L; + + private final int _size; + + private MRUMap(int size) + { + _size = size; + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) + { + return size() > _size; + } + } + + private static class UriRedirectInfo implements Serializable + { + private static final long serialVersionUID = 139567755844461433L; + + private final HttpURI _uri; + private final String _method; + private final MultiMap _formParameters; + + public UriRedirectInfo(Request request) + { + _uri = request.getHttpURI().asString(); + _method = request.getMethod(); + + // TODO: + if (MimeTypes.Type.FORM_ENCODED.is(request.getHeaders().get(HttpHeader.CONTENT_TYPE)) && HttpMethod.POST.is(request.getMethod())) + { + MultiMap formParameters = new MultiMap<>(); + // request.extractFormParameters(formParameters); + _formParameters = formParameters; + } + else + { + _formParameters = null; + } + } + + public HttpURI getUri() + { + return _uri; + } + + public String getMethod() + { + return _method; + } + + public MultiMap getFormParameters() + { + return _formParameters; + } + } + + /** + * This Authentication represents a just completed OpenId Connect authentication. + * Subsequent requests from the same user are authenticated by the presents + * of a {@link SessionAuthentication} instance in their session. + */ + public static class OpenIdAuthentication extends UserAuthentication implements Authentication.ResponseSent + { + public OpenIdAuthentication(String method, UserIdentity userIdentity) + { + super(method, userIdentity); + } + + @Override + public String toString() + { + return "OpenId" + super.toString(); + } + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java new file mode 100644 index 000000000000..07af42975325 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.Collection; + +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.server.Context; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.util.security.Constraint; + +public class OpenIdAuthenticatorFactory implements Authenticator.Factory +{ + @Override + public Authenticator getAuthenticator(Server server, Context context, Authenticator.AuthConfiguration configuration) + { + LoginService loginService = configuration.getLoginService(); + String auth = configuration.getAuthMethod(); + if (Constraint.__OPENID_AUTH.equalsIgnoreCase(auth)) + { + // If we have an OpenIdLoginService we can extract the configuration. + if (loginService instanceof OpenIdLoginService) + return new OpenIdAuthenticator(((OpenIdLoginService)loginService).getConfiguration()); + + // Otherwise we should find an OpenIdConfiguration for this realm on the Server. + Collection configurations = server.getBeans(OpenIdConfiguration.class); + if (configurations == null || configurations.isEmpty()) + throw new IllegalStateException("No OpenIdConfiguration found"); + + // If only 1 configuration use that regardless of its realm name. + if (configurations.size() == 1) + return new OpenIdAuthenticator(configurations.iterator().next()); + + // If there are multiple configurations then select one matching the realm name. + String realmName = configuration.getRealmName(); + OpenIdConfiguration openIdConfiguration = configurations.stream() + .filter(c -> c.getIssuer().equals(realmName)) + .findAny() + .orElseThrow(() -> new IllegalStateException("No OpenIdConfiguration found for realm \"" + realmName + "\"")); + return new OpenIdAuthenticator(openIdConfiguration); + } + + return null; + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java new file mode 100644 index 000000000000..0997f5081f64 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java @@ -0,0 +1,291 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP; +import org.eclipse.jetty.io.ClientConnector; +import org.eclipse.jetty.util.ajax.JSON; +import org.eclipse.jetty.util.annotation.Name; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.ssl.SslContextFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Holds the configuration for an OpenID Connect service. + * + * This uses the OpenID Provider URL with the path {@link #CONFIG_PATH} to discover + * the required information about the OIDC service. + */ +public class OpenIdConfiguration extends ContainerLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdConfiguration.class); + private static final String CONFIG_PATH = "/.well-known/openid-configuration"; + private static final String AUTHORIZATION_ENDPOINT = "authorization_endpoint"; + private static final String TOKEN_ENDPOINT = "token_endpoint"; + private static final String END_SESSION_ENDPOINT = "end_session_endpoint"; + private static final String ISSUER = "issuer"; + + private final HttpClient httpClient; + private final String issuer; + private final String clientId; + private final String clientSecret; + private final List scopes = new ArrayList<>(); + private final String authMethod; + private String authEndpoint; + private String tokenEndpoint; + private String endSessionEndpoint; + private boolean authenticateNewUsers = false; + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param provider The URL of the OpenID provider. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + */ + public OpenIdConfiguration(String provider, String clientId, String clientSecret) + { + this(provider, null, null, clientId, clientSecret, null); + } + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param issuer The URL of the OpenID provider. + * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. + * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + * @param httpClient The {@link HttpClient} instance to use. + */ + public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint, + String clientId, String clientSecret, HttpClient httpClient) + { + this(issuer, authorizationEndpoint, tokenEndpoint, clientId, clientSecret, "client_secret_post", httpClient); + } + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param issuer The URL of the OpenID provider. + * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. + * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + * @param authMethod Authentication method to use with the Token Endpoint. + * @param httpClient The {@link HttpClient} instance to use. + */ + public OpenIdConfiguration(@Name("issuer") String issuer, + @Name("authorizationEndpoint") String authorizationEndpoint, + @Name("tokenEndpoint") String tokenEndpoint, + @Name("clientId") String clientId, + @Name("clientSecret") String clientSecret, + @Name("authMethod") String authMethod, + @Name("httpClient") HttpClient httpClient) + { + this(issuer, authorizationEndpoint, tokenEndpoint, null, clientId, clientSecret, authMethod, httpClient); + } + + /** + * Create an OpenID configuration for a specific OIDC provider. + * @param issuer The URL of the OpenID provider. + * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. + * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. + * @param endSessionEndpoint the URL of the OpdnID provider's end session endpoint if configured. + * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. + * @param clientSecret The client secret known only by the Client and the Authorization Server. + * @param authMethod Authentication method to use with the Token Endpoint. + * @param httpClient The {@link HttpClient} instance to use. + */ + public OpenIdConfiguration(@Name("issuer") String issuer, + @Name("authorizationEndpoint") String authorizationEndpoint, + @Name("tokenEndpoint") String tokenEndpoint, + @Name("endSessionEndpoint") String endSessionEndpoint, + @Name("clientId") String clientId, + @Name("clientSecret") String clientSecret, + @Name("authMethod") String authMethod, + @Name("httpClient") HttpClient httpClient) + { + this.issuer = issuer; + this.clientId = clientId; + this.clientSecret = clientSecret; + this.authEndpoint = authorizationEndpoint; + this.endSessionEndpoint = endSessionEndpoint; + this.tokenEndpoint = tokenEndpoint; + this.httpClient = httpClient != null ? httpClient : newHttpClient(); + this.authMethod = authMethod == null ? "client_secret_post" : authMethod; + + if (this.issuer == null) + throw new IllegalArgumentException("Issuer was not configured"); + + addBean(this.httpClient); + } + + @Override + protected void doStart() throws Exception + { + super.doStart(); + + if (authEndpoint == null || tokenEndpoint == null) + { + Map discoveryDocument = fetchOpenIdConnectMetadata(); + processMetadata(discoveryDocument); + } + } + + /** + * Process the OpenID Connect metadata discovered by {@link #fetchOpenIdConnectMetadata()}. + * By default, only the {@link #AUTHORIZATION_ENDPOINT} and {@link #TOKEN_ENDPOINT} claims are extracted. + * @see OpenID Connect Discovery 1.0 + * @throws IllegalStateException if a required field is not present in the metadata. + */ + protected void processMetadata(Map discoveryDocument) + { + authEndpoint = (String)discoveryDocument.get(AUTHORIZATION_ENDPOINT); + if (authEndpoint == null) + throw new IllegalStateException(AUTHORIZATION_ENDPOINT); + + tokenEndpoint = (String)discoveryDocument.get(TOKEN_ENDPOINT); + if (tokenEndpoint == null) + throw new IllegalStateException(TOKEN_ENDPOINT); + + // End session endpoint is optional. + if (endSessionEndpoint == null) + endSessionEndpoint = (String)discoveryDocument.get(END_SESSION_ENDPOINT); + + // We are lenient and not throw here as some major OIDC providers do not conform to this. + if (!Objects.equals(discoveryDocument.get(ISSUER), issuer)) + LOG.warn("The issuer in the metadata is not correct."); + } + + /** + * Obtain the JSON metadata from OpenID Connect Discovery Configuration Endpoint. + * @return a set of Claims about the OpenID Provider's configuration in JSON format. + * @throws IllegalStateException if metadata could not be fetched from the OP. + */ + protected Map fetchOpenIdConnectMetadata() + { + String provider = issuer; + if (provider.endsWith("/")) + provider = provider.substring(0, provider.length() - 1); + + try + { + Map result; + String responseBody = httpClient.GET(provider + CONFIG_PATH).getContentAsString(); + Object parsedResult = new JSON().fromJSON(responseBody); + + if (parsedResult instanceof Map) + { + Map rawResult = (Map)parsedResult; + result = rawResult.entrySet().stream() + .filter(entry -> entry.getValue() != null) + .collect(Collectors.toMap(it -> it.getKey().toString(), Map.Entry::getValue)); + if (LOG.isDebugEnabled()) + LOG.debug("discovery document {}", result); + return result; + } + else + { + LOG.warn("OpenID provider did not return a proper JSON object response. Result was '{}'", responseBody); + throw new IllegalStateException("Could not parse OpenID provider's malformed response"); + } + } + catch (Exception e) + { + throw new IllegalStateException("invalid identity provider " + provider, e); + } + } + + public HttpClient getHttpClient() + { + return httpClient; + } + + public String getAuthEndpoint() + { + return authEndpoint; + } + + public String getClientId() + { + return clientId; + } + + public String getClientSecret() + { + return clientSecret; + } + + public String getIssuer() + { + return issuer; + } + + public String getTokenEndpoint() + { + return tokenEndpoint; + } + + public String getEndSessionEndpoint() + { + return endSessionEndpoint; + } + + public String getAuthMethod() + { + return authMethod; + } + + public void addScopes(String... scopes) + { + if (scopes != null) + Collections.addAll(this.scopes, scopes); + } + + public List getScopes() + { + return scopes; + } + + public boolean isAuthenticateNewUsers() + { + return authenticateNewUsers; + } + + public void setAuthenticateNewUsers(boolean authenticateNewUsers) + { + this.authenticateNewUsers = authenticateNewUsers; + } + + private static HttpClient newHttpClient() + { + ClientConnector connector = new ClientConnector(); + connector.setSslContextFactory(new SslContextFactory.Client(false)); + return new HttpClient(new HttpClientTransportOverHTTP(connector)); + } + + @Override + public String toString() + { + return String.format("%s@%x{iss=%s, clientId=%s, authEndpoint=%s, authMethod=%s, tokenEndpoint=%s, scopes=%s, authNewUsers=%s}", + getClass().getSimpleName(), hashCode(), issuer, clientId, authEndpoint, authMethod, tokenEndpoint, scopes, authenticateNewUsers); + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java new file mode 100644 index 000000000000..81616eede805 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java @@ -0,0 +1,213 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.io.Serializable; +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.client.Authentication; +import org.eclipse.jetty.client.BasicAuthentication; +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.FormRequestContent; +import org.eclipse.jetty.client.Request; +import org.eclipse.jetty.util.Fields; +import org.eclipse.jetty.util.ajax.JSON; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + *

    The credentials of an user to be authenticated with OpenID Connect. This will contain + * the OpenID ID Token and the OAuth 2.0 Access Token.

    + * + *

    + * This is constructed with an authorization code from the authentication request. This authorization code + * is then exchanged using {@link #redeemAuthCode(OpenIdConfiguration)} for a response containing the ID Token and Access Token. + * The response is then validated against the {@link OpenIdConfiguration}. + *

    + */ +public class OpenIdCredentials implements Serializable +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdCredentials.class); + private static final long serialVersionUID = 4766053233370044796L; + + private final String redirectUri; + private String authCode; + private Map response; + private Map claims; + private boolean verified = false; + + public OpenIdCredentials(Map claims) + { + this.redirectUri = null; + this.authCode = null; + this.claims = claims; + } + + public OpenIdCredentials(String authCode, String redirectUri) + { + this.authCode = authCode; + this.redirectUri = redirectUri; + } + + public String getUserId() + { + return (String)claims.get("sub"); + } + + public Map getClaims() + { + return claims; + } + + public Map getResponse() + { + return response; + } + + public void redeemAuthCode(OpenIdConfiguration configuration) throws Exception + { + if (LOG.isDebugEnabled()) + LOG.debug("redeemAuthCode() {}", this); + + if (authCode != null) + { + try + { + response = claimAuthCode(configuration); + if (LOG.isDebugEnabled()) + LOG.debug("response: {}", response); + + String idToken = (String)response.get("id_token"); + if (idToken == null) + throw new AuthenticationException("no id_token"); + + String accessToken = (String)response.get("access_token"); + if (accessToken == null) + throw new AuthenticationException("no access_token"); + + String tokenType = (String)response.get("token_type"); + if (!"Bearer".equalsIgnoreCase(tokenType)) + throw new AuthenticationException("invalid token_type"); + + claims = JwtDecoder.decode(idToken); + if (LOG.isDebugEnabled()) + LOG.debug("claims {}", claims); + } + finally + { + // reset authCode as it can only be used once + authCode = null; + } + } + + if (!verified) + { + validateClaims(configuration); + verified = true; + } + } + + private void validateClaims(OpenIdConfiguration configuration) throws Exception + { + // Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim. + if (!configuration.getIssuer().equals(claims.get("iss"))) + throw new AuthenticationException("Issuer Identifier MUST exactly match the iss Claim"); + + // The aud (audience) Claim MUST contain the client_id value. + validateAudience(configuration); + + // If an azp (authorized party) Claim is present, verify that its client_id is the Claim Value. + Object azp = claims.get("azp"); + if (azp != null && !configuration.getClientId().equals(azp)) + throw new AuthenticationException("Authorized party claim value should be the client_id"); + + // Check that the ID token has not expired by checking the exp claim. + long expiry = (Long)claims.get("exp"); + long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F); + if (currentTimeSeconds > expiry) + throw new AuthenticationException("ID Token has expired"); + } + + private void validateAudience(OpenIdConfiguration configuration) throws AuthenticationException + { + Object aud = claims.get("aud"); + String clientId = configuration.getClientId(); + boolean isString = aud instanceof String; + boolean isList = aud instanceof Object[]; + boolean isValidType = isString || isList; + + if (isString && !clientId.equals(aud)) + throw new AuthenticationException("Audience Claim MUST contain the client_id value"); + else if (isList) + { + List list = Arrays.asList((Object[])aud); + if (!list.contains(clientId)) + throw new AuthenticationException("Audience Claim MUST contain the client_id value"); + + if (list.size() > 1 && claims.get("azp") == null) + throw new AuthenticationException("A multi-audience ID token needs to contain an azp claim"); + } + else if (!isValidType) + throw new AuthenticationException("Audience claim was not valid"); + } + + @SuppressWarnings("unchecked") + private Map claimAuthCode(OpenIdConfiguration configuration) throws Exception + { + Fields fields = new Fields(); + fields.add("code", authCode); + fields.add("redirect_uri", redirectUri); + fields.add("grant_type", "authorization_code"); + + Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint()); + switch (configuration.getAuthMethod()) + { + case "client_secret_basic": + URI uri = URI.create(configuration.getTokenEndpoint()); + Authentication.Result authentication = new BasicAuthentication.BasicResult(uri, configuration.getClientId(), configuration.getClientSecret()); + authentication.apply(request); + break; + case "client_secret_post": + fields.add("client_id", configuration.getClientId()); + fields.add("client_secret", configuration.getClientSecret()); + break; + default: + throw new IllegalStateException(configuration.getAuthMethod()); + } + + FormRequestContent formContent = new FormRequestContent(fields); + request = request.body(formContent).timeout(10, TimeUnit.SECONDS); + ContentResponse response = request.send(); + String responseBody = response.getContentAsString(); + if (LOG.isDebugEnabled()) + LOG.debug("Authentication response: {}", responseBody); + + Object parsedResponse = new JSON().fromJSON(responseBody); + if (!(parsedResponse instanceof Map)) + throw new AuthenticationException("Malformed response from OpenID Provider"); + return (Map)parsedResponse; + } + + public static class AuthenticationException extends Exception + { + public AuthenticationException(String message) + { + super(message); + } + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java new file mode 100644 index 000000000000..a17fb0a8bbd5 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java @@ -0,0 +1,167 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.Objects; +import javax.security.auth.Subject; + +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The implementation of {@link LoginService} required to use OpenID Connect. + * + *

    + * Can contain an optional wrapped {@link LoginService} which is used to store role information about users. + *

    + */ +public class OpenIdLoginService extends ContainerLifeCycle implements LoginService +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdLoginService.class); + + private final OpenIdConfiguration configuration; + private final LoginService loginService; + private IdentityService identityService; + private boolean authenticateNewUsers; + + public OpenIdLoginService(OpenIdConfiguration configuration) + { + this(configuration, null); + } + + /** + * Use a wrapped {@link LoginService} to store information about user roles. + * Users in the wrapped loginService must be stored with their username as + * the value of the sub (subject) Claim, and a credentials value of the empty string. + * @param configuration the OpenID configuration to use. + * @param loginService the wrapped LoginService to defer to for user roles. + */ + public OpenIdLoginService(OpenIdConfiguration configuration, LoginService loginService) + { + this.configuration = Objects.requireNonNull(configuration); + this.loginService = loginService; + addBean(this.configuration); + addBean(this.loginService); + + setAuthenticateNewUsers(configuration.isAuthenticateNewUsers()); + } + + @Override + public String getName() + { + return configuration.getIssuer(); + } + + public OpenIdConfiguration getConfiguration() + { + return configuration; + } + + @Override + public UserIdentity login(String identifier, Object credentials, Request req) + { + if (LOG.isDebugEnabled()) + LOG.debug("login({}, {}, {})", identifier, credentials, req); + + OpenIdCredentials openIdCredentials = (OpenIdCredentials)credentials; + try + { + openIdCredentials.redeemAuthCode(configuration); + } + catch (Throwable e) + { + LOG.warn("Unable to redeem auth code", e); + return null; + } + + OpenIdUserPrincipal userPrincipal = new OpenIdUserPrincipal(openIdCredentials); + Subject subject = new Subject(); + subject.getPrincipals().add(userPrincipal); + subject.getPrivateCredentials().add(credentials); + subject.setReadOnly(); + + IdentityService identityService = getIdentityService(); + if (loginService != null) + { + UserIdentity userIdentity = loginService.login(openIdCredentials.getUserId(), "", req); + if (userIdentity == null) + { + if (isAuthenticateNewUsers()) + return identityService.newUserIdentity(subject, userPrincipal, new String[0]); + return null; + } + return new OpenIdUserIdentity(subject, userPrincipal, userIdentity); + } + + return identityService.newUserIdentity(subject, userPrincipal, new String[0]); + } + + public boolean isAuthenticateNewUsers() + { + return authenticateNewUsers; + } + + /** + * This setting is only meaningful if a wrapped {@link LoginService} has been set. + *

    + * If set to true, any users not found by the wrapped {@link LoginService} will still + * be authenticated but with no roles, if set to false users will not be + * authenticated unless they are discovered by the wrapped {@link LoginService}. + *

    + * @param authenticateNewUsers whether to authenticate users not found by a wrapping LoginService + */ + public void setAuthenticateNewUsers(boolean authenticateNewUsers) + { + this.authenticateNewUsers = authenticateNewUsers; + } + + @Override + public boolean validate(UserIdentity user) + { + if (!(user.getUserPrincipal() instanceof OpenIdUserPrincipal)) + return false; + + return loginService == null || loginService.validate(user); + } + + @Override + public IdentityService getIdentityService() + { + return loginService == null ? identityService : loginService.getIdentityService(); + } + + @Override + public void setIdentityService(IdentityService service) + { + if (isRunning()) + throw new IllegalStateException("Running"); + + if (loginService != null) + loginService.setIdentityService(service); + else + identityService = service; + } + + @Override + public void logout(UserIdentity user) + { + if (loginService != null) + loginService.logout(user); + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java new file mode 100644 index 000000000000..c1c29d2febad --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.security.Principal; +import javax.security.auth.Subject; + +import org.eclipse.jetty.security.UserIdentity; + +public class OpenIdUserIdentity implements UserIdentity +{ + private final Subject subject; + private final Principal userPrincipal; + private final UserIdentity userIdentity; + + public OpenIdUserIdentity(Subject subject, Principal userPrincipal, UserIdentity userIdentity) + { + this.subject = subject; + this.userPrincipal = userPrincipal; + this.userIdentity = userIdentity; + } + + @Override + public Subject getSubject() + { + return subject; + } + + @Override + public Principal getUserPrincipal() + { + return userPrincipal; + } + + @Override + public boolean isUserInRole(String role) + { + return userIdentity != null && userIdentity.isUserInRole(role); + } +} diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java new file mode 100644 index 000000000000..f5598de1c6cb --- /dev/null +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.io.Serializable; +import java.security.Principal; + +public class OpenIdUserPrincipal implements Principal, Serializable +{ + private static final long serialVersionUID = 1521094652756670469L; + private final OpenIdCredentials _credentials; + + public OpenIdUserPrincipal(OpenIdCredentials credentials) + { + _credentials = credentials; + } + + public OpenIdCredentials getCredentials() + { + return _credentials; + } + + @Override + public String getName() + { + return _credentials.getUserId(); + } + + @Override + public String toString() + { + return _credentials.getUserId(); + } +} diff --git a/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory b/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory new file mode 100644 index 000000000000..da9c63a7ec01 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory @@ -0,0 +1 @@ +org.eclipse.jetty.ee10.security.openid.OpenIdAuthenticatorFactory diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java new file mode 100644 index 000000000000..7a99cbf02cf3 --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java @@ -0,0 +1,117 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class JwtDecoderTest +{ + public static Stream paddingExamples() + { + return Stream.of( + Arguments.of("XXXX", "XXXX"), + Arguments.of("XXX", "XXX="), + Arguments.of("XX", "XX=="), + Arguments.of("XXX=", "XXX="), + Arguments.of("X-X", "X-X="), + Arguments.of("@#", "@#=="), + Arguments.of("X=", "X="), + Arguments.of("XX=", "XX="), + Arguments.of("XX==", "XX=="), + Arguments.of("XXX=", "XXX="), + Arguments.of("", "") + ); + } + + public static Stream badPaddingExamples() + { + return Stream.of( + Arguments.of("X"), + Arguments.of("XXXXX") + ); + } + + @ParameterizedTest + @MethodSource("paddingExamples") + public void testPaddingBase64(String input, String expected) + { + byte[] actual = JwtDecoder.padJWTSection(input); + assertThat(actual, is(expected.getBytes())); + } + + @ParameterizedTest + @MethodSource("badPaddingExamples") + public void testPaddingInvalidBase64(String input) + { + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> JwtDecoder.padJWTSection(input)); + + assertThat(error.getMessage(), is("Not a valid Base64-encoded string")); + } + + @Test + public void testEncodeDecode() + { + String issuer = "example.com"; + String subject = "1234"; + String clientId = "1234.client.id"; + String name = "Bob"; + long expiry = 123; + + // Create a fake ID Token. + String claims = JwtEncoder.createIdToken(issuer, clientId, subject, name, expiry); + String idToken = JwtEncoder.encode(claims); + + // Decode the ID Token and verify the claims are the same. + Map decodedClaims = JwtDecoder.decode(idToken); + assertThat(decodedClaims.get("iss"), is(issuer)); + assertThat(decodedClaims.get("sub"), is(subject)); + assertThat(decodedClaims.get("aud"), is(clientId)); + assertThat(decodedClaims.get("name"), is(name)); + assertThat(decodedClaims.get("exp"), is(expiry)); + } + + @Test + public void testDecodeMissingPadding() + { + // Example given in Issue #4128 which requires the re-adding the B64 padding to decode. + String jwt = "eyJraWQiOiIxNTU1OTM0ODQ3IiwieDV0IjoiOWdCOW9zRldSRHRSMkhtNGNmVnJnWTBGcmZRIiwiYWxnIjoiUlMyNTYifQ" + + ".eyJhdF9oYXNoIjoiQTA0NUoxcE5YRk1nYzlXN2wxSk1fUSIsImRlbGVnYXRpb25faWQiOiJjZTBhNjRlNS0xYWY3LTQ2MzEtOGUz" + + "NC1mNDE5N2JkYzVjZTAiLCJhY3IiOiJ1cm46c2U6Y3VyaXR5OmF1dGhlbnRpY2F0aW9uOmh0bWwtZm9ybTpodG1sLXByaW1hcnkiL" + + "CJzX2hhc2giOiIwc1FtRG9YY3FwcnM4NWUzdy0wbHdBIiwiYXpwIjoiNzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYz" + + "c2IiwiYXV0aF90aW1lIjoxNTY5NjU4MDk1LCJleHAiOjE1Njk2NjE5OTUsIm5iZiI6MTU2OTY1ODM5NSwianRpIjoiZjJkNWI2YzE" + + "tNTIxYi00Y2Y5LThlNWEtOTg5NGJhNmE0MzkyIiwiaXNzIjoiaHR0cHM6Ly9ub3JkaWNhcGlzLmN1cml0eS5pby9-IiwiYXVkIjoi" + + "NzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYzc2Iiwic3ViIjoibmlrb3MiLCJpYXQiOjE1Njk2NTgzOTUsInB1cnBvc" + + "2UiOiJpZCJ9.Wd458zNmXggpkDN6vbS3-aiajh4-VbkmcStLYUqahYJUp9p-AUI_RZttWvwh3UDMG9rWww_ya8KFK_SkPfKooEaSN" + + "OjOhw0ox4d-9lgti3J49eRyO20RViXvRHyLVtcjv5IaqvMXgwW60Thubv19OION7DstyArffcxNNSpiqDq6wjd0T2DJ3gSXXlJHLT" + + "Wrry3svqu1j_GCbHc04XYGicxsusKgc3n22dh4I6p4trdo0Gu5Un0bZ8Yov7IzWItqTgm9X5r9gZlAOLcAuK1WTwkzAwZJ24HgvxK" + + "muYfV_4ZCg_VPN2Op8YPuRAQOgUERpeTv1RDFTOG9GKZIMBVR0A"; + + // Decode the ID Token and verify the claims are the correct. + Map decodedClaims = JwtDecoder.decode(jwt); + assertThat(decodedClaims.get("sub"), is("nikos")); + assertThat(decodedClaims.get("aud"), is("76be79cb-3a56-4e17-8776-42577924cc76")); + assertThat(decodedClaims.get("exp"), is(1569661995L)); + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java new file mode 100644 index 000000000000..2e8930c9b97b --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java @@ -0,0 +1,53 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.Base64; + +/** + * A basic JWT encoder for testing purposes. + */ +public class JwtEncoder +{ + private static final Base64.Encoder ENCODER = Base64.getUrlEncoder(); + private static final String DEFAULT_HEADER = "{\"INFO\": \"this is not used or checked in our implementation\"}"; + private static final String DEFAULT_SIGNATURE = "we do not validate signature as we use the authorization code flow"; + + public static String encode(String idToken) + { + return stripPadding(ENCODER.encodeToString(DEFAULT_HEADER.getBytes())) + "." + + stripPadding(ENCODER.encodeToString(idToken.getBytes())) + "." + + stripPadding(ENCODER.encodeToString(DEFAULT_SIGNATURE.getBytes())); + } + + private static String stripPadding(String paddedBase64) + { + return paddedBase64.split("=")[0]; + } + + /** + * Create a basic JWT for testing using argument supplied attributes. + */ + public static String createIdToken(String provider, String clientId, String subject, String name, long expiry) + { + return "{" + + "\"iss\": \"" + provider + "\"," + + "\"sub\": \"" + subject + "\"," + + "\"aud\": \"" + clientId + "\"," + + "\"exp\": " + expiry + "," + + "\"name\": \"" + name + "\"," + + "\"email\": \"" + name + "@example.com" + "\"" + + "}"; + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java new file mode 100644 index 000000000000..805b62befd9b --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java @@ -0,0 +1,254 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.io.File; +import java.io.IOException; +import java.security.Principal; +import java.util.Map; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.security.ConstraintMapping; +import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.session.FileSessionDataStoreFactory; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.security.Constraint; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.is; + +@SuppressWarnings("unchecked") +public class OpenIdAuthenticationTest +{ + public static final String CLIENT_ID = "testClient101"; + public static final String CLIENT_SECRET = "secret37989798"; + + private OpenIdProvider openIdProvider; + private Server server; + private ServerConnector connector; + private HttpClient client; + + @BeforeEach + public void setup() throws Exception + { + openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); + openIdProvider.start(); + + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); + + // Add servlets + context.addServlet(LoginPage.class, "/login"); + context.addServlet(LogoutPage.class, "/logout"); + context.addServlet(HomePage.class, "/*"); + context.addServlet(ErrorPage.class, "/error"); + + // configure security constraints + Constraint constraint = new Constraint(); + constraint.setName(Constraint.__OPENID_AUTH); + constraint.setRoles(new String[]{"**"}); + constraint.setAuthenticate(true); + + Constraint adminConstraint = new Constraint(); + adminConstraint.setName(Constraint.__OPENID_AUTH); + adminConstraint.setRoles(new String[]{"admin"}); + adminConstraint.setAuthenticate(true); + + // constraint mappings + ConstraintMapping profileMapping = new ConstraintMapping(); + profileMapping.setConstraint(constraint); + profileMapping.setPathSpec("/profile"); + ConstraintMapping loginMapping = new ConstraintMapping(); + loginMapping.setConstraint(constraint); + loginMapping.setPathSpec("/login"); + ConstraintMapping adminMapping = new ConstraintMapping(); + adminMapping.setConstraint(adminConstraint); + adminMapping.setPathSpec("/admin"); + + // security handler + ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); + + securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); + securityHandler.setRealmName(openIdProvider.getProvider()); + securityHandler.addConstraintMapping(profileMapping); + securityHandler.addConstraintMapping(loginMapping); + securityHandler.addConstraintMapping(adminMapping); + + // Authentication using local OIDC Provider + server.addBean(new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET)); + securityHandler.setInitParameter(OpenIdAuthenticator.REDIRECT_PATH, "/redirect_path"); + securityHandler.setInitParameter(OpenIdAuthenticator.ERROR_PAGE, "/error"); + securityHandler.setInitParameter(OpenIdAuthenticator.LOGOUT_REDIRECT_PATH, "/"); + context.setSecurityHandler(securityHandler); + + File datastoreDir = MavenTestingUtils.getTargetTestingDir("datastore"); + IO.delete(datastoreDir); + FileSessionDataStoreFactory fileSessionDataStoreFactory = new FileSessionDataStoreFactory(); + fileSessionDataStoreFactory.setStoreDir(datastoreDir); + server.addBean(fileSessionDataStoreFactory); + + server.start(); + String redirectUri = "http://localhost:" + connector.getLocalPort() + "/redirect_path"; + openIdProvider.addRedirectUri(redirectUri); + + client = new HttpClient(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + openIdProvider.stop(); + server.stop(); + } + + @Test + public void testLoginLogout() throws Exception + { + openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); + + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Request to login is success + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("success")); + + // Now authenticated we can get info + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // Request to admin page gives 403 as we do not have admin role + response = client.GET(appUriString + "/admin"); + assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403)); + + // We can restart the server and still be logged in as we have persistent session datastore. + server.stop(); + server.start(); + appUriString = "http://localhost:" + connector.getLocalPort(); + + // After restarting server the authentication is saved as a session authentication. + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // We are no longer authenticated after logging out + response = client.GET(appUriString + "/logout"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Test that the user was logged out successfully on the openid provider. + assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(0L)); + assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); + } + + public static class LoginPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/html"); + response.getWriter().println("success"); + response.getWriter().println("
    Home"); + } + } + + public static class LogoutPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + request.logout(); + } + } + + public static class AdminPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); + response.getWriter().println(userInfo.get("sub") + ": success"); + } + } + + public static class HomePage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/html"); + Principal userPrincipal = request.getUserPrincipal(); + if (userPrincipal != null) + { + Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); + response.getWriter().println("userId: " + userInfo.get("sub") + "
    "); + response.getWriter().println("name: " + userInfo.get("name") + "
    "); + response.getWriter().println("email: " + userInfo.get("email") + "
    "); + response.getWriter().println("
    Logout"); + } + else + { + response.getWriter().println("not authenticated"); + response.getWriter().println("
    Login"); + } + } + } + + public static class ErrorPage extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException + { + response.setContentType("text/html"); + response.getWriter().println("not authorized"); + response.getWriter().println("
    Home"); + } + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java new file mode 100644 index 000000000000..c7188e2a8412 --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jetty.client.HttpClient; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class OpenIdCredentialsTest +{ + @Test + public void testSingleAudienceValueInArray() throws Exception + { + String issuer = "myIssuer123"; + String clientId = "myClientId456"; + OpenIdConfiguration configuration = new OpenIdConfiguration(issuer, "", "", clientId, "", new HttpClient()); + + Map claims = new HashMap<>(); + claims.put("iss", issuer); + claims.put("aud", new String[]{clientId}); + claims.put("exp", System.currentTimeMillis() + 5000); + + assertDoesNotThrow(() -> new OpenIdCredentials(claims).redeemAuthCode(configuration)); + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java new file mode 100644 index 000000000000..f54a2485241c --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java @@ -0,0 +1,384 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import java.io.IOException; +import java.io.PrintWriter; +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.util.StringUtil; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.statistic.CounterStatistic; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OpenIdProvider extends ContainerLifeCycle +{ + private static final Logger LOG = LoggerFactory.getLogger(OpenIdProvider.class); + + private static final String CONFIG_PATH = "/.well-known/openid-configuration"; + private static final String AUTH_PATH = "/auth"; + private static final String TOKEN_PATH = "/token"; + private static final String END_SESSION_PATH = "/end_session"; + private final Map issuedAuthCodes = new HashMap<>(); + + protected final String clientId; + protected final String clientSecret; + protected final List redirectUris = new ArrayList<>(); + private final ServerConnector connector; + private final Server server; + private int port = 0; + private String provider; + private User preAuthedUser; + private final CounterStatistic loggedInUsers = new CounterStatistic(); + + public static void main(String[] args) throws Exception + { + String clientId = "CLIENT_ID123"; + String clientSecret = "PASSWORD123"; + int port = 5771; + String redirectUri = "http://localhost:8080/openid/auth"; + + OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret); + openIdProvider.addRedirectUri(redirectUri); + openIdProvider.setPort(port); + openIdProvider.start(); + try + { + openIdProvider.join(); + } + finally + { + openIdProvider.stop(); + } + } + + public OpenIdProvider(String clientId, String clientSecret) + { + this.clientId = clientId; + this.clientSecret = clientSecret; + + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + + ServletContextHandler contextHandler = new ServletContextHandler(); + contextHandler.setContextPath("/"); + contextHandler.addServlet(new ServletHolder(new ConfigServlet()), CONFIG_PATH); + contextHandler.addServlet(new ServletHolder(new AuthEndpoint()), AUTH_PATH); + contextHandler.addServlet(new ServletHolder(new TokenEndpoint()), TOKEN_PATH); + contextHandler.addServlet(new ServletHolder(new EndSessionEndpoint()), END_SESSION_PATH); + server.setHandler(contextHandler); + + addBean(server); + } + + public void join() throws InterruptedException + { + server.join(); + } + + public OpenIdConfiguration getOpenIdConfiguration() + { + String provider = getProvider(); + String authEndpoint = provider + AUTH_PATH; + String tokenEndpoint = provider + TOKEN_PATH; + return new OpenIdConfiguration(provider, authEndpoint, tokenEndpoint, clientId, clientSecret, null); + } + + public CounterStatistic getLoggedInUsers() + { + return loggedInUsers; + } + + @Override + protected void doStart() throws Exception + { + connector.setPort(port); + super.doStart(); + provider = "http://localhost:" + connector.getLocalPort(); + } + + public void setPort(int port) + { + if (isStarted()) + throw new IllegalStateException(); + this.port = port; + } + + public void setUser(User user) + { + this.preAuthedUser = user; + } + + public String getProvider() + { + if (!isStarted() && port == 0) + throw new IllegalStateException("Port of OpenIdProvider not configured"); + return provider; + } + + public void addRedirectUri(String uri) + { + redirectUris.add(uri); + } + + public class AuthEndpoint extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + if (!clientId.equals(req.getParameter("client_id"))) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid client_id"); + return; + } + + String redirectUri = req.getParameter("redirect_uri"); + if (!redirectUris.contains(redirectUri)) + { + LOG.warn("invalid redirectUri {}", redirectUri); + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); + return; + } + + String scopeString = req.getParameter("scope"); + List scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(StringUtil.csvSplit(scopeString)); + if (!scopes.contains("openid")) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no openid scope"); + return; + } + + if (!"code".equals(req.getParameter("response_type"))) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "response_type must be code"); + return; + } + + String state = req.getParameter("state"); + if (state == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); + return; + } + + if (preAuthedUser == null) + { + PrintWriter writer = resp.getWriter(); + resp.setContentType("text/html"); + writer.println("

    Login to OpenID Connect Provider

    "); + writer.println("
    "); + writer.println(""); + writer.println(""); + writer.println(""); + writer.println(""); + writer.println("
    "); + } + else + { + redirectUser(resp, preAuthedUser, redirectUri, state); + } + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + String redirectUri = req.getParameter("redirectUri"); + if (!redirectUris.contains(redirectUri)) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); + return; + } + + String state = req.getParameter("state"); + if (state == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); + return; + } + + String username = req.getParameter("username"); + if (username == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no username"); + return; + } + + User user = new User(username); + redirectUser(resp, user, redirectUri, state); + } + + public void redirectUser(HttpServletResponse response, User user, String redirectUri, String state) throws IOException + { + String authCode = UUID.randomUUID().toString().replace("-", ""); + issuedAuthCodes.put(authCode, user); + + try + { + redirectUri += "?code=" + authCode + "&state=" + state; + response.sendRedirect(response.encodeRedirectURL(redirectUri)); + } + catch (Throwable t) + { + issuedAuthCodes.remove(authCode); + throw t; + } + } + } + + private class TokenEndpoint extends HttpServlet + { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + String code = req.getParameter("code"); + + if (!clientId.equals(req.getParameter("client_id")) || + !clientSecret.equals(req.getParameter("client_secret")) || + !redirectUris.contains(req.getParameter("redirect_uri")) || + !"authorization_code".equals(req.getParameter("grant_type")) || + code == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "bad auth request"); + return; + } + + User user = issuedAuthCodes.remove(code); + if (user == null) + { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid auth code"); + return; + } + + String accessToken = "ABCDEFG"; + long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis(); + String response = "{" + + "\"access_token\": \"" + accessToken + "\"," + + "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId)) + "\"," + + "\"expires_in\": " + expiry + "," + + "\"token_type\": \"Bearer\"" + + "}"; + + loggedInUsers.increment(); + resp.setContentType("text/plain"); + resp.getWriter().print(response); + } + } + + private class EndSessionEndpoint extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + doPost(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + String idToken = req.getParameter("id_token_hint"); + if (idToken == null) + { + resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "no id_token_hint"); + return; + } + + String logoutRedirect = req.getParameter("post_logout_redirect_uri"); + if (logoutRedirect == null) + { + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().println("logout success on end_session_endpoint"); + return; + } + + loggedInUsers.decrement(); + resp.setContentType("text/plain"); + resp.sendRedirect(logoutRedirect); + } + } + + private class ConfigServlet extends HttpServlet + { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + { + String discoveryDocument = "{" + + "\"issuer\": \"" + provider + "\"," + + "\"authorization_endpoint\": \"" + provider + AUTH_PATH + "\"," + + "\"token_endpoint\": \"" + provider + TOKEN_PATH + "\"," + + "\"end_session_endpoint\": \"" + provider + END_SESSION_PATH + "\"," + + "}"; + + resp.getWriter().write(discoveryDocument); + } + } + + public static class User + { + private final String subject; + private final String name; + + public User(String name) + { + this(UUID.nameUUIDFromBytes(name.getBytes()).toString(), name); + } + + public User(String subject, String name) + { + this.subject = subject; + this.name = name; + } + + public String getName() + { + return name; + } + + public String getSubject() + { + return subject; + } + + public String getIdToken(String provider, String clientId) + { + long expiry = System.currentTimeMillis() + Duration.ofMinutes(1).toMillis(); + return JwtEncoder.createIdToken(provider, clientId, subject, name, expiry); + } + + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof User)) + return false; + return Objects.equals(subject, ((User)obj).subject) && Objects.equals(name, ((User)obj).name); + } + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java new file mode 100644 index 000000000000..289288d22922 --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java @@ -0,0 +1,184 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee10.security.openid; + +import org.eclipse.jetty.ee10.servlet.ServletContextHandler; +import org.eclipse.jetty.ee10.servlet.security.Authenticator; +import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; +import org.eclipse.jetty.ee10.servlet.security.LoginService; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.util.security.Constraint; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class OpenIdReamNameTest +{ + private final Server server = new Server(); + + public static ServletContextHandler configureOpenIdContext(String realmName) + { + ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); + securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); + securityHandler.setRealmName(realmName); + ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/" + realmName); + context.setSecurityHandler(securityHandler); + return context; + } + + @Test + public void testSingleConfiguration() throws Exception + { + // Add some OpenID configurations. + OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", + "", "", "", "", null); + server.addBean(config1); + + // Configure two webapps to select configs based on realm name. + ServletContextHandler context1 = configureOpenIdContext("This doesn't matter if only 1 OpenIdConfiguration"); + ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); + contextHandlerCollection.addHandler(context1); + server.setHandler(contextHandlerCollection); + + try + { + server.start(); + + // The OpenIdConfiguration from context1 matches to config1. + Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); + LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); + assertThat(loginService, instanceOf(OpenIdLoginService.class)); + assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); + } + finally + { + server.stop(); + } + } + + @Test + public void testSingleConfigurationNoRealmName() throws Exception + { + // Add some OpenID configurations. + OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", + "", "", "", "", null); + server.addBean(config1); + + // Configure two webapps to select configs based on realm name. + ServletContextHandler context1 = configureOpenIdContext(null); + ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); + contextHandlerCollection.addHandler(context1); + server.setHandler(contextHandlerCollection); + + try + { + server.start(); + + // The OpenIdConfiguration from context1 matches to config1. + Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); + LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); + assertThat(loginService, instanceOf(OpenIdLoginService.class)); + assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); + } + finally + { + server.stop(); + } + } + + @Test + public void testMultipleConfiguration() throws Exception + { + // Add some OpenID configurations. + OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", + "", "", "", "", null); + OpenIdConfiguration config2 = new OpenIdConfiguration("provider2", + "", "", "", "", null); + server.addBean(config1); + server.addBean(config2); + + // Configure two webapps to select configs based on realm name. + ServletContextHandler context1 = configureOpenIdContext(config1.getIssuer()); + ServletContextHandler context2 = configureOpenIdContext(config2.getIssuer()); + ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); + contextHandlerCollection.addHandler(context1); + contextHandlerCollection.addHandler(context2); + server.setHandler(contextHandlerCollection); + + try + { + server.start(); + + // The OpenIdConfiguration from context1 matches to config1. + Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); + LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); + assertThat(loginService, instanceOf(OpenIdLoginService.class)); + assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); + + // The OpenIdConfiguration from context2 matches to config2. + authenticator = context2.getSecurityHandler().getAuthenticator(); + assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); + loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); + assertThat(loginService, instanceOf(OpenIdLoginService.class)); + assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config2)); + } + finally + { + server.stop(); + } + } + + @Test + public void testMultipleConfigurationNoMatch() throws Exception + { + // Add some OpenID configurations. + OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", + "", "", "", "", null); + OpenIdConfiguration config2 = new OpenIdConfiguration("provider2", + "", "", "", "", null); + server.addBean(config1); + server.addBean(config2); + + // Configure two webapps to select configs based on realm name. + ServletContextHandler context1 = configureOpenIdContext("provider3"); + ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); + contextHandlerCollection.addHandler(context1); + server.setHandler(contextHandlerCollection); + + // Multiple OpenIdConfigurations were available and didn't match one based on realm name. + assertThrows(IllegalStateException.class, server::start); + } + + @Test + public void testNoConfiguration() throws Exception + { + ServletContextHandler context1 = configureOpenIdContext(null); + ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); + contextHandlerCollection.addHandler(context1); + server.setHandler(contextHandlerCollection); + + // If no OpenIdConfigurations are present it is bad configuration. + assertThrows(IllegalStateException.class, server::start); + } +} diff --git a/jetty-core/jetty-openid/src/test/resources/jetty-logging.properties b/jetty-core/jetty-openid/src/test/resources/jetty-logging.properties new file mode 100755 index 000000000000..6f21b764f54f --- /dev/null +++ b/jetty-core/jetty-openid/src/test/resources/jetty-logging.properties @@ -0,0 +1,3 @@ +# Jetty Logging using jetty-slf4j-impl +# org.eclipse.jetty.LEVEL=DEBUG +# org.eclipse.jetty.security.openid.LEVEL=DEBUG \ No newline at end of file diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java new file mode 100644 index 000000000000..5d6b4ec89fa6 --- /dev/null +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/WrappedAuthConfiguration.java @@ -0,0 +1,74 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security; + +import java.util.Set; + +import org.eclipse.jetty.security.Authenticator.AuthConfiguration; + +/** + * A wrapper for {@link AuthConfiguration}. This allows you to create a new AuthConfiguration which can + * override a method to change a value from another instance of AuthConfiguration. + */ +public class WrappedAuthConfiguration implements AuthConfiguration +{ + private final AuthConfiguration _configuration; + + public WrappedAuthConfiguration(AuthConfiguration configuration) + { + _configuration = configuration; + } + + @Override + public String getAuthMethod() + { + return _configuration.getAuthMethod(); + } + + @Override + public String getRealmName() + { + return _configuration.getRealmName(); + } + + @Override + public String getParameter(String param) + { + return _configuration.getParameter(param); + } + + @Override + public Set getParameterNames() + { + return _configuration.getParameterNames(); + } + + @Override + public LoginService getLoginService() + { + return _configuration.getLoginService(); + } + + @Override + public IdentityService getIdentityService() + { + return _configuration.getIdentityService(); + } + + @Override + public boolean isSessionRenewedOnAuthentication() + { + return _configuration.isSessionRenewedOnAuthentication(); + } +} diff --git a/jetty-core/pom.xml b/jetty-core/pom.xml index 19b04fbddb5a..bd4e7f442525 100644 --- a/jetty-core/pom.xml +++ b/jetty-core/pom.xml @@ -28,6 +28,7 @@ jetty-jmx jetty-jndi jetty-keystore + jetty-openid jetty-osgi jetty-proxy jetty-quic From 447e54be3df0813e5c43e2506509af8db9e8708e Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 4 Apr 2023 15:24:38 +1000 Subject: [PATCH 024/129] implement OpenID module for jetty-core Signed-off-by: Lachlan Roberts --- .../java/org/eclipse/jetty/http/HttpURI.java | 7 +- jetty-core/jetty-openid/pom.xml | 5 + .../src/main/config/etc/jetty-openid.xml | 2 +- .../src/main/config/modules/openid.mod | 13 +- ....xml => jetty-openid-baseloginservice.xml} | 0 .../src/main/java/module-info.java | 4 +- .../security/openid/JwtDecoder.java | 2 +- .../openid/OpenIdAuthConfiguration.java | 2 +- .../security/openid/OpenIdAuthenticator.java | 170 ++++++---- .../openid/OpenIdAuthenticatorFactory.java | 2 +- .../security/openid/OpenIdConfiguration.java | 2 +- .../security/openid/OpenIdCredentials.java | 2 +- .../security/openid/OpenIdLoginService.java | 2 +- .../security/openid/OpenIdUserIdentity.java | 2 +- .../security/openid/OpenIdUserPrincipal.java | 2 +- ...e10.servlet.security.Authenticator$Factory | 1 - ...lipse.jetty.security.Authenticator$Factory | 1 + .../openid/OpenIdAuthenticationTest.java | 254 -------------- .../security/openid/JwtDecoderTest.java | 2 +- .../security/openid/JwtEncoder.java | 2 +- .../openid/OpenIdAuthenticationTest.java | 318 ++++++++++++++++++ .../openid/OpenIdCredentialsTest.java | 2 +- .../security/openid/OpenIdProvider.java | 203 ++++++----- .../security/openid/OpenIdReamNameTest.java | 41 +-- .../security/AbstractUserAuthentication.java | 4 +- .../jetty/security/Authentication.java | 33 +- .../eclipse/jetty/security/Authenticator.java | 9 +- .../jetty/security/SecurityHandler.java | 25 +- .../DeferredAuthentication.java | 11 + .../authentication/FormAuthenticator.java | 6 +- .../authentication/LoginAuthenticator.java | 2 +- .../security/AuthenticationTestHandler.java | 2 +- .../org/eclipse/jetty/server/Request.java | 7 + .../jetty/session/SimpleSessionHandler.java | 3 + 34 files changed, 671 insertions(+), 472 deletions(-) rename jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml => jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml (95%) rename jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod => jetty-core/jetty-openid/src/main/config/modules/openid.mod (84%) rename jetty-core/jetty-openid/src/main/config/modules/openid/{jetty-ee10-openid-baseloginservice.xml => jetty-openid-baseloginservice.xml} (100%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/JwtDecoder.java (98%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdAuthConfiguration.java (97%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdAuthenticator.java (85%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdAuthenticatorFactory.java (98%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdConfiguration.java (99%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdCredentials.java (99%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdLoginService.java (99%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdUserIdentity.java (96%) rename jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdUserPrincipal.java (96%) delete mode 100644 jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory create mode 100644 jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory delete mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java rename jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/{ee10 => }/security/openid/JwtDecoderTest.java (99%) rename jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/{ee10 => }/security/openid/JwtEncoder.java (97%) create mode 100644 jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java rename jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdCredentialsTest.java (96%) rename jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdProvider.java (53%) rename jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/{ee10 => }/security/openid/OpenIdReamNameTest.java (79%) diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java index 3f054f18211a..2db688d24e24 100644 --- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java +++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.http; +import java.io.Serial; +import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; import java.util.Collection; @@ -266,8 +268,11 @@ default URI toURI() } } - class Immutable implements HttpURI + class Immutable implements HttpURI, Serializable { + @Serial + private static final long serialVersionUID = 2245620284548399386L; + private final String _scheme; private final String _user; private final String _host; diff --git a/jetty-core/jetty-openid/pom.xml b/jetty-core/jetty-openid/pom.xml index 7b6a431956eb..57d444db8761 100644 --- a/jetty-core/jetty-openid/pom.xml +++ b/jetty-core/jetty-openid/pom.xml @@ -59,6 +59,11 @@ org.slf4j slf4j-api + + org.eclipse.jetty + jetty-session + test + org.eclipse.jetty jetty-slf4j-impl diff --git a/jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml b/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml similarity index 95% rename from jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml rename to jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml index 085915563ad7..e8e3881cef9e 100644 --- a/jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml +++ b/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml @@ -27,7 +27,7 @@ - + diff --git a/jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod b/jetty-core/jetty-openid/src/main/config/modules/openid.mod similarity index 84% rename from jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod rename to jetty-core/jetty-openid/src/main/config/modules/openid.mod index d0779b6d3557..0225276bfd08 100644 --- a/jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod +++ b/jetty-core/jetty-openid/src/main/config/modules/openid.mod @@ -3,23 +3,20 @@ [description] Adds OpenId Connect authentication to the server. -[environment] -ee10 - [depend] -ee10-security +security client [lib] lib/jetty-util-ajax-${jetty.version}.jar -lib/jetty-ee10-openid-${jetty.version}.jar +lib/jetty-openid-${jetty.version}.jar [files] -basehome:modules/openid/jetty-ee10-openid-baseloginservice.xml|etc/jetty-ee10-openid-baseloginservice.xml +basehome:modules/openid/jetty-openid-baseloginservice.xml|etc/jetty-openid-baseloginservice.xml [xml] -etc/jetty-ee10-openid-baseloginservice.xml -etc/jetty-ee10-openid.xml +etc/jetty-openid-baseloginservice.xml +etc/jetty-openid.xml [ini-template] ## The OpenID Identity Provider's issuer ID (the entire URL *before* ".well-known/openid-configuration") diff --git a/jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml b/jetty-core/jetty-openid/src/main/config/modules/openid/jetty-openid-baseloginservice.xml similarity index 100% rename from jetty-core/jetty-openid/src/main/config/modules/openid/jetty-ee10-openid-baseloginservice.xml rename to jetty-core/jetty-openid/src/main/config/modules/openid/jetty-openid-baseloginservice.xml diff --git a/jetty-core/jetty-openid/src/main/java/module-info.java b/jetty-core/jetty-openid/src/main/java/module-info.java index a735a9de65f4..df8f012bef3c 100644 --- a/jetty-core/jetty-openid/src/main/java/module-info.java +++ b/jetty-core/jetty-openid/src/main/java/module-info.java @@ -11,8 +11,8 @@ // ======================================================================== // -import org.eclipse.jetty.ee10.security.openid.OpenIdAuthenticatorFactory; import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.openid.OpenIdAuthenticatorFactory; module org.eclipse.jetty.security.openid { @@ -22,7 +22,7 @@ requires transitive org.eclipse.jetty.security; requires org.slf4j; - exports org.eclipse.jetty.ee10.security.openid; + exports org.eclipse.jetty.security.openid; provides Authenticator.Factory with OpenIdAuthenticatorFactory; } diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java similarity index 98% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java index 0f86bfc60e4e..1b485021be80 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/JwtDecoder.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.nio.charset.StandardCharsets; import java.util.Arrays; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthConfiguration.java similarity index 97% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthConfiguration.java index 3d8f251b38b3..eb2c23445a42 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthConfiguration.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.LoginService; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java similarity index 85% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java index 62b6fa102f88..78446e4a8674 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.io.IOException; import java.io.Serializable; @@ -248,10 +248,10 @@ public UserIdentity login(String username, Object credentials, Request request, } @Override - public void logout(Request request) + public void logout(Request request, Response response) { attemptLogoutRedirect(request, response); - super.logout(request); + super.logout(request, response); Session session = request.getSession(false); if (session == null) @@ -285,11 +285,12 @@ private void attemptLogoutRedirect(Request request, Response response) String redirectUri = null; if (_logoutRedirectPath != null) { - StringBuilder sb = new StringBuilder(128); - URIUtil.appendSchemeHostPort(sb, request.getHttpURI().getScheme(), Request.getServerName(request), Request.getServerPort(request)); - sb.append(Request.getContextPath(request)); - sb.append(_logoutRedirectPath); - redirectUri = sb.toString(); + HttpURI.Mutable httpURI = HttpURI.build() + .scheme(request.getHttpURI().getScheme()) + .host(Request.getServerName(request)) + .port(Request.getServerPort(request)) + .path(URIUtil.compactPath(Request.getContextPath(request) + _logoutRedirectPath)); + redirectUri = httpURI.toString(); } Session session = request.getSession(false); @@ -330,50 +331,45 @@ private void sendRedirect(Request request, Response response, String location) t } @Override - public Request prepareRequest(Request request) + public Request prepareRequest(Request request, Authentication authentication) { - //if this is a request resulting from a redirect after auth is complete - //(ie its from a redirect to the original request uri) then due to - //browser handling of 302 redirects, the method may not be the same as - //that of the original request. Replace the method and original post - //params (if it was a post). - // - //See Servlet Spec 3.1 sec 13.6.3 - Session session = request.getSession(false); - if (session == null) - return request; //not authenticated yet - - HttpURI juri; - String method; - synchronized (session) + // if this is a request resulting from a redirect after auth is complete + // (ie its from a redirect to the original request uri) then due to + // browser handling of 302 redirects, the method may not be the same as + // that of the original request. Replace the method and original post + // params (if it was a post). + if (authentication instanceof Authentication.User) { - if (session.getAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE) == null) + Session session = request.getSession(false); + if (session == null) return request; //not authenticated yet - juri = (HttpURI)session.getAttribute(J_URI); - if (juri == null) - return request; //no original uri saved - - method = (String)session.getAttribute(J_METHOD); - if (method == null || method.length() == 0) - return request; //didn't save original request method - } - - if (!juri.equals(request.getHttpURI())) - return request; //this request is not for the same url as the original + HttpURI juri = (HttpURI)session.getAttribute(J_URI); + HttpURI uri = request.getHttpURI(); + if ((uri.equals(juri))) + { + session.removeAttribute(J_URI); - // Restore the original request's method on this request. - if (LOG.isDebugEnabled()) - LOG.debug("Restoring original method {} for {} with method {}", method, juri, request.getMethod()); + Fields fields = (Fields)session.removeAttribute(J_POST); + if (fields != null) + request.setAttribute(FormFields.class.getName(), fields); - return new Request.Wrapper(request) - { - @Override - public String getMethod() - { - return method; + String method = (String)session.removeAttribute(J_METHOD); + if (method != null && request.getMethod().equals(method)) + { + return new Request.Wrapper(request) + { + @Override + public String getMethod() + { + return method; + } + }; + } } - }; + } + + return request; } protected Fields getParameters(Request request) @@ -391,26 +387,38 @@ protected Fields getParameters(Request request) } @Override - public Authentication validateRequest(Request request, Response response, Callback cb, boolean mandatory) throws ServerAuthException + public boolean isMandatory(Request request, Response response, boolean mandatory) { - if (LOG.isDebugEnabled()) - LOG.debug("validateRequest({},{},{})", request, response, mandatory); - String uri = request.getHttpURI().toString(); if (uri == null) uri = "/"; - mandatory |= isJSecurityCheck(uri); - if (!mandatory) - return new DeferredAuthentication(this); - + if (isJSecurityCheck(uri)) + return true; if (isErrorPage(Request.getPathInContext(request)) && !DeferredAuthentication.isDeferred(response)) - return new DeferredAuthentication(this); + return false; + return mandatory; + } + + @Override + public Authentication validateRequest(Request request, Response response, Callback cb) throws ServerAuthException + { + if (LOG.isDebugEnabled()) + LOG.debug("validateRequest({},{})", request, response); + + String uri = request.getHttpURI().toString(); + if (uri == null) + uri = "/"; try { // Get the Session. Session session = request.getSession(true); + if (session == null) + { + sendError(request, response, cb, "session could not be created"); + return Authentication.SEND_FAILURE; + } // TODO: No session API to work this out? /* @@ -467,6 +475,7 @@ public Authentication validateRequest(Request request, Response response, Callba // Save redirect info in session so original request can be restored after redirect. synchronized (session) { + // TODO: We are duplicating this logic. session.setAttribute(J_URI, uriRedirectInfo.getUri()); session.setAttribute(J_METHOD, uriRedirectInfo.getMethod()); session.setAttribute(J_POST, uriRedirectInfo.getFormParameters()); @@ -476,7 +485,7 @@ public Authentication validateRequest(Request request, Response response, Callba response.getHeaders().putLongField(HttpHeader.CONTENT_LENGTH, 0); int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpStatus.MOVED_TEMPORARILY_302 : HttpStatus.SEE_OTHER_303; - Response.sendRedirect(request, response, cb, redirectCode, uriRedirectInfo.getUri(), true); + Response.sendRedirect(request, response, cb, redirectCode, uriRedirectInfo.getUri().toString(), true); return openIdAuth; } @@ -534,18 +543,46 @@ public Authentication validateRequest(Request request, Response response, Callba { if (LOG.isDebugEnabled()) LOG.debug("auth deferred {}", session.getId()); - return Authentication.UNAUTHENTICATED; + return null; + } + + // Save the current URI + synchronized (session) + { + // But only if it is not set already, or we save every uri that leads to a login form redirect + if (session.getAttribute(J_URI) == null || _alwaysSaveUri) + { + HttpURI juri = request.getHttpURI(); + session.setAttribute(J_URI, juri); + if (!HttpMethod.GET.is(request.getMethod())) + session.setAttribute(J_METHOD, request.getMethod()); + + if (HttpMethod.POST.is(request.getMethod())) + { + try + { + session.setAttribute(J_POST, FormFields.from(request).get()); + } + catch (ExecutionException e) + { + throw new ServerAuthException(e.getCause()); + } + catch (InterruptedException e) + { + throw new ServerAuthException(e); + } + } + } } - // Send the the challenge. + // Send the challenge. String challengeUri = getChallengeUri(request); if (LOG.isDebugEnabled()) LOG.debug("challenge {}->{}", session.getId(), challengeUri); int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() ? HttpStatus.MOVED_TEMPORARILY_302 : HttpStatus.SEE_OTHER_303; Response.sendRedirect(request, response, cb, redirectCode, challengeUri, true); - - return Authentication.SEND_CONTINUE; + return Authentication.CHALLENGE; } catch (IOException e) { @@ -579,15 +616,16 @@ private void sendError(Request request, Response response, Callback callback, St if (LOG.isDebugEnabled()) LOG.debug("auth failed {}", _errorPage); - String redirectUri = URIUtil.addPaths(httpServletRequest.getContextPath(), _errorPage); + String contextPath = Request.getContextPath(request); + String redirectUri = URIUtil.addPaths(contextPath, _errorPage); if (message != null) { String query = URIUtil.addQueries(ERROR_PARAMETER + "=" + UrlEncoded.encodeString(message), _errorQuery); - redirectUri = URIUtil.addPathQuery(URIUtil.addPaths(httpServletRequest.getContextPath(), _errorPath), query); + redirectUri = URIUtil.addPathQuery(URIUtil.addPaths(contextPath, _errorPath), query); } int redirectCode = request.getConnectionMetaData().getHttpVersion().getVersion() < HttpVersion.HTTP_1_1.getVersion() - ? HttpServletResponse.SC_MOVED_TEMPORARILY : HttpServletResponse.SC_SEE_OTHER; + ? HttpStatus.MOVED_TEMPORARILY_302 : HttpStatus.SEE_OTHER_303; Response.sendRedirect(request, response, callback, redirectCode, redirectUri, true); } } @@ -645,12 +683,6 @@ protected String getChallengeUri(Request request) "&response_type=code"; } - @Override - public boolean secureResponse(Request req, Response res, Callback callback, boolean mandatory, Authentication.User validatedUser) throws ServerAuthException - { - return req.isSecure(); - } - private UriRedirectInfo removeAndClearCsrfMap(Session session, String csrf) { @SuppressWarnings("unchecked") @@ -703,7 +735,7 @@ private static class UriRedirectInfo implements Serializable public UriRedirectInfo(Request request) { - _uri = request.getHttpURI().asString(); + _uri = request.getHttpURI(); _method = request.getMethod(); // TODO: diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java similarity index 98% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java index 07af42975325..504183d429e1 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.Collection; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java similarity index 99% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java index 0997f5081f64..502bc9cb54b8 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdConfiguration.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.ArrayList; import java.util.Collections; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java similarity index 99% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java index 81616eede805..a5dfa9508bc8 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdCredentials.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.io.Serializable; import java.net.URI; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java similarity index 99% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java index a17fb0a8bbd5..9e2b75928228 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.Objects; import javax.security.auth.Subject; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java similarity index 96% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java index c1c29d2febad..006bf4f616fa 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserIdentity.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.security.Principal; import javax.security.auth.Subject; diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java similarity index 96% rename from jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java rename to jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java index f5598de1c6cb..6be4a0e77e71 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdUserPrincipal.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.io.Serializable; import java.security.Principal; diff --git a/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory b/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory deleted file mode 100644 index da9c63a7ec01..000000000000 --- a/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.ee10.servlet.security.Authenticator$Factory +++ /dev/null @@ -1 +0,0 @@ -org.eclipse.jetty.ee10.security.openid.OpenIdAuthenticatorFactory diff --git a/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory b/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory new file mode 100644 index 000000000000..5f55fc49ebc2 --- /dev/null +++ b/jetty-core/jetty-openid/src/main/resources/META-INF/services/org.eclipse.jetty.security.Authenticator$Factory @@ -0,0 +1 @@ +org.eclipse.jetty.security.openid.OpenIdAuthenticatorFactory diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java deleted file mode 100644 index 805b62befd9b..000000000000 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java +++ /dev/null @@ -1,254 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee10.security.openid; - -import java.io.File; -import java.io.IOException; -import java.security.Principal; -import java.util.Map; - -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.client.ContentResponse; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.security.ConstraintMapping; -import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; -import org.eclipse.jetty.http.HttpStatus; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.session.FileSessionDataStoreFactory; -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.security.Constraint; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.is; - -@SuppressWarnings("unchecked") -public class OpenIdAuthenticationTest -{ - public static final String CLIENT_ID = "testClient101"; - public static final String CLIENT_SECRET = "secret37989798"; - - private OpenIdProvider openIdProvider; - private Server server; - private ServerConnector connector; - private HttpClient client; - - @BeforeEach - public void setup() throws Exception - { - openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); - openIdProvider.start(); - - server = new Server(); - connector = new ServerConnector(server); - server.addConnector(connector); - ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); - - // Add servlets - context.addServlet(LoginPage.class, "/login"); - context.addServlet(LogoutPage.class, "/logout"); - context.addServlet(HomePage.class, "/*"); - context.addServlet(ErrorPage.class, "/error"); - - // configure security constraints - Constraint constraint = new Constraint(); - constraint.setName(Constraint.__OPENID_AUTH); - constraint.setRoles(new String[]{"**"}); - constraint.setAuthenticate(true); - - Constraint adminConstraint = new Constraint(); - adminConstraint.setName(Constraint.__OPENID_AUTH); - adminConstraint.setRoles(new String[]{"admin"}); - adminConstraint.setAuthenticate(true); - - // constraint mappings - ConstraintMapping profileMapping = new ConstraintMapping(); - profileMapping.setConstraint(constraint); - profileMapping.setPathSpec("/profile"); - ConstraintMapping loginMapping = new ConstraintMapping(); - loginMapping.setConstraint(constraint); - loginMapping.setPathSpec("/login"); - ConstraintMapping adminMapping = new ConstraintMapping(); - adminMapping.setConstraint(adminConstraint); - adminMapping.setPathSpec("/admin"); - - // security handler - ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); - assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); - - securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); - securityHandler.setRealmName(openIdProvider.getProvider()); - securityHandler.addConstraintMapping(profileMapping); - securityHandler.addConstraintMapping(loginMapping); - securityHandler.addConstraintMapping(adminMapping); - - // Authentication using local OIDC Provider - server.addBean(new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET)); - securityHandler.setInitParameter(OpenIdAuthenticator.REDIRECT_PATH, "/redirect_path"); - securityHandler.setInitParameter(OpenIdAuthenticator.ERROR_PAGE, "/error"); - securityHandler.setInitParameter(OpenIdAuthenticator.LOGOUT_REDIRECT_PATH, "/"); - context.setSecurityHandler(securityHandler); - - File datastoreDir = MavenTestingUtils.getTargetTestingDir("datastore"); - IO.delete(datastoreDir); - FileSessionDataStoreFactory fileSessionDataStoreFactory = new FileSessionDataStoreFactory(); - fileSessionDataStoreFactory.setStoreDir(datastoreDir); - server.addBean(fileSessionDataStoreFactory); - - server.start(); - String redirectUri = "http://localhost:" + connector.getLocalPort() + "/redirect_path"; - openIdProvider.addRedirectUri(redirectUri); - - client = new HttpClient(); - client.start(); - } - - @AfterEach - public void stop() throws Exception - { - openIdProvider.stop(); - server.stop(); - } - - @Test - public void testLoginLogout() throws Exception - { - openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); - - String appUriString = "http://localhost:" + connector.getLocalPort(); - - // Initially not authenticated - ContentResponse response = client.GET(appUriString + "/"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); - String content = response.getContentAsString(); - assertThat(content, containsString("not authenticated")); - - // Request to login is success - response = client.GET(appUriString + "/login"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); - content = response.getContentAsString(); - assertThat(content, containsString("success")); - - // Now authenticated we can get info - response = client.GET(appUriString + "/"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); - content = response.getContentAsString(); - assertThat(content, containsString("userId: 123456789")); - assertThat(content, containsString("name: Alice")); - assertThat(content, containsString("email: Alice@example.com")); - - // Request to admin page gives 403 as we do not have admin role - response = client.GET(appUriString + "/admin"); - assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403)); - - // We can restart the server and still be logged in as we have persistent session datastore. - server.stop(); - server.start(); - appUriString = "http://localhost:" + connector.getLocalPort(); - - // After restarting server the authentication is saved as a session authentication. - response = client.GET(appUriString + "/"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); - content = response.getContentAsString(); - assertThat(content, containsString("userId: 123456789")); - assertThat(content, containsString("name: Alice")); - assertThat(content, containsString("email: Alice@example.com")); - - // We are no longer authenticated after logging out - response = client.GET(appUriString + "/logout"); - assertThat(response.getStatus(), is(HttpStatus.OK_200)); - content = response.getContentAsString(); - assertThat(content, containsString("not authenticated")); - - // Test that the user was logged out successfully on the openid provider. - assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(0L)); - assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); - assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); - } - - public static class LoginPage extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { - response.setContentType("text/html"); - response.getWriter().println("success"); - response.getWriter().println("
    Home"); - } - } - - public static class LogoutPage extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - request.logout(); - } - } - - public static class AdminPage extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { - Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); - response.getWriter().println(userInfo.get("sub") + ": success"); - } - } - - public static class HomePage extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { - response.setContentType("text/html"); - Principal userPrincipal = request.getUserPrincipal(); - if (userPrincipal != null) - { - Map userInfo = (Map)request.getSession().getAttribute(OpenIdAuthenticator.CLAIMS); - response.getWriter().println("userId: " + userInfo.get("sub") + "
    "); - response.getWriter().println("name: " + userInfo.get("name") + "
    "); - response.getWriter().println("email: " + userInfo.get("email") + "
    "); - response.getWriter().println("
    Logout"); - } - else - { - response.getWriter().println("not authenticated"); - response.getWriter().println("
    Login"); - } - } - } - - public static class ErrorPage extends HttpServlet - { - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException - { - response.setContentType("text/html"); - response.getWriter().println("not authorized"); - response.getWriter().println("
    Home"); - } - } -} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java similarity index 99% rename from jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java rename to jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java index 7a99cbf02cf3..b343b222e52e 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtDecoderTest.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.Map; import java.util.stream.Stream; diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java similarity index 97% rename from jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java rename to jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java index 2e8930c9b97b..928a51fd8224 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/JwtEncoder.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.Base64; diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java new file mode 100644 index 000000000000..5049dc54ecc0 --- /dev/null +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java @@ -0,0 +1,318 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.security.openid; + +import java.io.File; +import java.io.PrintStream; +import java.security.Principal; +import java.util.Map; + +import org.eclipse.jetty.client.ContentResponse; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.Constraint; +import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.session.FileSessionDataStoreFactory; +import org.eclipse.jetty.session.SimpleSessionHandler; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.IO; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.is; + +@SuppressWarnings("unchecked") +public class OpenIdAuthenticationTest +{ + public static final String CLIENT_ID = "testClient101"; + public static final String CLIENT_SECRET = "secret37989798"; + + private OpenIdProvider openIdProvider; + private Server server; + private ServerConnector connector; + private HttpClient client; + + @BeforeEach + public void setup() throws Exception + { + server = new Server(); + connector = new ServerConnector(server); + server.addConnector(connector); + + // Set up a local OIDC provider and add its configuration to the Server. + openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); + openIdProvider.start(); + server.addBean(new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET)); + + // Configure SecurityHandler. + SecurityHandler.Mapped securityHandler = new SecurityHandler.Mapped(); + assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); + securityHandler.setAuthMethod(Authenticator.OPENID_AUTH); + securityHandler.setRealmName(openIdProvider.getProvider()); + + // Configure Contexts. + ContextHandlerCollection contexts = new ContextHandlerCollection(); + securityHandler.setHandler(contexts); + SimpleSessionHandler sessionHandler = new SimpleSessionHandler(); + sessionHandler.setHandler(securityHandler); + ContextHandler contextHandler = new ContextHandler(); + contextHandler.setHandler(sessionHandler); + server.setHandler(contextHandler); + contexts.addHandler(new LoginPage("/login")); + contexts.addHandler(new LogoutPage("/logout")); + contexts.addHandler(new HomePage("/")); + contexts.addHandler(new ErrorPage("/error")); + + // Configure security constraints. + securityHandler.put("/login", Constraint.AUTHENTICATED); + securityHandler.put("/profile", Constraint.AUTHENTICATED); + securityHandler.put("/admin", Constraint.from("admin")); + + // Configure Jetty to use the local OIDC provider we have previously configured. + securityHandler.setParameter(OpenIdAuthenticator.REDIRECT_PATH, "/redirect_path"); + securityHandler.setParameter(OpenIdAuthenticator.ERROR_PAGE, "/error"); + securityHandler.setParameter(OpenIdAuthenticator.LOGOUT_REDIRECT_PATH, "/"); + + File datastoreDir = MavenTestingUtils.getTargetTestingDir("datastore"); + IO.delete(datastoreDir); + FileSessionDataStoreFactory fileSessionDataStoreFactory = new FileSessionDataStoreFactory(); + fileSessionDataStoreFactory.setStoreDir(datastoreDir); + server.addBean(fileSessionDataStoreFactory); + + // Start the server and add the Servers RedirectURI to the Provider. + server.start(); + String redirectUri = "http://localhost:" + connector.getLocalPort() + "/redirect_path"; + openIdProvider.addRedirectUri(redirectUri); + + client = new HttpClient(); + client.start(); + } + + @AfterEach + public void stop() throws Exception + { + openIdProvider.stop(); + server.stop(); + } + + @Test + public void testLoginLogout() throws Exception + { + openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); + + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Request to log in is success. + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("success")); + + // Now authenticated we can get info + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // Request to admin page gives 403 as we do not have admin role + response = client.GET(appUriString + "/admin"); + assertThat(response.getStatus(), is(HttpStatus.FORBIDDEN_403)); + + // We can restart the server and still be logged in as we have persistent session datastore. + server.stop(); + server.start(); + appUriString = "http://localhost:" + connector.getLocalPort(); + + // After restarting server the authentication is saved as a session authentication. + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // We are no longer authenticated after logging out + response = client.GET(appUriString + "/logout"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Test that the user was logged out successfully on the openid provider. + assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(0L)); + assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); + } + + public static class LoginPage extends ContextHandler + { + public LoginPage(String contextPath) + { + super(contextPath); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); + try (PrintStream output = new PrintStream(Content.Sink.asOutputStream(response))) + { + output.println("success"); + output.println("
    Home"); + output.close(); + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + + return true; + } + } + + public static class LogoutPage extends ContextHandler + { + public LogoutPage(String contextPath) + { + super(contextPath); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + Authentication.logout(request, response); + callback.succeeded(); + return true; + } + } + + public static class AdminPage extends ContextHandler + { + public AdminPage(String contextPath) + { + super(contextPath); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); + try (PrintStream output = new PrintStream(Content.Sink.asOutputStream(response))) + { + Map userInfo = (Map)request.getSession(false).getAttribute(OpenIdAuthenticator.CLAIMS); + output.println(userInfo.get("sub") + ": success"); + output.close(); + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + + return true; + } + } + + public static class HomePage extends ContextHandler + { + public HomePage(String contextPath) + { + super(contextPath); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); + + try (PrintStream output = new PrintStream(Content.Sink.asOutputStream(response))) + { + Principal userPrincipal = Authentication.getUserPrincipal(request); + if (userPrincipal != null) + { + Map userInfo = (Map)request.getSession(false).getAttribute(OpenIdAuthenticator.CLAIMS); + output.println("userId: " + userInfo.get("sub") + "
    "); + output.println("name: " + userInfo.get("name") + "
    "); + output.println("email: " + userInfo.get("email") + "
    "); + output.println("
    Logout"); + } + else + { + output.println("not authenticated"); + output.println("
    Login"); + } + + output.close(); + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + + return true; + } + } + + public static class ErrorPage extends ContextHandler + { + public ErrorPage(String contextPath) + { + super(contextPath); + } + + @Override + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); + try (PrintStream output = new PrintStream(Content.Sink.asOutputStream(response))) + { + output.println("not authorized"); + output.println("
    Home"); + output.close(); + callback.succeeded(); + } + catch (Throwable t) + { + callback.failed(t); + } + + return true; + } + } +} diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdCredentialsTest.java similarity index 96% rename from jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java rename to jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdCredentialsTest.java index c7188e2a8412..961b01d30e1d 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdCredentialsTest.java @@ -11,7 +11,7 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.util.HashMap; import java.util.Map; diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java similarity index 53% rename from jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java rename to jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java index f54a2485241c..acce4fc03e34 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java @@ -11,10 +11,9 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; import java.io.IOException; -import java.io.PrintWriter; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; @@ -25,14 +24,18 @@ import java.util.Objects; import java.util.UUID; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.ServletHolder; +import org.eclipse.jetty.http.BadMessageException; +import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.util.BufferUtil; +import org.eclipse.jetty.util.Callback; +import org.eclipse.jetty.util.Fields; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.statistic.CounterStatistic; @@ -89,13 +92,12 @@ public OpenIdProvider(String clientId, String clientSecret) connector = new ServerConnector(server); server.addConnector(connector); - ServletContextHandler contextHandler = new ServletContextHandler(); - contextHandler.setContextPath("/"); - contextHandler.addServlet(new ServletHolder(new ConfigServlet()), CONFIG_PATH); - contextHandler.addServlet(new ServletHolder(new AuthEndpoint()), AUTH_PATH); - contextHandler.addServlet(new ServletHolder(new TokenEndpoint()), TOKEN_PATH); - contextHandler.addServlet(new ServletHolder(new EndSessionEndpoint()), END_SESSION_PATH); - server.setHandler(contextHandler); + ContextHandlerCollection contexts = new ContextHandlerCollection(); + contexts.addHandler(new ConfigServlet(CONFIG_PATH)); + contexts.addHandler(new AuthEndpoint(AUTH_PATH)); + contexts.addHandler(new TokenEndpoint(TOKEN_PATH)); + contexts.addHandler(new EndSessionEndpoint(END_SESSION_PATH)); + server.setHandler(contexts); addBean(server); } @@ -150,93 +152,118 @@ public void addRedirectUri(String uri) redirectUris.add(uri); } - public class AuthEndpoint extends HttpServlet + public class AuthEndpoint extends ContextHandler { + public AuthEndpoint(String contextPath) + { + super(contextPath); + } + @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + public boolean handle(Request request, Response response, Callback callback) throws Exception + { + switch (request.getMethod()) + { + case "GET": + doGet(request, response, callback); + break; + case "POST": + doPost(request, response, callback); + break; + default: + throw new BadMessageException("Unsupported HTTP Method"); + } + + return true; + } + + protected void doGet(Request request, Response response, Callback callback) throws Exception { - if (!clientId.equals(req.getParameter("client_id"))) + Fields parameters = Request.getParameters(request); + if (!clientId.equals(parameters.getValue("client_id"))) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid client_id"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid client_id"); return; } - String redirectUri = req.getParameter("redirect_uri"); + String redirectUri = parameters.getValue("redirect_uri"); if (!redirectUris.contains(redirectUri)) { - LOG.warn("invalid redirectUri {}", redirectUri); - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid redirect_uri"); return; } - String scopeString = req.getParameter("scope"); + String scopeString = parameters.getValue("scope"); List scopes = (scopeString == null) ? Collections.emptyList() : Arrays.asList(StringUtil.csvSplit(scopeString)); if (!scopes.contains("openid")) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no openid scope"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no openid scope"); return; } - if (!"code".equals(req.getParameter("response_type"))) + if (!"code".equals(parameters.getValue("response_type"))) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "response_type must be code"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "response_type must be code"); return; } - String state = req.getParameter("state"); + String state = parameters.getValue("state"); if (state == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no state param"); return; } if (preAuthedUser == null) { - PrintWriter writer = resp.getWriter(); - resp.setContentType("text/html"); - writer.println("

    Login to OpenID Connect Provider

    "); - writer.println("
    "); - writer.println(""); - writer.println(""); - writer.println(""); - writer.println(""); - writer.println("
    "); + response.getHeaders().add(HttpHeader.CONTENT_TYPE, "text/html"); + + String content = + "

    Login to OpenID Connect Provider

    " + + "
    " + + "" + + "" + + "" + + "" + + "
    "; + response.write(true, BufferUtil.toBuffer(content), callback); } else { - redirectUser(resp, preAuthedUser, redirectUri, state); + redirectUser(request, response, callback, preAuthedUser, redirectUri, state); } } - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException + protected void doPost(Request request, Response response, Callback callback) throws Exception { - String redirectUri = req.getParameter("redirectUri"); + Fields parameters = Request.getParameters(request); + + String redirectUri = parameters.getValue("redirectUri"); if (!redirectUris.contains(redirectUri)) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid redirect_uri"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid redirect_uri"); return; } - String state = req.getParameter("state"); + String state = parameters.getValue("state"); if (state == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no state param"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no state param"); return; } - String username = req.getParameter("username"); + String username = parameters.getValue("username"); if (username == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "no username"); + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "no username"); return; } User user = new User(username); - redirectUser(resp, user, redirectUri, state); + redirectUser(request, response, callback, user, redirectUri, state); } - public void redirectUser(HttpServletResponse response, User user, String redirectUri, String state) throws IOException + public void redirectUser(Request request, Response response, Callback callback, User user, String redirectUri, String state) throws IOException { String authCode = UUID.randomUUID().toString().replace("-", ""); issuedAuthCodes.put(authCode, user); @@ -244,7 +271,7 @@ public void redirectUser(HttpServletResponse response, User user, String redirec try { redirectUri += "?code=" + authCode + "&state=" + state; - response.sendRedirect(response.encodeRedirectURL(redirectUri)); + Response.sendRedirect(request, response, callback, redirectUri); } catch (Throwable t) { @@ -254,33 +281,40 @@ public void redirectUser(HttpServletResponse response, User user, String redirec } } - private class TokenEndpoint extends HttpServlet + private class TokenEndpoint extends ContextHandler { + public TokenEndpoint(String contextPath) + { + super(contextPath); + } + @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + public boolean handle(Request request, Response response, Callback callback) throws Exception { - String code = req.getParameter("code"); + Fields parameters = Request.getParameters(request); + + String code = parameters.getValue("code"); - if (!clientId.equals(req.getParameter("client_id")) || - !clientSecret.equals(req.getParameter("client_secret")) || - !redirectUris.contains(req.getParameter("redirect_uri")) || - !"authorization_code".equals(req.getParameter("grant_type")) || + if (!clientId.equals(parameters.getValue("client_id")) || + !clientSecret.equals(parameters.getValue("client_secret")) || + !redirectUris.contains(parameters.getValue("redirect_uri")) || + !"authorization_code".equals(parameters.getValue("grant_type")) || code == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "bad auth request"); - return; + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "bad auth request"); + return true; } User user = issuedAuthCodes.remove(code); if (user == null) { - resp.sendError(HttpServletResponse.SC_FORBIDDEN, "invalid auth code"); - return; + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "invalid auth code"); + return true; } String accessToken = "ABCDEFG"; long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis(); - String response = "{" + + String content = "{" + "\"access_token\": \"" + accessToken + "\"," + "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId)) + "\"," + "\"expires_in\": " + expiry + "," + @@ -288,47 +322,55 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S "}"; loggedInUsers.increment(); - resp.setContentType("text/plain"); - resp.getWriter().print(response); + response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain"); + response.write(true, BufferUtil.toBuffer(content), callback); + return true; } } - private class EndSessionEndpoint extends HttpServlet + private class EndSessionEndpoint extends ContextHandler { - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + public EndSessionEndpoint(String contextPath) { - doPost(req, resp); + super(contextPath); } @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException + public boolean handle(Request request, Response response, Callback callback) throws Exception { - String idToken = req.getParameter("id_token_hint"); + Fields parameters = Request.getParameters(request); + + String idToken = parameters.getValue("id_token_hint"); if (idToken == null) { - resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "no id_token_hint"); - return; + Response.writeError(request, response, callback, HttpStatus.BAD_REQUEST_400, "no id_token_hint"); + return true; } - String logoutRedirect = req.getParameter("post_logout_redirect_uri"); + String logoutRedirect = parameters.getValue("post_logout_redirect_uri"); if (logoutRedirect == null) { - resp.setStatus(HttpServletResponse.SC_OK); - resp.getWriter().println("logout success on end_session_endpoint"); - return; + response.setStatus(HttpStatus.OK_200); + response.write(true, BufferUtil.toBuffer("logout success on end_session_endpoint"), callback); + return true; } loggedInUsers.decrement(); - resp.setContentType("text/plain"); - resp.sendRedirect(logoutRedirect); + response.getHeaders().put(HttpHeader.CONTENT_TYPE, "text/plain"); + Response.sendRedirect(request, response, callback, logoutRedirect); + return true; } } - private class ConfigServlet extends HttpServlet + private class ConfigServlet extends ContextHandler { + public ConfigServlet(String contextPath) + { + super(contextPath); + } + @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException + public boolean handle(Request request, Response response, Callback callback) throws Exception { String discoveryDocument = "{" + "\"issuer\": \"" + provider + "\"," + @@ -337,7 +379,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO "\"end_session_endpoint\": \"" + provider + END_SESSION_PATH + "\"," + "}"; - resp.getWriter().write(discoveryDocument); + response.write(true, BufferUtil.toBuffer(discoveryDocument), callback); + return true; } } diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdReamNameTest.java similarity index 79% rename from jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java rename to jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdReamNameTest.java index 289288d22922..ab55e156ccef 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdReamNameTest.java @@ -11,15 +11,13 @@ // ======================================================================== // -package org.eclipse.jetty.ee10.security.openid; +package org.eclipse.jetty.security.openid; -import org.eclipse.jetty.ee10.servlet.ServletContextHandler; -import org.eclipse.jetty.ee10.servlet.security.Authenticator; -import org.eclipse.jetty.ee10.servlet.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee10.servlet.security.LoginService; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.security.Constraint; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @@ -32,16 +30,13 @@ public class OpenIdReamNameTest { private final Server server = new Server(); - public static ServletContextHandler configureOpenIdContext(String realmName) + public static SecurityHandler configureOpenIdContext(String realmName) { - ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); + SecurityHandler.Mapped securityHandler = new SecurityHandler.Mapped(); assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); - securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); + securityHandler.setAuthMethod(Authenticator.OPENID_AUTH); securityHandler.setRealmName(realmName); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/" + realmName); - context.setSecurityHandler(securityHandler); - return context; + return securityHandler; } @Test @@ -53,7 +48,7 @@ public void testSingleConfiguration() throws Exception server.addBean(config1); // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext("This doesn't matter if only 1 OpenIdConfiguration"); + SecurityHandler context1 = configureOpenIdContext("This doesn't matter if only 1 OpenIdConfiguration"); ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); contextHandlerCollection.addHandler(context1); server.setHandler(contextHandlerCollection); @@ -63,7 +58,7 @@ public void testSingleConfiguration() throws Exception server.start(); // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + Authenticator authenticator = context1.getAuthenticator(); assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); assertThat(loginService, instanceOf(OpenIdLoginService.class)); @@ -84,7 +79,7 @@ public void testSingleConfigurationNoRealmName() throws Exception server.addBean(config1); // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext(null); + SecurityHandler context1 = configureOpenIdContext(null); ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); contextHandlerCollection.addHandler(context1); server.setHandler(contextHandlerCollection); @@ -94,7 +89,7 @@ public void testSingleConfigurationNoRealmName() throws Exception server.start(); // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + Authenticator authenticator = context1.getAuthenticator(); assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); assertThat(loginService, instanceOf(OpenIdLoginService.class)); @@ -118,8 +113,8 @@ public void testMultipleConfiguration() throws Exception server.addBean(config2); // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext(config1.getIssuer()); - ServletContextHandler context2 = configureOpenIdContext(config2.getIssuer()); + SecurityHandler context1 = configureOpenIdContext(config1.getIssuer()); + SecurityHandler context2 = configureOpenIdContext(config2.getIssuer()); ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); contextHandlerCollection.addHandler(context1); contextHandlerCollection.addHandler(context2); @@ -130,14 +125,14 @@ public void testMultipleConfiguration() throws Exception server.start(); // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); + Authenticator authenticator = context1.getAuthenticator(); assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); assertThat(loginService, instanceOf(OpenIdLoginService.class)); assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); // The OpenIdConfiguration from context2 matches to config2. - authenticator = context2.getSecurityHandler().getAuthenticator(); + authenticator = context2.getAuthenticator(); assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); assertThat(loginService, instanceOf(OpenIdLoginService.class)); @@ -161,7 +156,7 @@ public void testMultipleConfigurationNoMatch() throws Exception server.addBean(config2); // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext("provider3"); + SecurityHandler context1 = configureOpenIdContext("provider3"); ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); contextHandlerCollection.addHandler(context1); server.setHandler(contextHandlerCollection); @@ -173,7 +168,7 @@ public void testMultipleConfigurationNoMatch() throws Exception @Test public void testNoConfiguration() throws Exception { - ServletContextHandler context1 = configureOpenIdContext(null); + SecurityHandler context1 = configureOpenIdContext(null); ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); contextHandlerCollection.addHandler(context1); server.setHandler(contextHandlerCollection); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java index 559f8a9442dc..8b1f85821043 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractUserAuthentication.java @@ -59,7 +59,7 @@ public boolean isUserInRole(String role) } @Override - public void logout(Request request) + public void logout(Request request, Response response) { SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); if (security != null) @@ -70,7 +70,7 @@ public void logout(Request request) Authentication authentication = null; if (authenticator instanceof LoginAuthenticator loginAuthenticator) { - ((LoginAuthenticator)authenticator).logout(request); + ((LoginAuthenticator)authenticator).logout(request, response); authentication = new LoggedOutAuthentication(loginAuthenticator); } Authentication.setAuthentication(request, authentication); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java index 284fcdebd1be..ec7e60157621 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authentication.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.security; +import java.security.Principal; + import org.eclipse.jetty.http.HttpException; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.QuietException; @@ -37,6 +39,23 @@ static Authentication getAuthentication(Request request) return auth instanceof Authentication authentication ? authentication : null; } + static Principal getUserPrincipal(Request request) + { + Authentication authentication = Authentication.getAuthentication(request); + if (authentication instanceof UserAuthentication userAuthentication) + { + return userAuthentication.getUserIdentity().getUserPrincipal(); + } + if (authentication instanceof DeferredAuthentication deferredAuthentication) + { + User user = deferredAuthentication.authenticate(request); + if (user == null) + return null; + return user.getUserIdentity().getUserPrincipal(); + } + return null; + } + static void setAuthentication(Request request, Authentication authentication) { request.setAttribute(Authentication.class.getName(), authentication); @@ -110,16 +129,23 @@ static Authentication.User login(String username, String password, Request reque return null; } - static boolean logout(Request request) + static boolean logout(Request request, Response response) { Authentication authentication = getAuthentication(request); //if already authenticated, return true if (authentication instanceof Authentication.User userAuthentication) { - userAuthentication.logout(request); + userAuthentication.logout(request, response); return true; } + + if (authentication instanceof DeferredAuthentication deferredAuthentication) + { + deferredAuthentication.logout(request, response); + return true; + } + return false; } @@ -147,8 +173,9 @@ interface User extends Authentication * such that a call to getUserPrincipal/getRemoteUser will return null. * * @param request the request + * @param response the response */ - void logout(Request request); + void logout(Request request, Response response); } /** diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 93e27f73e492..3ead8af632cb 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -56,6 +56,7 @@ public interface Authenticator String getAuthMethod(); /** + * TODO: fix javadoc and rename method. * Called after to validateRequest. * This may be restore method or content from a previous request * that was challenged. @@ -68,6 +69,11 @@ default Request prepareRequest(Request request, Authentication authentication) return request; } + default boolean isMandatory(Request request, Response response, boolean mandatory) + { + return true; + } + /** * Get an {@link Constraint.Authentication} applicable to the path for * this authenticator. This is typically used to vary protection on special URIs known to a @@ -90,8 +96,7 @@ default Constraint.Authentication getConstraintAuthentication(String pathInConte * @param callback the callback to use for writing a response * @return An Authentication. If Authentication is successful, this will be a {@link User}. If a response has * been sent by the Authenticator (which can be done for both successful and unsuccessful authentications), then the result will - * implement {@link Authentication.ResponseSent}. If Authentication is not mandatory, then a - * {@link Authentication.Deferred} may be returned. + * implement {@link Authentication.ResponseSent}. * @throws ServerAuthException if unable to validate request */ Authentication validateRequest(Request request, Response response, Callback callback) throws ServerAuthException; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 2277ff6b0bd8..0416443a6aa7 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -447,22 +447,27 @@ public boolean handle(Request request, Response response, Callback callback) thr Constraint.Authentication constraintAuthentication = constraint.getAuthentication(); constraintAuthentication = _authenticator.getConstraintAuthentication(pathInContext, constraintAuthentication); boolean mustValidate = constraintAuthentication != Constraint.Authentication.REQUIRE_NONE; + mustValidate = _authenticator.isMandatory(request, response, mustValidate); try { - Authentication authentication = mustValidate ? _authenticator.validateRequest(request, response, callback) : null; - - if (authentication instanceof Authentication.ResponseSent) - return true; - - if (isNotAuthorized(constraint, authentication)) + Authentication authentication; + if (mustValidate) { - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!authorized"); - return true; - } + authentication = _authenticator.validateRequest(request, response, callback); + if (authentication instanceof Authentication.ResponseSent) + return true; - if (authentication == null) + if (isNotAuthorized(constraint, authentication)) + { + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!authorized"); + return true; + } + } + else + { authentication = _deferredAuthentication; + } Authentication.setAuthentication(request, authentication); IdentityService.Association association = authentication instanceof Authentication.User user diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java index 38e2624a9762..0de3ea4406e5 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/DeferredAuthentication.java @@ -22,6 +22,7 @@ import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.SecurityHandler; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; import org.eclipse.jetty.security.UserIdentity; @@ -104,6 +105,16 @@ public Authentication.User login(String username, Object password, Request reque return null; } + public void logout(Request request, Response response) + { + SecurityHandler security = SecurityHandler.getCurrentSecurityHandler(); + if (security != null) + { + security.logout(null); + _authenticator.logout(request, response); + } + } + public IdentityService.Association getAssociation() { return _association; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index eb73f111ae8a..2e9eff7f4db4 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -170,9 +170,9 @@ public UserIdentity login(String username, Object password, Request request, Res } @Override - public void logout(Request request) + public void logout(Request request, Response response) { - super.logout(request); + super.logout(request, response); Session session = request.getSession(false); if (session == null) return; @@ -189,7 +189,7 @@ public Request prepareRequest(Request request, Authentication authentication) // browser handling of 302 redirects, the method may not be the same as // that of the original request. Replace the method and original post // params (if it was a post). - if (authentication instanceof Authentication.User user) + if (authentication instanceof Authentication.User) { Session session = request.getSession(false); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 50ce2b24cf5d..3f0075d359aa 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -58,7 +58,7 @@ public UserIdentity login(String username, Object password, Request request, Res return null; } - public void logout(Request request) + public void logout(Request request, Response response) { Session session = request.getSession(false); if (session == null) diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java index 0875e733fa85..6f5a64b84f01 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java @@ -65,7 +65,7 @@ public boolean handle(Request request, Response response, Callback callback) thr out.append(user == null ? "-" : user.getUserIdentity().getUserPrincipal()); } - case "logout" -> out.append(Authentication.logout(request)); + case "logout" -> out.append(Authentication.logout(request, response)); case "thread" -> out.append(TestIdentityService.USER_IDENTITY.get()); diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java index 57ecb2ecf551..4d9307d4abbc 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java @@ -427,6 +427,13 @@ static Fields extractQueryParameters(Request request, Charset charset) return fields; } + static Fields getParameters(Request request) throws Exception + { + Fields queryFields = Request.extractQueryParameters(request); + Fields formFields = FormFields.from(request).get(); + return Fields.combine(queryFields, formFields); + } + @SuppressWarnings("unchecked") static List getCookies(Request request) { diff --git a/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java index 468fdd912b90..0d68091356fd 100644 --- a/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java +++ b/jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SimpleSessionHandler.java @@ -35,6 +35,9 @@ public class SimpleSessionHandler extends AbstractSessionManager implements Hand public void setServer(Server server) { _server = server; + Handler handler = getHandler(); + if (handler != null) + handler.setServer(server); } @Override From f60a0fb43dd37a69561120adc38cb3a35909201a Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Wed, 5 Apr 2023 18:48:14 +1000 Subject: [PATCH 025/129] remove isMandatory and use getConstraintAuthentication method for Authenticator Signed-off-by: Lachlan Roberts --- .../security/openid/OpenIdAuthenticator.java | 25 ++++++++----------- .../eclipse/jetty/security/Authenticator.java | 5 ---- .../jetty/security/SecurityHandler.java | 25 ++++++++----------- .../authentication/FormAuthenticator.java | 2 +- 4 files changed, 22 insertions(+), 35 deletions(-) diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java index 78446e4a8674..97a4e8aa4763 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java @@ -29,6 +29,8 @@ import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.security.Authentication; +import org.eclipse.jetty.security.Authenticator; +import org.eclipse.jetty.security.Constraint; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.ServerAuthException; import org.eclipse.jetty.security.UserAuthentication; @@ -46,7 +48,6 @@ import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.UrlEncoded; -import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -151,7 +152,7 @@ public void setConfiguration(AuthConfiguration authConfig) @Override public String getAuthMethod() { - return Constraint.__OPENID_AUTH; + return Authenticator.OPENID_AUTH; } @Deprecated @@ -387,17 +388,13 @@ protected Fields getParameters(Request request) } @Override - public boolean isMandatory(Request request, Response response, boolean mandatory) + public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) { - String uri = request.getHttpURI().toString(); - if (uri == null) - uri = "/"; - - if (isJSecurityCheck(uri)) - return true; - if (isErrorPage(Request.getPathInContext(request)) && !DeferredAuthentication.isDeferred(response)) - return false; - return mandatory; + if (isJSecurityCheck(pathInContext)) + return Constraint.Authentication.REQUIRE; + if (isErrorPage(pathInContext)) + return Constraint.Authentication.REQUIRE_NONE; + return existing; } @Override @@ -476,7 +473,7 @@ public Authentication validateRequest(Request request, Response response, Callba synchronized (session) { // TODO: We are duplicating this logic. - session.setAttribute(J_URI, uriRedirectInfo.getUri()); + session.setAttribute(J_URI, uriRedirectInfo.getUri().asImmutable()); session.setAttribute(J_METHOD, uriRedirectInfo.getMethod()); session.setAttribute(J_POST, uriRedirectInfo.getFormParameters()); } @@ -553,7 +550,7 @@ public Authentication validateRequest(Request request, Response response, Callba if (session.getAttribute(J_URI) == null || _alwaysSaveUri) { HttpURI juri = request.getHttpURI(); - session.setAttribute(J_URI, juri); + session.setAttribute(J_URI, juri.asImmutable()); if (!HttpMethod.GET.is(request.getMethod())) session.setAttribute(J_METHOD, request.getMethod()); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 3ead8af632cb..9b2222a4be7c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -69,11 +69,6 @@ default Request prepareRequest(Request request, Authentication authentication) return request; } - default boolean isMandatory(Request request, Response response, boolean mandatory) - { - return true; - } - /** * Get an {@link Constraint.Authentication} applicable to the path for * this authenticator. This is typically used to vary protection on special URIs known to a diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 0416443a6aa7..2277ff6b0bd8 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -447,28 +447,23 @@ public boolean handle(Request request, Response response, Callback callback) thr Constraint.Authentication constraintAuthentication = constraint.getAuthentication(); constraintAuthentication = _authenticator.getConstraintAuthentication(pathInContext, constraintAuthentication); boolean mustValidate = constraintAuthentication != Constraint.Authentication.REQUIRE_NONE; - mustValidate = _authenticator.isMandatory(request, response, mustValidate); try { - Authentication authentication; - if (mustValidate) - { - authentication = _authenticator.validateRequest(request, response, callback); - if (authentication instanceof Authentication.ResponseSent) - return true; + Authentication authentication = mustValidate ? _authenticator.validateRequest(request, response, callback) : null; - if (isNotAuthorized(constraint, authentication)) - { - Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!authorized"); - return true; - } - } - else + if (authentication instanceof Authentication.ResponseSent) + return true; + + if (isNotAuthorized(constraint, authentication)) { - authentication = _deferredAuthentication; + Response.writeError(request, response, callback, HttpStatus.FORBIDDEN_403, "!authorized"); + return true; } + if (authentication == null) + authentication = _deferredAuthentication; + Authentication.setAuthentication(request, authentication); IdentityService.Association association = authentication instanceof Authentication.User user ? _identityService.associate(user.getUserIdentity()) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 2e9eff7f4db4..9086dc78ffba 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -320,7 +320,7 @@ public Authentication validateRequest(Request request, Response response, Callba if (session.getAttribute(__J_URI) == null || _alwaysSaveUri) { HttpURI juri = request.getHttpURI(); - session.setAttribute(__J_URI, juri); + session.setAttribute(__J_URI, juri.asImmutable()); if (!HttpMethod.GET.is(request.getMethod())) session.setAttribute(__J_METHOD, request.getMethod()); From c793052c839058c4c163a010976848c988c6759d Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 5 Apr 2023 11:59:40 +0200 Subject: [PATCH 026/129] WIP --- .../main/java/org/eclipse/jetty/security/IdentityService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 4432ebfa188e..660e94c5b700 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -68,7 +68,7 @@ public interface IdentityService UserIdentity getSystemUserIdentity(); - interface Association extends AutoCloseable + interface Association extends Closeable { } From cf9ab28b8736cea3ad54c407762538858a07c915 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 6 Apr 2023 13:56:19 +0200 Subject: [PATCH 027/129] WIP to using core for EE9 --- .../ConfigurableSpnegoLoginService.java | 8 +- .../authentication/AuthorizationService.java | 2 +- .../jetty/util/security/Constraint.java | 2 +- .../jetty/ee9/jaas/JAASLoginService.java | 12 +- .../security/jaspi/JaspiAuthenticator.java | 2 +- .../jaspi/ServletCallbackHandler.java | 4 +- .../jetty/ee9/nested/Authentication.java | 3 +- .../org/eclipse/jetty/ee9/nested/Request.java | 7 +- .../jetty/ee9/nested/UserIdentity.java | 112 ------ .../jetty/ee9/nested/UserIdentityScope.java | 66 ++++ .../security/openid/OpenIdAuthenticator.java | 2 +- .../security/openid/OpenIdLoginService.java | 2 +- .../security/openid/OpenIdUserIdentity.java | 2 +- .../ee9/security/AbstractLoginService.java | 158 --------- .../security/AbstractUserAuthentication.java | 10 +- .../jetty/ee9/security/Authenticator.java | 2 + .../ConfigurableSpnegoLoginService.java | 325 ------------------ .../security/ConstraintSecurityHandler.java | 4 +- .../security/DefaultAuthenticatorFactory.java | 2 + .../ee9/security/DefaultIdentityService.java | 80 ----- .../ee9/security/DefaultUserIdentity.java | 77 ----- .../jetty/ee9/security/EmptyLoginService.java | 57 --- .../jetty/ee9/security/HashLoginService.java | 187 ---------- .../jetty/ee9/security/IdentityService.java | 85 ----- .../jetty/ee9/security/JDBCLoginService.java | 260 -------------- .../ee9/security/LoggedOutAuthentication.java | 3 +- .../jetty/ee9/security/LoginService.java | 69 ---- .../jetty/ee9/security/PropertyUserStore.java | 316 ----------------- .../jetty/ee9/security/SecurityHandler.java | 5 +- .../ee9/security/SpnegoUserIdentity.java | 56 --- .../ee9/security/UserAuthentication.java | 2 +- .../security/WrappedAuthConfiguration.java | 2 + .../authentication/AuthorizationService.java | 43 --- .../authentication/BasicAuthenticator.java | 2 +- .../ConfigurableSpnegoAuthenticator.java | 4 +- .../DeferredAuthentication.java | 6 +- .../authentication/DigestAuthenticator.java | 2 +- .../authentication/FormAuthenticator.java | 2 +- .../authentication/LoginAuthenticator.java | 6 +- .../authentication/LoginCallbackImpl.java | 4 +- .../authentication/SessionAuthentication.java | 4 +- .../SslClientCertAuthenticator.java | 2 +- .../jetty/ee9/security/ConstraintTest.java | 6 +- .../ee9/security/DataConstraintsTest.java | 2 +- .../jetty/ee9/servlet/ServletHandler.java | 2 +- .../jetty/ee9/servlet/ServletHolder.java | 2 +- .../servlet/ServletContextHandlerTest.java | 2 +- 47 files changed, 132 insertions(+), 1881 deletions(-) delete mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentity.java create mode 100644 jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConfigurableSpnegoLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultIdentityService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultUserIdentity.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/EmptyLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/HashLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/JDBCLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoginService.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserIdentity.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/AuthorizationService.java diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java index 1784c05ab1fd..2ddcad6244d9 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java @@ -166,10 +166,10 @@ private PrivilegedAction newSpnegoContext(Subject subject) } @Override - public UserIdentity login(String username, Object credentials, Request req) + public UserIdentity login(String username, Object credentials, Request request) { Subject subject = _context._subject; - Session httpSession = req.getSession(false); + Session httpSession = request.getSession(false); GSSContext gssContext = null; if (httpSession != null) { @@ -191,14 +191,14 @@ public UserIdentity login(String username, Object credentials, Request req) if (httpSession != null) httpSession.removeAttribute(GSSContextHolder.ATTRIBUTE); - UserIdentity roles = _authorizationService.getUserIdentity(req, userName); + UserIdentity roles = _authorizationService.getUserIdentity(request, userName); return new SpnegoUserIdentity(subject, principal, roles); } else { // The GSS context is not established yet, save it into the HTTP session. if (httpSession == null) - httpSession = req.getSession(true); + httpSession = request.getSession(true); GSSContextHolder holder = new GSSContextHolder(gssContext); httpSession.setAttribute(GSSContextHolder.ATTRIBUTE, holder); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java index e983965e23cb..19df8f108658 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -36,7 +36,7 @@ public interface AuthorizationService * @param loginService the {@link LoginService} to wrap * @return an AuthorizationService that delegates the query for roles to the given {@link LoginService} */ - public static AuthorizationService from(LoginService loginService, Object credentials) + static AuthorizationService from(LoginService loginService, Object credentials) { return (request, name) -> loginService.login(name, credentials, request); } diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java index c78c2209c278..c34d780a1573 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java @@ -20,7 +20,7 @@ * Constraint * * Describe an auth and/or data constraint. - * TODO remove + * TODO remove or move to EE9 */ @Deprecated public class Constraint implements Cloneable, Serializable diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java index c49f5a7566bb..6ef3bcfca43b 100644 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java +++ b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java @@ -31,13 +31,13 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.DefaultIdentityService; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.server.Request; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -182,7 +182,7 @@ protected void doStart() throws Exception } @Override - public UserIdentity login(final String username, final Object credentials, final ServletRequest request) + public UserIdentity login(final String username, final Object credentials, final Request request) { try { diff --git a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java index cd2944b24936..60cfae695b11 100644 --- a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java +++ b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java @@ -35,7 +35,6 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.eclipse.jetty.ee9.nested.Authentication; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.EmptyLoginService; import org.eclipse.jetty.ee9.security.IdentityService; import org.eclipse.jetty.ee9.security.LoginService; @@ -45,6 +44,7 @@ import org.eclipse.jetty.ee9.security.authentication.DeferredAuthentication; import org.eclipse.jetty.ee9.security.authentication.LoginAuthenticator; import org.eclipse.jetty.ee9.security.authentication.SessionAuthentication; +import org.eclipse.jetty.security.UserIdentity; import static org.eclipse.jetty.ee9.security.jaspi.JaspiAuthenticatorFactory.MESSAGE_LAYER; diff --git a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/ServletCallbackHandler.java b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/ServletCallbackHandler.java index 60c870b7809c..df80a72dfe82 100644 --- a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/ServletCallbackHandler.java +++ b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/ServletCallbackHandler.java @@ -26,11 +26,11 @@ import jakarta.security.auth.message.callback.PrivateKeyCallback; import jakarta.security.auth.message.callback.SecretKeyCallback; import jakarta.security.auth.message.callback.TrustStoreCallback; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.authentication.LoginCallback; import org.eclipse.jetty.ee9.security.authentication.LoginCallbackImpl; import org.eclipse.jetty.ee9.security.jaspi.callback.CredentialValidationCallback; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; /** * This {@link CallbackHandler} will bridge {@link Callback}s to handle to the given to the Jetty {@link LoginService}. diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Authentication.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Authentication.java index ca22c549e5ed..a4fa8da52a5e 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Authentication.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Authentication.java @@ -17,6 +17,7 @@ import jakarta.servlet.ServletResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.jetty.security.UserIdentity; /** * The Authentication state of a request. @@ -46,7 +47,7 @@ public interface User extends LogoutAuthentication UserIdentity getUserIdentity(); - boolean isUserInRole(UserIdentity.Scope scope, String role); + boolean isUserInRole(UserIdentityScope scope, String role); } /** diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java index 2ddace8318d4..79f3d6a80371 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java @@ -78,6 +78,7 @@ import org.eclipse.jetty.http.MimeTypes; import org.eclipse.jetty.io.Connection; import org.eclipse.jetty.io.RuntimeIOException; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.HttpCookieUtils; import org.eclipse.jetty.server.HttpCookieUtils.SetCookieHttpField; import org.eclipse.jetty.server.Server; @@ -182,7 +183,7 @@ public static Request getBaseRequest(ServletRequest request) private MultiMap _contentParameters; private MultiMap _parameters; private Charset _queryEncoding; - private UserIdentity.Scope _scope; + private UserIdentityScope _scope; private long _timeStamp; private MultiPartFormInputStream _multiParts; //if the request is a multi-part mime private AsyncContextState _async; @@ -1407,7 +1408,7 @@ public UserIdentity getResolvedUserIdentity() return null; } - public UserIdentity.Scope getUserIdentityScope() + public UserIdentityScope getUserIdentityScope() { return _scope; } @@ -1842,7 +1843,7 @@ public void setTimeStamp(long ts) _timeStamp = ts; } - public void setUserIdentityScope(UserIdentity.Scope scope) + public void setUserIdentityScope(UserIdentityScope scope) { _scope = scope; } diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentity.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentity.java deleted file mode 100644 index a5441e1ff5ac..000000000000 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentity.java +++ /dev/null @@ -1,112 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.nested; - -import java.security.Principal; -import java.util.Map; -import javax.security.auth.Subject; - -/** - * User object that encapsulates user identity and operations such as run-as-role actions, - * checking isUserInRole and getUserPrincipal. - *

    - * Implementations of UserIdentity should be immutable so that they may be - * cached by Authenticators and LoginServices. - */ -public interface UserIdentity -{ - - /** - * @return The user subject - */ - Subject getSubject(); - - /** - * @return The user principal - */ - Principal getUserPrincipal(); - - /** - * Check if the user is in a role. - * This call is used to satisfy authorization calls from - * container code which will be using translated role names. - * - * @param role A role name. - * @param scope the scope - * @return True if the user can act in that role. - */ - boolean isUserInRole(String role, Scope scope); - - /** - * A UserIdentity Scope. - * A scope is the environment in which a User Identity is to - * be interpreted. Typically it is set by the target servlet of - * a request. - */ - interface Scope - { - - /** - * @return The context handler that the identity is being considered within - */ - ContextHandler getContextHandler(); - - /** - * @return The context path that the identity is being considered within - */ - String getContextPath(); - - /** - * @return The name of the identity context. Typically this is the servlet name. - */ - String getName(); - - /** - * @return A map of role reference names that converts from names used by application code - * to names used by the context deployment. - */ - Map getRoleRefMap(); - } - - public interface UnauthenticatedUserIdentity extends UserIdentity - { - } - - public static final UserIdentity UNAUTHENTICATED_IDENTITY = new UnauthenticatedUserIdentity() - { - @Override - public Subject getSubject() - { - return null; - } - - @Override - public Principal getUserPrincipal() - { - return null; - } - - @Override - public boolean isUserInRole(String role, Scope scope) - { - return false; - } - - @Override - public String toString() - { - return "UNAUTHENTICATED"; - } - }; -} diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java new file mode 100644 index 000000000000..aad0cbd16056 --- /dev/null +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java @@ -0,0 +1,66 @@ +// +// ======================================================================== +// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.ee9.nested; + +import java.util.Map; + +/** + * User object that encapsulates user identity and operations such as run-as-role actions, + * checking isUserInRole and getUserPrincipal. + *

    + * Implementations of UserIdentity should be immutable so that they may be + * cached by Authenticators and LoginServices. + */ +public interface UserIdentityScope +{ + /** + * @return The context handler that the identity is being considered within + */ + ContextHandler getContextHandler(); + + /** + * @return The context path that the identity is being considered within + */ + String getContextPath(); + + /** + * @return The name of the identity context. Typically this is the servlet name. + */ + String getName(); + + /** + * @return A map of role reference names that converts from names used by application code + * to names used by the context deployment. + */ + Map getRoleRefMap(); + + static String deRefRole(UserIdentityScope scope, String role) + { + if (scope == null) + return role; + + Map roleRefMap = scope.getRoleRefMap(); + if (roleRefMap == null || roleRefMap.isEmpty()) + return role; + + String ref = roleRefMap.get(role); + while (ref != null) + { + role = ref; + ref = roleRefMap.get(role); + } + return role; + } + +} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java index 6ae8c617161b..6d6af046042e 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.Response; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; @@ -39,6 +38,7 @@ import org.eclipse.jetty.ee9.security.authentication.SessionAuthentication; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.UrlEncoded; diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java index 3b8263cee763..53256bbcfb77 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java @@ -17,9 +17,9 @@ import javax.security.auth.Subject; import jakarta.servlet.ServletRequest; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.IdentityService; import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java index e1088a4eb99a..92a529f1f6e3 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java @@ -16,7 +16,7 @@ import java.security.Principal; import javax.security.auth.Subject; -import org.eclipse.jetty.ee9.nested.UserIdentity; +import org.eclipse.jetty.security.UserIdentity; public class OpenIdUserIdentity implements UserIdentity { diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractLoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractLoginService.java deleted file mode 100644 index 78dc0c7f13f8..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractLoginService.java +++ /dev/null @@ -1,158 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.util.ArrayList; -import java.util.List; -import javax.security.auth.Subject; - -import jakarta.servlet.ServletRequest; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractLoginService - * - * Base class for LoginServices that allows subclasses to provide the user authentication and authorization information, - * but provides common behaviour such as handling authentication. - */ -public abstract class AbstractLoginService extends ContainerLifeCycle implements LoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractLoginService.class); - - protected IdentityService _identityService = new DefaultIdentityService(); - protected String _name; - protected boolean _fullValidate = false; - - protected abstract List loadRoleInfo(UserPrincipal user); - - protected abstract UserPrincipal loadUserInfo(String username); - - protected AbstractLoginService() - { - addBean(_identityService); - } - - @Override - public String getName() - { - return _name; - } - - /** - * Set the identityService. - * - * @param identityService the identityService to set - */ - @Override - public void setIdentityService(IdentityService identityService) - { - if (isRunning()) - throw new IllegalStateException("Running"); - updateBean(_identityService, identityService); - _identityService = identityService; - } - - /** - * Set the name. - * - * @param name the name to set - */ - public void setName(String name) - { - if (isRunning()) - throw new IllegalStateException("Running"); - _name = name; - } - - @Override - public String toString() - { - return String.format("%s@%x[%s]", this.getClass().getSimpleName(), hashCode(), _name); - } - - @Override - public UserIdentity login(String username, Object credentials, ServletRequest request) - { - if (username == null) - return null; - - UserPrincipal userPrincipal = loadUserInfo(username); - if (userPrincipal != null && userPrincipal.authenticate(credentials)) - { - //safe to load the roles - List roles = loadRoleInfo(userPrincipal); - - List roleNames = new ArrayList<>(); - Subject subject = new Subject(); - userPrincipal.configureSubject(subject); - if (roles != null) - { - roles.forEach(p -> - { - p.configureForSubject(subject); - roleNames.add(p.getName()); - }); - } - - subject.setReadOnly(); - return _identityService.newUserIdentity(subject, userPrincipal, roleNames.toArray(new String[0])); - } - - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - if (!isFullValidate()) - return true; //if we have a user identity it must be valid - - //Do a full validation back against the user store - UserPrincipal fresh = loadUserInfo(user.getUserPrincipal().getName()); - if (fresh == null) - return false; //user no longer exists - - if (user.getUserPrincipal() instanceof UserPrincipal) - { - return fresh.authenticate(((UserPrincipal)user.getUserPrincipal())); - } - - throw new IllegalStateException("UserPrincipal not known"); //can't validate - } - - @Override - public IdentityService getIdentityService() - { - return _identityService; - } - - @Override - public void logout(UserIdentity user) - { - //Override in subclasses - } - - public boolean isFullValidate() - { - return _fullValidate; - } - - public void setFullValidate(boolean fullValidate) - { - _fullValidate = fullValidate; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java index 0f78410c2822..d2c80825e90f 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java @@ -19,9 +19,9 @@ import jakarta.servlet.ServletRequest; import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.nested.UserIdentity.Scope; +import org.eclipse.jetty.ee9.nested.UserIdentityScope; import org.eclipse.jetty.ee9.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.security.UserIdentity; /** * AbstractUserAuthentication @@ -54,7 +54,7 @@ public UserIdentity getUserIdentity() } @Override - public boolean isUserInRole(Scope scope, String role) + public boolean isUserInRole(UserIdentityScope scope, String role) { String roleToTest = null; if (scope != null && scope.getRoleRefMap() != null) @@ -70,10 +70,10 @@ public boolean isUserInRole(Scope scope, String role) if (!declaredRolesContains("**")) return true; else - return _userIdentity.isUserInRole(role, scope); + return _userIdentity.isUserInRole(UserIdentityScope.deRefRole(scope, role)); } - return _userIdentity.isUserInRole(role, scope); + return _userIdentity.isUserInRole(UserIdentityScope.deRefRole(scope, role)); } public boolean declaredRolesContains(String roleName) diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java index 8f28dc44e032..9cd351c72608 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java @@ -20,6 +20,8 @@ import jakarta.servlet.ServletResponse; import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; /** diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConfigurableSpnegoLoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConfigurableSpnegoLoginService.java deleted file mode 100644 index eb2a00db0b49..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConfigurableSpnegoLoginService.java +++ /dev/null @@ -1,325 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.Serializable; -import java.net.InetAddress; -import java.nio.file.Path; -import java.security.PrivilegedAction; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; -import javax.security.auth.Subject; -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; - -import jakarta.servlet.ServletRequest; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpSession; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.authentication.AuthorizationService; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.ietf.jgss.GSSContext; -import org.ietf.jgss.GSSCredential; -import org.ietf.jgss.GSSException; -import org.ietf.jgss.GSSManager; -import org.ietf.jgss.GSSName; -import org.ietf.jgss.Oid; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *

    A configurable (as opposed to using system properties) SPNEGO LoginService.

    - *

    At startup, this LoginService will login via JAAS the service principal, composed - * of the {@link #getServiceName() service name} and the {@link #getHostName() host name}, - * for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal - * credentials.

    - *

    Upon receiving an HTTP request, the server tries to authenticate the client - * calling {@link #login(String, Object, ServletRequest)} where the GSS APIs are used to - * verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is - * established.

    - */ -public class ConfigurableSpnegoLoginService extends ContainerLifeCycle implements LoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(ConfigurableSpnegoLoginService.class); - - private final GSSManager _gssManager = GSSManager.getInstance(); - private final String _realm; - private final AuthorizationService _authorizationService; - private IdentityService _identityService = new DefaultIdentityService(); - private String _serviceName; - private Path _keyTabPath; - private String _hostName; - private SpnegoContext _context; - - public ConfigurableSpnegoLoginService(String realm, AuthorizationService authorizationService) - { - _realm = realm; - _authorizationService = authorizationService; - } - - /** - * @return the realm name - */ - @Override - public String getName() - { - return _realm; - } - - /** - * @return the path of the keyTab file containing service credentials - */ - public Path getKeyTabPath() - { - return _keyTabPath; - } - - /** - * @param keyTabFile the path of the keyTab file containing service credentials - */ - public void setKeyTabPath(Path keyTabFile) - { - _keyTabPath = keyTabFile; - } - - /** - * @return the service name, typically "HTTP" - * @see #getHostName() - */ - public String getServiceName() - { - return _serviceName; - } - - /** - * @param serviceName the service name - * @see #setHostName(String) - */ - public void setServiceName(String serviceName) - { - _serviceName = serviceName; - } - - /** - * @return the host name of the service - * @see #setServiceName(String) - */ - public String getHostName() - { - return _hostName; - } - - /** - * @param hostName the host name of the service - */ - public void setHostName(String hostName) - { - _hostName = hostName; - } - - @Override - protected void doStart() throws Exception - { - if (_hostName == null) - _hostName = InetAddress.getLocalHost().getCanonicalHostName(); - if (LOG.isDebugEnabled()) - LOG.debug("Retrieving credentials for service {}/{}", getServiceName(), getHostName()); - LoginContext loginContext = new LoginContext("", null, null, new SpnegoConfiguration()); - loginContext.login(); - Subject subject = loginContext.getSubject(); - _context = Subject.doAs(subject, newSpnegoContext(subject)); - super.doStart(); - } - - private PrivilegedAction newSpnegoContext(Subject subject) - { - return () -> - { - try - { - GSSName serviceName = _gssManager.createName(getServiceName() + "@" + getHostName(), GSSName.NT_HOSTBASED_SERVICE); - Oid kerberosOid = new Oid("1.2.840.113554.1.2.2"); - Oid spnegoOid = new Oid("1.3.6.1.5.5.2"); - Oid[] mechanisms = new Oid[]{kerberosOid, spnegoOid}; - GSSCredential serviceCredential = _gssManager.createCredential(serviceName, GSSCredential.DEFAULT_LIFETIME, mechanisms, GSSCredential.ACCEPT_ONLY); - SpnegoContext context = new SpnegoContext(); - context._subject = subject; - context._serviceCredential = serviceCredential; - return context; - } - catch (GSSException x) - { - throw new RuntimeException(x); - } - }; - } - - @Override - public UserIdentity login(String username, Object credentials, ServletRequest req) - { - Subject subject = _context._subject; - HttpServletRequest request = (HttpServletRequest)req; - HttpSession httpSession = request.getSession(false); - GSSContext gssContext = null; - if (httpSession != null) - { - GSSContextHolder holder = (GSSContextHolder)httpSession.getAttribute(GSSContextHolder.ATTRIBUTE); - gssContext = holder == null ? null : holder.gssContext; - } - if (gssContext == null) - gssContext = Subject.doAs(subject, newGSSContext()); - - byte[] input = Base64.getDecoder().decode((String)credentials); - byte[] output = Subject.doAs(_context._subject, acceptGSSContext(gssContext, input)); - String token = Base64.getEncoder().encodeToString(output); - - String userName = toUserName(gssContext); - // Save the token in the principal so it can be sent in the response. - SpnegoUserPrincipal principal = new SpnegoUserPrincipal(userName, token); - if (gssContext.isEstablished()) - { - if (httpSession != null) - httpSession.removeAttribute(GSSContextHolder.ATTRIBUTE); - - UserIdentity roles = _authorizationService.getUserIdentity(request, userName); - return new SpnegoUserIdentity(subject, principal, roles); - } - else - { - // The GSS context is not established yet, save it into the HTTP session. - if (httpSession == null) - httpSession = request.getSession(true); - GSSContextHolder holder = new GSSContextHolder(gssContext); - httpSession.setAttribute(GSSContextHolder.ATTRIBUTE, holder); - - // Return an unestablished UserIdentity. - return new SpnegoUserIdentity(subject, principal, null); - } - } - - private PrivilegedAction newGSSContext() - { - return () -> - { - try - { - return _gssManager.createContext(_context._serviceCredential); - } - catch (GSSException x) - { - throw new RuntimeException(x); - } - }; - } - - private PrivilegedAction acceptGSSContext(GSSContext gssContext, byte[] token) - { - return () -> - { - try - { - return gssContext.acceptSecContext(token, 0, token.length); - } - catch (GSSException x) - { - throw new RuntimeException(x); - } - }; - } - - private String toUserName(GSSContext gssContext) - { - try - { - String name = gssContext.getSrcName().toString(); - int at = name.indexOf('@'); - if (at < 0) - return name; - return name.substring(0, at); - } - catch (GSSException x) - { - throw new RuntimeException(x); - } - } - - @Override - public boolean validate(UserIdentity user) - { - return false; - } - - @Override - public IdentityService getIdentityService() - { - return _identityService; - } - - @Override - public void setIdentityService(IdentityService identityService) - { - _identityService = identityService; - } - - @Override - public void logout(UserIdentity user) - { - } - - private class SpnegoConfiguration extends Configuration - { - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) - { - final String principal = getServiceName() + "/" + getHostName(); - Map options = new HashMap<>(); - if (LOG.isDebugEnabled()) - options.put("debug", "true"); - options.put("doNotPrompt", "true"); - options.put("refreshKrb5Config", "true"); - options.put("principal", principal); - options.put("useKeyTab", "true"); - Path keyTabPath = getKeyTabPath(); - if (keyTabPath != null) - options.put("keyTab", keyTabPath.toAbsolutePath().toString()); - // This option is required to store the service credentials in - // the Subject, so that it can be later used by acceptSecContext(). - options.put("storeKey", "true"); - options.put("isInitiator", "false"); - String moduleClass = "com.sun.security.auth.module.Krb5LoginModule"; - AppConfigurationEntry config = new AppConfigurationEntry(moduleClass, AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options); - return new AppConfigurationEntry[]{config}; - } - } - - private static class SpnegoContext - { - private Subject _subject; - private GSSCredential _serviceCredential; - } - - private static class GSSContextHolder implements Serializable - { - public static final String ATTRIBUTE = GSSContextHolder.class.getName(); - - private final transient GSSContext gssContext; - - private GSSContextHolder(GSSContext gssContext) - { - this.gssContext = gssContext; - } - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintSecurityHandler.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintSecurityHandler.java index afec5c8833df..911e6257684a 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintSecurityHandler.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintSecurityHandler.java @@ -35,12 +35,12 @@ import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.Response; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.pathmap.MappedResource; import org.eclipse.jetty.http.pathmap.MatchedResource; import org.eclipse.jetty.http.pathmap.PathMappings; import org.eclipse.jetty.http.pathmap.PathSpec; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.URIUtil; @@ -699,7 +699,7 @@ protected boolean checkWebResourcePermissions(String pathInContext, Request requ boolean isUserInRole = false; for (String role : roleInfo.getRoles()) { - if (userIdentity.isUserInRole(role, null)) + if (userIdentity.isUserInRole(role)) { isUserInRole = true; break; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultAuthenticatorFactory.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultAuthenticatorFactory.java index 64d35868c054..8efd0ba82c2e 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultAuthenticatorFactory.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultAuthenticatorFactory.java @@ -25,6 +25,8 @@ import org.eclipse.jetty.ee9.security.authentication.LoginAuthenticator; import org.eclipse.jetty.ee9.security.authentication.SessionAuthentication; import org.eclipse.jetty.ee9.security.authentication.SslClientCertAuthenticator; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultIdentityService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultIdentityService.java deleted file mode 100644 index 623a75882f33..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultIdentityService.java +++ /dev/null @@ -1,80 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.ee9.nested.UserIdentity; - -/** - * Default Identity Service implementation. - * This service handles only role reference maps passed in an - * associated {@link UserIdentity.Scope}. If there are roles - * refs present, then associate will wrap the UserIdentity with one - * that uses the role references in the - * {@link UserIdentity#isUserInRole(String, UserIdentity.Scope)} - * implementation. All other operations are effectively noops. - */ -public class DefaultIdentityService implements IdentityService -{ - - public DefaultIdentityService() - { - } - - /** - * If there are roles refs present in the scope, then wrap the UserIdentity - * with one that uses the role references in the {@link UserIdentity#isUserInRole(String, UserIdentity.Scope)} - */ - @Override - public Object associate(UserIdentity user) - { - return null; - } - - @Override - public void disassociate(Object previous) - { - } - - @Override - public Object setRunAs(UserIdentity user, RunAsToken token) - { - return token; - } - - @Override - public void unsetRunAs(Object lastToken) - { - } - - @Override - public RunAsToken newRunAsToken(String runAsName) - { - return new RoleRunAsToken(runAsName); - } - - @Override - public UserIdentity getSystemUserIdentity() - { - return null; - } - - @Override - public UserIdentity newUserIdentity(final Subject subject, final Principal userPrincipal, final String[] roles) - { - return new DefaultUserIdentity(subject, userPrincipal, roles); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultUserIdentity.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultUserIdentity.java deleted file mode 100644 index 3125672d7a67..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultUserIdentity.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.ee9.nested.UserIdentity; - -/** - * The default implementation of UserIdentity. - */ -public class DefaultUserIdentity implements UserIdentity -{ - private final Subject _subject; - private final Principal _userPrincipal; - private final String[] _roles; - - public DefaultUserIdentity(Subject subject, Principal userPrincipal, String[] roles) - { - _subject = subject; - _userPrincipal = userPrincipal; - _roles = roles; - } - - @Override - public Subject getSubject() - { - return _subject; - } - - @Override - public Principal getUserPrincipal() - { - return _userPrincipal; - } - - @Override - public boolean isUserInRole(String role, Scope scope) - { - //Servlet Spec 3.1, pg 125 - if ("*".equals(role)) - return false; - - String roleToTest = null; - if (scope != null && scope.getRoleRefMap() != null) - roleToTest = scope.getRoleRefMap().get(role); - - //Servlet Spec 3.1, pg 125 - if (roleToTest == null) - roleToTest = role; - - for (String r : _roles) - { - if (r.equals(roleToTest)) - return true; - } - return false; - } - - @Override - public String toString() - { - return DefaultUserIdentity.class.getSimpleName() + "('" + _userPrincipal + "')"; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/EmptyLoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/EmptyLoginService.java deleted file mode 100644 index da17de33bd92..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/EmptyLoginService.java +++ /dev/null @@ -1,57 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import jakarta.servlet.ServletRequest; -import org.eclipse.jetty.ee9.nested.UserIdentity; - -/** - * LoginService implementation which always denies any attempt to login. - */ -public class EmptyLoginService implements LoginService -{ - @Override - public String getName() - { - return null; - } - - @Override - public UserIdentity login(String username, Object credentials, ServletRequest request) - { - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - return false; - } - - @Override - public IdentityService getIdentityService() - { - return null; - } - - @Override - public void setIdentityService(IdentityService service) - { - } - - @Override - public void logout(UserIdentity user) - { - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/HashLoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/HashLoginService.java deleted file mode 100644 index 403564a56c6d..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/HashLoginService.java +++ /dev/null @@ -1,187 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.util.List; - -import org.eclipse.jetty.util.resource.Resource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * An implementation of a LoginService that stores users and roles in-memory in HashMaps. - * The source of the users and roles information is a properties file formatted like so: - *
    - *  username: password [,rolename ...]
    - * 
    - * - * Passwords may be clear text, obfuscated or checksummed. The class com.eclipse.Util.Password should be used to generate obfuscated passwords or password - * checksums. - *

    - * If DIGEST Authentication is used, the password must be in a recoverable format, either plain text or OBF:. - */ -public class HashLoginService extends AbstractLoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(HashLoginService.class); - - private Resource _config; - private int refreshInterval; // default is not to reload - private UserStore _userStore; - private boolean _userStoreAutoCreate = false; - - public HashLoginService() - { - } - - public HashLoginService(String name) - { - setName(name); - } - - public HashLoginService(String name, Resource config) - { - setName(name); - setConfig(config); - } - - public Resource getConfig() - { - return _config; - } - - /** - * Load users from properties file. - *

    - * The property file maps usernames to password specs followed by an optional comma separated list of role names. - *

    - * - * @param config uri or url or path to realm properties file - */ - public void setConfig(Resource config) - { - _config = config; - } - - /** - * Is hot reload enabled on this user store - * - * @return true if hot reload was enabled before startup - * @deprecated use {@link #getRefreshInterval()} - */ - @Deprecated - public boolean isHotReload() - { - return refreshInterval > 0; - } - - /** - * Enable Hot Reload of the Property File - * - * @param enable true to enable 1s refresh interval, false to disable - * @deprecated use {@link #setRefreshInterval(int)} - */ - @Deprecated - public void setHotReload(boolean enable) - { - setRefreshInterval(enable ? 1 : 0); - } - - /** - * @return the scan interval in seconds for reloading the property file. - */ - public int getRefreshInterval() - { - return refreshInterval; - } - - /** - * @param refreshIntervalSeconds Set the scan interval in seconds for reloading the property file. - */ - public void setRefreshInterval(int refreshIntervalSeconds) - { - if (isRunning()) - throw new IllegalStateException("Cannot set while user store is running"); - this.refreshInterval = refreshIntervalSeconds; - } - - /** - * Configure the {@link UserStore} implementation to use. - * If none, for backward compat if none the {@link PropertyUserStore} will be used - * - * @param userStore the {@link UserStore} implementation to use - */ - public void setUserStore(UserStore userStore) - { - updateBean(_userStore, userStore); - _userStore = userStore; - } - - @Override - protected List loadRoleInfo(UserPrincipal user) - { - return _userStore.getRolePrincipals(user.getName()); - } - - @Override - protected UserPrincipal loadUserInfo(String userName) - { - return _userStore.getUserPrincipal(userName); - } - - @Override - protected void doStart() throws Exception - { - super.doStart(); - if (_userStore == null) - { - if (LOG.isDebugEnabled()) - LOG.debug("doStart: Starting new PropertyUserStore. PropertiesFile: {} refresh: {}s", _config, refreshInterval); - PropertyUserStore propertyUserStore = new PropertyUserStore(); - propertyUserStore.setRefreshInterval(refreshInterval); - propertyUserStore.setConfig(_config); - setUserStore(propertyUserStore); - _userStoreAutoCreate = true; - } - } - - /** - * To facilitate testing. - * - * @return the UserStore - */ - UserStore getUserStore() - { - return _userStore; - } - - /** - * - * @return true if a UserStore has been created from a config, false if a UserStore was provided. - */ - boolean isUserStoreAutoCreate() - { - return _userStoreAutoCreate; - } - - @Override - protected void doStop() throws Exception - { - super.doStop(); - if (_userStoreAutoCreate) - { - setUserStore(null); - _userStoreAutoCreate = false; - } - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java deleted file mode 100644 index 2ec6591dcf1f..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.nested.UserIdentity; - -/** - * Associates UserIdentities from with threads and UserIdentity.Contexts. - */ -public interface IdentityService -{ - static final String[] NO_ROLES = new String[]{}; - - /** - * Associate a user identity with the current thread. - * This is called with as a thread enters the - * {@link SecurityHandler#handle(String, Request, jakarta.servlet.http.HttpServletRequest, jakarta.servlet.http.HttpServletResponse)} - * method and then again with a null argument as that call exits. - * - * @param user The current user or null for no user to associated. - * @return an object representing the previous associated state - */ - Object associate(UserIdentity user); - - /** - * Disassociate the user identity from the current thread - * and restore previous identity. - * - * @param previous The opaque object returned from a call to {@link IdentityService#associate(UserIdentity)} - */ - void disassociate(Object previous); - - /** - * Associate a runas Token with the current user and thread. - * - * @param user The UserIdentity - * @param token The runAsToken to associate. - * @return The previous runAsToken or null. - */ - Object setRunAs(UserIdentity user, RunAsToken token); - - /** - * Disassociate the current runAsToken from the thread - * and reassociate the previous token. - * - * @param token RUNAS returned from previous associateRunAs call - */ - void unsetRunAs(Object token); - - /** - * Create a new UserIdentity for use with this identity service. - * The UserIdentity should be immutable and able to be cached. - * - * @param subject Subject to include in UserIdentity - * @param userPrincipal Principal to include in UserIdentity. This will be returned from getUserPrincipal calls - * @param roles set of roles to include in UserIdentity. - * @return A new immutable UserIdententity - */ - UserIdentity newUserIdentity(Subject subject, Principal userPrincipal, String[] roles); - - /** - * Create a new RunAsToken from a runAsName (normally a role). - * - * @param runAsName Normally a role name - * @return A new immutable RunAsToken - */ - RunAsToken newRunAsToken(String runAsName); - - UserIdentity getSystemUserIdentity(); -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/JDBCLoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/JDBCLoginService.java deleted file mode 100644 index 1a070ce5a4ed..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/JDBCLoginService.java +++ /dev/null @@ -1,260 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.InputStream; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.stream.Collectors; - -import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.util.security.Credential; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JDBC as a source of user authentication and authorization information. - * Uses one database connection that is lazily initialized. Reconnect on failures. - */ -public class JDBCLoginService extends AbstractLoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginService.class); - - protected String _config; - protected String _jdbcDriver; - protected String _url; - protected String _userName; - protected String _password; - protected String _userTableKey; - protected String _userTablePasswordField; - protected String _roleTableRoleField; - protected String _userSql; - protected String _roleSql; - protected Connection _con; - - /** - * JDBCUserPrincipal - * - * A UserPrincipal with extra jdbc key info. - */ - public class JDBCUserPrincipal extends UserPrincipal - { - final int _userKey; - - public JDBCUserPrincipal(String name, Credential credential, int key) - { - super(name, credential); - _userKey = key; - } - - public int getUserKey() - { - return _userKey; - } - } - - public JDBCLoginService() - { - } - - public JDBCLoginService(String name) - { - setName(name); - } - - public JDBCLoginService(String name, String config) - { - setName(name); - setConfig(config); - } - - public JDBCLoginService(String name, IdentityService identityService, String config) - { - setName(name); - setIdentityService(identityService); - setConfig(config); - } - - @Override - protected void doStart() throws Exception - { - Properties properties = new Properties(); - try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable(); - InputStream in = resourceFactory.newResource(_config).newInputStream()) - { - properties.load(in); - } - _jdbcDriver = properties.getProperty("jdbcdriver"); - _url = properties.getProperty("url"); - _userName = properties.getProperty("username"); - _password = properties.getProperty("password"); - _userTableKey = properties.getProperty("usertablekey"); - _userTablePasswordField = properties.getProperty("usertablepasswordfield"); - _roleTableRoleField = properties.getProperty("roletablerolefield"); - - final String userTable = properties.getProperty("usertable"); - final String userTableUserField = properties.getProperty("usertableuserfield"); - final String roleTable = properties.getProperty("roletable"); - final String roleTableKey = properties.getProperty("roletablekey"); - final String userRoleTable = properties.getProperty("userroletable"); - final String userRoleTableUserKey = properties.getProperty("userroletableuserkey"); - final String userRoleTableRoleKey = properties.getProperty("userroletablerolekey"); - - if (_jdbcDriver == null || _jdbcDriver.equals("") || - _url == null || _url.equals("") || - _userName == null || _userName.equals("") || - _password == null) - { - LOG.warn("UserRealm {} has not been properly configured", getName()); - } - - _userSql = "select " + _userTableKey + "," + _userTablePasswordField + " from " + userTable + " where " + userTableUserField + " = ?"; - _roleSql = "select r." + _roleTableRoleField + - " from " + roleTable + " r, " + userRoleTable + - " u where u." + userRoleTableUserKey + " = ?" + - " and r." + roleTableKey + " = u." + userRoleTableRoleKey; - - Loader.loadClass(_jdbcDriver).getDeclaredConstructor().newInstance(); - super.doStart(); - } - - public String getConfig() - { - return _config; - } - - /** - * Load JDBC connection configuration from properties file. - * - * @param config Filename or url of user properties file. - */ - public void setConfig(String config) - { - if (isRunning()) - throw new IllegalStateException("Running"); - _config = config; - } - - /** - * Connect to database with parameters setup by loadConfig() - */ - public Connection connectDatabase() - throws SQLException - { - return DriverManager.getConnection(_url, _userName, _password); - } - - @Override - public UserPrincipal loadUserInfo(String username) - { - try - { - if (null == _con) - _con = connectDatabase(); - - try (PreparedStatement stat1 = _con.prepareStatement(_userSql)) - { - stat1.setObject(1, username); - try (ResultSet rs1 = stat1.executeQuery()) - { - if (rs1.next()) - { - int key = rs1.getInt(_userTableKey); - String credentials = rs1.getString(_userTablePasswordField); - - return new JDBCUserPrincipal(username, Credential.getCredential(credentials), key); - } - } - } - } - catch (SQLException e) - { - LOG.warn("LoginService {} could not load user {}", getName(), username, e); - closeConnection(); - } - - return null; - } - - @Override - public List loadRoleInfo(UserPrincipal user) - { - if (user == null) - return null; - - JDBCUserPrincipal jdbcUser = (JDBCUserPrincipal)user; - - try - { - if (null == _con) - _con = connectDatabase(); - - List roles = new ArrayList(); - - try (PreparedStatement stat2 = _con.prepareStatement(_roleSql)) - { - stat2.setInt(1, jdbcUser.getUserKey()); - try (ResultSet rs2 = stat2.executeQuery()) - { - while (rs2.next()) - roles.add(rs2.getString(_roleTableRoleField)); - - return roles.stream().map(RolePrincipal::new).collect(Collectors.toList()); - } - } - } - catch (SQLException e) - { - LOG.warn("LoginService {} could not load roles for user {}", getName(), user.getName(), e); - closeConnection(); - } - - return null; - } - - @Override - protected void doStop() throws Exception - { - closeConnection(); - super.doStop(); - } - - /** - * Close an existing connection - */ - private void closeConnection() - { - if (_con != null) - { - if (LOG.isDebugEnabled()) - LOG.debug("Closing db connection for JDBCLoginService"); - try - { - _con.close(); - } - catch (Exception e) - { - LOG.trace("IGNORED", e); - } - } - _con = null; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java index 1c647b32cf1e..b0f988c757b8 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java @@ -15,8 +15,9 @@ import jakarta.servlet.ServletRequest; import org.eclipse.jetty.ee9.nested.Authentication; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.authentication.LoginAuthenticator; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.UserIdentity; /** * LoggedOutAuthentication diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoginService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoginService.java deleted file mode 100644 index bbde5f4d6a6a..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoginService.java +++ /dev/null @@ -1,69 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import jakarta.servlet.ServletRequest; -import org.eclipse.jetty.ee9.nested.UserIdentity; - -/** - * Login Service Interface. - *

    - * The Login service provides an abstract mechanism for an {@link Authenticator} - * to check credentials and to create a {@link UserIdentity} using the - * set {@link IdentityService}. - */ -public interface LoginService -{ - - /** - * @return Get the name of the login service (aka Realm name) - */ - String getName(); - - /** - * Login a user. - * - * @param username The user name - * @param credentials The users credentials - * @param request TODO - * @return A UserIdentity if the credentials matched, otherwise null - */ - UserIdentity login(String username, Object credentials, ServletRequest request); - - /** - * Validate a user identity. - * Validate that a UserIdentity previously created by a call - * to {@link #login(String, Object, ServletRequest)} is still valid. - * - * @param user The user to validate - * @return true if authentication has not been revoked for the user. - */ - boolean validate(UserIdentity user); - - /** - * Get the IdentityService associated with this Login Service. - * - * @return the IdentityService associated with this Login Service. - */ - IdentityService getIdentityService(); - - /** - * Set the IdentityService associated with this Login Service. - * - * @param service the IdentityService associated with this Login Service. - */ - void setIdentityService(IdentityService service); - - void logout(UserIdentity user); -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java deleted file mode 100644 index 4993200cc588..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java +++ /dev/null @@ -1,316 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.eclipse.jetty.util.Scanner; -import org.eclipse.jetty.util.StringUtil; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.Resources; -import org.eclipse.jetty.util.security.Credential; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *

    This class monitors a property file of the format mentioned below - * and notifies registered listeners of the changes to the the given file.

    - * - *
    - *  username: password [,rolename ...]
    - * 
    - * - *

    Passwords may be clear text, obfuscated or checksummed. - * The class {@link org.eclipse.jetty.util.security.Password} should be used - * to generate obfuscated passwords or password checksums.

    - * - *

    If DIGEST Authentication is used, the password must be in a recoverable - * format, either plain text or obfuscated.

    - */ -public class PropertyUserStore extends UserStore implements Scanner.DiscreteListener -{ - private static final Logger LOG = LoggerFactory.getLogger(PropertyUserStore.class); - - protected Resource _configResource; - protected Scanner _scanner; - protected int _refreshInterval = 0; - protected boolean _firstLoad = true; // true if first load, false from that point on - protected List _listeners; - - /** - * Get the config (as a string) - * - * @return the config path as a string - */ - public Resource getConfig() - { - return _configResource; - } - - /** - * Set the Config Path from a String reference to a file - * - * @param config the config file - * TODO: reintroduce setConfig(String) and internal ResourceFactory usage - */ - public void setConfig(Resource config) - { - _configResource = config; - } - - /** - * @return the resource associated with the configured properties file, creating it if necessary - * @deprecated - */ - @Deprecated(forRemoval = true) - public Resource getConfigResource() - { - return getConfig(); - } - - /** - * Is hot reload enabled on this user store - * - * @return true if hot reload was enabled before startup - * @deprecated use {@link #getRefreshInterval()} - */ - @Deprecated - public boolean isHotReload() - { - return getRefreshInterval() > 0; - } - - /** - * Enable Hot Reload of the Property File - * - * @param enable true to enable to a 1 second scan, false to disable - * @deprecated use {@link #setRefreshInterval(int)} - */ - @Deprecated - public void setHotReload(boolean enable) - { - setRefreshInterval(enable ? 1 : 0); - } - - /** - * Enable Hot Reload of the Property File - * - * @param scanSeconds the period in seconds to scan for property file changes, or 0 for no scanning - */ - public void setRefreshInterval(int scanSeconds) - { - if (isRunning()) - { - throw new IllegalStateException("Cannot set scan period while user store is running"); - } - this._refreshInterval = scanSeconds; - } - - /** - * @return the period in seconds to scan for property file changes, or 0 for no scanning - */ - public int getRefreshInterval() - { - return _refreshInterval; - } - - @Override - public String toString() - { - return String.format("%s[cfg=%s]", super.toString(), _configResource); - } - - /** - * Load the user data from the property file. - * @throws IOException If the users cannot be loaded - */ - protected void loadUsers() throws IOException - { - Resource config = getConfig(); - - if (config == null) - throw new IllegalStateException("No config path set"); - - if (LOG.isDebugEnabled()) - LOG.debug("Loading {} from {}", this, config); - - if (Resources.missing(config)) - throw new IllegalStateException("Config does not exist: " + config); - - Properties properties = new Properties(); - try (InputStream inputStream = config.newInputStream()) - { - if (inputStream == null) - throw new IllegalStateException("Config does have properties: " + config); - properties.load(inputStream); - } - - Set known = new HashSet<>(); - - for (Map.Entry entry : properties.entrySet()) - { - String username = ((String)entry.getKey()).trim(); - String credentials = ((String)entry.getValue()).trim(); - String roles = null; - int c = credentials.indexOf(','); - if (c >= 0) - { - roles = credentials.substring(c + 1).trim(); - credentials = credentials.substring(0, c).trim(); - } - - if (username.length() > 0) - { - String[] roleArray = IdentityService.NO_ROLES; - if (roles != null && roles.length() > 0) - roleArray = StringUtil.csvSplit(roles); - known.add(username); - Credential credential = Credential.getCredential(credentials); - addUser(username, credential, roleArray); - notifyUpdate(username, credential, roleArray); - } - } - - List currentlyKnownUsers = new ArrayList<>(_users.keySet()); - // if its not the initial load then we want to process removed users - if (!_firstLoad) - { - for (String user : currentlyKnownUsers) - { - if (!known.contains(user)) - { - removeUser(user); - notifyRemove(user); - } - } - } - - // set initial load to false as there should be no more initial loads - _firstLoad = false; - - if (LOG.isDebugEnabled()) - LOG.debug("Loaded {} from {}", this, config); - } - - /** - * Depending on the value of the refresh interval, this method will either start - * up a scanner thread that will monitor the properties file for changes after - * it has initially loaded it. Otherwise the users will be loaded and there will - * be no active monitoring thread so changes will not be detected. - */ - @Override - protected void doStart() throws Exception - { - Resource config = getConfig(); - if (getRefreshInterval() > 0 && (config != null)) - { - _scanner = new Scanner(null, false); - _scanner.addFile(config.getPath()); - _scanner.setScanInterval(_refreshInterval); - _scanner.setReportExistingFilesOnStartup(false); - _scanner.addListener(this); - addBean(_scanner); - } - - loadUsers(); - super.doStart(); - } - - @Override - public void pathChanged(Path path) throws Exception - { - loadUsers(); - } - - @Override - public void pathAdded(Path path) throws Exception - { - loadUsers(); - } - - @Override - public void pathRemoved(Path path) throws Exception - { - loadUsers(); - } - - @Override - protected void doStop() throws Exception - { - super.doStop(); - removeBean(_scanner); - _scanner = null; - } - - /** - * Notifies the registered listeners of potential updates to a user - * - * @param username the user that was updated - * @param credential the updated credentials - * @param roleArray the updated roles - */ - private void notifyUpdate(String username, Credential credential, String[] roleArray) - { - if (_listeners != null) - { - for (UserListener listener : _listeners) - { - listener.update(username, credential, roleArray); - } - } - } - - /** - * Notifies the registered listeners that a user has been removed. - * - * @param username the user that was removed - */ - private void notifyRemove(String username) - { - if (_listeners != null) - { - for (UserListener listener : _listeners) - { - listener.remove(username); - } - } - } - - /** - * Registers a listener to be notified of the contents of the property file - * - * @param listener the user listener - */ - public void registerUserListener(UserListener listener) - { - if (_listeners == null) - _listeners = new ArrayList<>(); - _listeners.add(listener); - } - - public interface UserListener - { - void update(String username, Credential credential, String[] roleArray); - - void remove(String username); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java index 744e4d9d0577..d70ffab49057 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java @@ -34,8 +34,11 @@ import org.eclipse.jetty.ee9.nested.HandlerWrapper; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.Response; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.authentication.DeferredAuthentication; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.component.DumpableCollection; import org.slf4j.Logger; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserIdentity.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserIdentity.java deleted file mode 100644 index 92d36f405441..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserIdentity.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.ee9.nested.UserIdentity; - -public class SpnegoUserIdentity implements UserIdentity -{ - private final Subject _subject; - private final Principal _principal; - private final UserIdentity _roleDelegate; - - public SpnegoUserIdentity(Subject subject, Principal principal, UserIdentity roleDelegate) - { - _subject = subject; - _principal = principal; - _roleDelegate = roleDelegate; - } - - @Override - public Subject getSubject() - { - return _subject; - } - - @Override - public Principal getUserPrincipal() - { - return _principal; - } - - @Override - public boolean isUserInRole(String role, Scope scope) - { - return _roleDelegate != null && _roleDelegate.isUserInRole(role, scope); - } - - public boolean isEstablished() - { - return _roleDelegate != null; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java index f69df0db16b2..1ab482b2dd83 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java @@ -13,7 +13,7 @@ package org.eclipse.jetty.ee9.security; -import org.eclipse.jetty.ee9.nested.UserIdentity; +import org.eclipse.jetty.security.UserIdentity; /** * @version $Rev: 4793 $ $Date: 2009-03-19 00:00:01 +0100 (Thu, 19 Mar 2009) $ diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java index 527bf9ebfba6..6bb7963ce6d9 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java @@ -16,6 +16,8 @@ import java.util.Set; import org.eclipse.jetty.ee9.security.Authenticator.AuthConfiguration; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; /** * A wrapper for {@link AuthConfiguration}. This allows you create a new AuthConfiguration which can diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/AuthorizationService.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/AuthorizationService.java deleted file mode 100644 index d4732214ef9f..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/AuthorizationService.java +++ /dev/null @@ -1,43 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.authentication; - -import jakarta.servlet.http.HttpServletRequest; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.LoginService; - -/** - *

    A service to query for user roles.

    - */ -@FunctionalInterface -public interface AuthorizationService -{ - /** - * @param request the current HTTP request - * @param name the user name - * @return a {@link UserIdentity} to query for roles of the given user - */ - UserIdentity getUserIdentity(HttpServletRequest request, String name); - - /** - *

    Wraps a {@link LoginService} as an AuthorizationService

    - * - * @param loginService the {@link LoginService} to wrap - * @return an AuthorizationService that delegates the query for roles to the given {@link LoginService} - */ - public static AuthorizationService from(LoginService loginService, Object credentials) - { - return (request, name) -> loginService.login(name, credentials, request); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java index 4d7cad4918eb..ddce0a6ee257 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java @@ -24,10 +24,10 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.security.Constraint; public class BasicAuthenticator extends LoginAuthenticator diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java index 72603f177a52..fd26ae42a171 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -26,14 +26,14 @@ import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.ConfigurableSpnegoLoginService; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.SpnegoUserIdentity; import org.eclipse.jetty.ee9.security.SpnegoUserPrincipal; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.security.ConfigurableSpnegoLoginService; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java index e647aa4ace8f..6d2ce34b70e8 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java @@ -27,13 +27,13 @@ import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.Authentication; -import org.eclipse.jetty.ee9.nested.UserIdentity; -import org.eclipse.jetty.ee9.security.IdentityService; import org.eclipse.jetty.ee9.security.LoggedOutAuthentication; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.SecurityHandler; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DigestAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DigestAuthenticator.java index 655e166f1196..0a455afd2231 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DigestAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DigestAuthenticator.java @@ -32,11 +32,11 @@ import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.SecurityHandler; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.QuotedStringTokenizer; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.security.Constraint; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/FormAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/FormAuthenticator.java index ff0a9e101b9a..f475070ae778 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/FormAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/FormAuthenticator.java @@ -31,13 +31,13 @@ import org.eclipse.jetty.ee9.nested.Authentication.User; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.Response; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpHeaderValue; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java index 1c3e96786505..3bcea42ab0c8 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java @@ -19,10 +19,10 @@ import jakarta.servlet.http.HttpSession; import org.eclipse.jetty.ee9.nested.HttpChannel; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.Authenticator; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Session; import org.eclipse.jetty.session.ManagedSession; import org.slf4j.Logger; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallbackImpl.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallbackImpl.java index 274180e8453a..90a4a80a4e17 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallbackImpl.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallbackImpl.java @@ -16,8 +16,6 @@ import java.security.Principal; import javax.security.auth.Subject; -import org.eclipse.jetty.ee9.security.IdentityService; - /** * This is similar to the jaspi PasswordValidationCallback but includes user * principal and group info as well. @@ -37,7 +35,7 @@ public class LoginCallbackImpl implements LoginCallback private Principal userPrincipal; - private String[] roles = IdentityService.NO_ROLES; + private String[] roles = new String[0]; //TODO could use Credential instance instead of Object if Basic/Form create a Password object public LoginCallbackImpl(Subject subject, String userName, Object credential) diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SessionAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SessionAuthentication.java index 7eeb3db7c626..867182bbad86 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SessionAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SessionAuthentication.java @@ -21,11 +21,11 @@ import jakarta.servlet.http.HttpSessionActivationListener; import jakarta.servlet.http.HttpSessionBindingListener; import jakarta.servlet.http.HttpSessionEvent; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.AbstractUserAuthentication; import org.eclipse.jetty.ee9.security.Authenticator; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.SecurityHandler; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.UserIdentity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SslClientCertAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SslClientCertAuthenticator.java index a08c1c50b32c..cf5fa2154716 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SslClientCertAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SslClientCertAuthenticator.java @@ -24,10 +24,10 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Authentication.User; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.Authenticator; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.util.ssl.SslContextFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java index 01d234bec67d..69a7f391e2e3 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java @@ -44,7 +44,7 @@ import org.eclipse.jetty.ee9.nested.HandlerWrapper; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.SessionHandler; -import org.eclipse.jetty.ee9.nested.UserIdentity; +import org.eclipse.jetty.ee9.nested.UserIdentityScope; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.security.authentication.DigestAuthenticator; import org.eclipse.jetty.ee9.security.authentication.FormAuthenticator; @@ -2015,9 +2015,9 @@ private class RoleRefHandler extends HandlerWrapper @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - UserIdentity.Scope old = ((Request)request).getUserIdentityScope(); + UserIdentityScope old = ((Request)request).getUserIdentityScope(); - UserIdentity.Scope scope = new UserIdentity.Scope() + UserIdentityScope scope = new UserIdentityScope() { @Override public ContextHandler getContextHandler() diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java index 5209988db91c..cee7b6c7a99e 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java @@ -24,11 +24,11 @@ import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.SessionHandler; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; diff --git a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java index 9de80a06b4e9..d5513e9d42ac 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java +++ b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java @@ -50,7 +50,6 @@ import org.eclipse.jetty.ee9.nested.ServletPathMapping; import org.eclipse.jetty.ee9.nested.ServletRequestHttpWrapper; import org.eclipse.jetty.ee9.nested.ServletResponseHttpWrapper; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.IdentityService; import org.eclipse.jetty.ee9.security.SecurityHandler; import org.eclipse.jetty.http.pathmap.MappedResource; @@ -59,6 +58,7 @@ import org.eclipse.jetty.http.pathmap.PathMappings; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.http.pathmap.ServletPathSpec; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.MultiMap; diff --git a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java index 7d21f376c038..d46a9d122499 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java +++ b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java @@ -45,9 +45,9 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.IdentityService; import org.eclipse.jetty.ee9.security.RunAsToken; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.NanoTime; import org.eclipse.jetty.util.StringUtil; diff --git a/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextHandlerTest.java b/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextHandlerTest.java index 4bf832bb48a8..0057e15a23ea 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextHandlerTest.java +++ b/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextHandlerTest.java @@ -65,11 +65,11 @@ import org.eclipse.jetty.ee9.nested.ResourceHandler; import org.eclipse.jetty.ee9.nested.Response; import org.eclipse.jetty.ee9.nested.SessionHandler; -import org.eclipse.jetty.ee9.nested.UserIdentity; import org.eclipse.jetty.ee9.security.RoleInfo; import org.eclipse.jetty.ee9.security.SecurityHandler; import org.eclipse.jetty.http.HttpTester; import org.eclipse.jetty.logging.StacklessLogging; +import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; From ce2eee41eaf79938d091ac40b69a7318138eaece Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 7 Apr 2023 15:18:35 +0200 Subject: [PATCH 028/129] WIP to using core for EE9 --- .../security/openid/OpenIdLoginService.java | 9 +- .../jetty/security/AbstractLoginService.java | 5 +- .../ConfigurableSpnegoLoginService.java | 12 +- .../jetty/security/EmptyLoginService.java | 6 +- .../jetty/security/IdentityService.java | 4 +- .../eclipse/jetty/security/LoginService.java | 10 +- .../authentication/AuthorizationService.java | 11 +- .../ConfigurableSpnegoAuthenticator.java | 2 +- .../authentication/LoginAuthenticator.java | 6 +- .../jetty/security/jaas/JAASLoginService.java | 7 +- .../security/AuthenticationTestHandler.java | 4 +- .../main/java/org/eclipse/jetty/util/IO.java | 18 + jetty-ee8/jetty-ee8-openid/pom.xml | 4 + .../jetty/ee9/demos/OneWebAppWithJsp.java | 2 +- .../jetty/ee9/demos/SecuredHelloHandler.java | 5 +- .../ee9/demos/ServerWithAnnotations.java | 4 +- jetty-ee9/jetty-ee9-jaas/pom.xml | 153 ---- .../src/main/config/etc/jetty-ee9-jaas.xml | 21 - .../src/main/config/modules/ee9-jaas.mod | 21 - .../src/main/java/module-info.java | 27 - .../jetty/ee9/jaas/JAASLoginService.java | 310 ------- .../eclipse/jetty/ee9/jaas/JAASPrincipal.java | 63 -- .../org/eclipse/jetty/ee9/jaas/JAASRole.java | 33 - .../jetty/ee9/jaas/JAASUserPrincipal.java | 68 -- .../ee9/jaas/PropertyUserStoreManager.java | 94 --- .../callback/AbstractCallbackHandler.java | 51 -- .../jaas/callback/DefaultCallbackHandler.java | 74 -- .../ee9/jaas/callback/ObjectCallback.java | 44 - .../callback/RequestParameterCallback.java | 50 -- .../jaas/callback/ServletRequestCallback.java | 38 - .../jetty/ee9/jaas/callback/package-info.java | 18 - .../eclipse/jetty/ee9/jaas/package-info.java | 18 - .../jaas/spi/AbstractDatabaseLoginModule.java | 158 ---- .../ee9/jaas/spi/AbstractLoginModule.java | 291 ------- .../ee9/jaas/spi/DataSourceLoginModule.java | 83 -- .../jetty/ee9/jaas/spi/JDBCLoginModule.java | 102 --- .../jetty/ee9/jaas/spi/LdapLoginModule.java | 756 ------------------ .../ee9/jaas/spi/PropertyFileLoginModule.java | 143 ---- .../jetty/ee9/jaas/spi/package-info.java | 18 - .../ee9/jaas/JAASLdapLoginServiceTest.java | 217 ----- .../jetty/ee9/jaas/JAASLoginServiceTest.java | 161 ---- .../jetty/ee9/jaas/TestLoginModule.java | 59 -- .../jaas/spi/PropertyFileLoginModuleTest.java | 71 -- .../test/resources/jetty-logging.properties | 3 - .../src/test/resources/login.properties | 1 - .../security/jaspi/JaspiAuthenticator.java | 9 +- .../jaspi/JaspiAuthenticatorFactory.java | 4 +- .../jetty/ee9/security/jaspi/JaspiTest.java | 10 +- .../ee9/maven/plugin/AbstractWebAppMojo.java | 2 +- .../jetty/ee9/maven/plugin/JettyEmbedder.java | 2 +- .../jetty/ee9/maven/plugin/ServerSupport.java | 2 +- .../jetty/ee9/nested/SessionHandler.java | 16 + jetty-ee9/jetty-ee9-openid/pom.xml | 8 + .../src/main/java/module-info.java | 5 +- .../jetty/ee9/security/openid/JwtDecoder.java | 101 --- .../openid/OpenIdAuthConfiguration.java | 4 +- .../security/openid/OpenIdAuthenticator.java | 5 +- .../openid/OpenIdAuthenticatorFactory.java | 6 +- .../security/openid/OpenIdConfiguration.java | 291 ------- .../security/openid/OpenIdCredentials.java | 213 ----- .../security/openid/OpenIdLoginService.java | 167 ---- .../security/openid/OpenIdUserIdentity.java | 51 -- .../security/openid/OpenIdUserPrincipal.java | 45 -- .../ee9/security/openid/JwtDecoderTest.java | 117 --- .../openid/OpenIdAuthenticationTest.java | 1 + .../openid/OpenIdCredentialsTest.java | 40 - .../ee9/security/openid/OpenIdProvider.java | 1 + .../security/openid/OpenIdReamNameTest.java | 184 ----- .../plus/security/DataSourceLoginService.java | 8 +- .../org/eclipse/jetty/ee9/runner/Runner.java | 2 +- jetty-ee9/jetty-ee9-security/pom.xml | 4 + .../jetty/ee9/security/RolePrincipal.java | 47 -- .../jetty/ee9/security/RoleRunAsToken.java | 38 - .../jetty/ee9/security/RunAsToken.java | 23 - .../jetty/ee9/security/SecurityHandler.java | 18 +- .../jetty/ee9/security/UserPrincipal.java | 87 -- .../eclipse/jetty/ee9/security/UserStore.java | 87 -- .../ConfigurableSpnegoAuthenticator.java | 8 +- .../DeferredAuthentication.java | 12 +- .../authentication/LoginAuthenticator.java | 8 +- .../security/ClientCertAuthenticatorTest.java | 1 + .../ee9/security/DataConstraintsTest.java | 9 +- .../security/DefaultIdentityServiceTest.java | 2 + .../ee9/security/HashLoginServiceTest.java | 85 -- .../ee9/security/PropertyUserStoreTest.java | 334 -------- .../security/SpecExampleConstraintTest.java | 2 +- .../jetty/ee9/security/TestLoginService.java | 6 +- .../jetty/ee9/security/UserStoreTest.java | 56 -- .../jetty/ee9/servlet/ServletHandler.java | 6 +- .../jetty/ee9/servlet/ServletHolder.java | 30 +- .../ee9/servlet/CustomRequestLogTest.java | 4 +- .../jetty/ee9/test/DigestPostTest.java | 6 +- .../DatabaseLoginServiceTestServer.java | 2 +- .../loginservice/JdbcLoginServiceTest.java | 4 +- .../examples/WebSocketServerExamplesTest.java | 4 +- .../tests/WebSocketServletExamplesTest.java | 4 +- jetty-ee9/pom.xml | 1 - pom.xml | 5 + .../distribution/openid/OpenIdProvider.java | 2 +- 99 files changed, 205 insertions(+), 5239 deletions(-) delete mode 100644 jetty-ee9/jetty-ee9-jaas/pom.xml delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/config/etc/jetty-ee9-jaas.xml delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/config/modules/ee9-jaas.mod delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASPrincipal.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASRole.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/PropertyUserStoreManager.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/AbstractCallbackHandler.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/DefaultCallbackHandler.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ObjectCallback.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/RequestParameterCallback.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ServletRequestCallback.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/package-info.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/package-info.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/DataSourceLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/JDBCLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/LdapLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/package-info.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLdapLoginServiceTest.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLoginServiceTest.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/resources/jetty-logging.properties delete mode 100644 jetty-ee9/jetty-ee9-jaas/src/test/resources/login.properties delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/JwtDecoder.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdConfiguration.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentials.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserPrincipal.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtDecoderTest.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentialsTest.java delete mode 100644 jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdReamNameTest.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RolePrincipal.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RunAsToken.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserPrincipal.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserStore.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/HashLoginServiceTest.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java delete mode 100644 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java index 9e2b75928228..84260420d19c 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdLoginService.java @@ -14,12 +14,13 @@ package org.eclipse.jetty.security.openid; import java.util.Objects; +import java.util.function.Function; import javax.security.auth.Subject; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; -import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -74,10 +75,10 @@ public OpenIdConfiguration getConfiguration() } @Override - public UserIdentity login(String identifier, Object credentials, Request req) + public UserIdentity login(String identifier, Object credentials, Function getSession) { if (LOG.isDebugEnabled()) - LOG.debug("login({}, {}, {})", identifier, credentials, req); + LOG.debug("login({}, {}, {})", identifier, credentials, getSession); OpenIdCredentials openIdCredentials = (OpenIdCredentials)credentials; try @@ -99,7 +100,7 @@ public UserIdentity login(String identifier, Object credentials, Request req) IdentityService identityService = getIdentityService(); if (loginService != null) { - UserIdentity userIdentity = loginService.login(openIdCredentials.getUserId(), "", req); + UserIdentity userIdentity = loginService.login(openIdCredentials.getUserId(), "", getSession); if (userIdentity == null) { if (isAuthenticateNewUsers()) diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java index 5a9649e5fb50..794cce53e89c 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/AbstractLoginService.java @@ -15,9 +15,10 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Function; import javax.security.auth.Subject; -import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,7 +85,7 @@ public String toString() } @Override - public UserIdentity login(String username, Object credentials, Request request) + public UserIdentity login(String username, Object credentials, Function getSession) { if (username == null) return null; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java index 2ddcad6244d9..1f32cdc6ea15 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/ConfigurableSpnegoLoginService.java @@ -20,13 +20,13 @@ import java.util.Base64; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import javax.security.auth.Subject; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.Configuration; import javax.security.auth.login.LoginContext; import org.eclipse.jetty.security.authentication.AuthorizationService; -import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.ietf.jgss.GSSContext; @@ -45,7 +45,7 @@ * for example {@code HTTP/wonder.com}, using a {@code keyTab} file as the service principal * credentials.

    *

    Upon receiving an HTTP request, the server tries to authenticate the client - * calling {@link #login(String, Object, Request)} where the GSS APIs are used to + * calling {@link #login(String, Object, Function)} where the GSS APIs are used to * verify client tokens and (perhaps after a few round-trips) a {@code GSSContext} is * established.

    */ @@ -166,10 +166,10 @@ private PrivilegedAction newSpnegoContext(Subject subject) } @Override - public UserIdentity login(String username, Object credentials, Request request) + public UserIdentity login(String username, Object credentials, Function getSession) { Subject subject = _context._subject; - Session httpSession = request.getSession(false); + Session httpSession = getSession.apply(false); GSSContext gssContext = null; if (httpSession != null) { @@ -191,14 +191,14 @@ public UserIdentity login(String username, Object credentials, Request request) if (httpSession != null) httpSession.removeAttribute(GSSContextHolder.ATTRIBUTE); - UserIdentity roles = _authorizationService.getUserIdentity(request, userName); + UserIdentity roles = _authorizationService.getUserIdentity(userName, getSession); return new SpnegoUserIdentity(subject, principal, roles); } else { // The GSS context is not established yet, save it into the HTTP session. if (httpSession == null) - httpSession = request.getSession(true); + httpSession = getSession.apply(true); GSSContextHolder holder = new GSSContextHolder(gssContext); httpSession.setAttribute(GSSContextHolder.ATTRIBUTE, holder); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java index 78ff375e36a6..560b15ff6510 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/EmptyLoginService.java @@ -13,7 +13,9 @@ package org.eclipse.jetty.security; -import org.eclipse.jetty.server.Request; +import java.util.function.Function; + +import org.eclipse.jetty.server.Session; /** * LoginService implementation which always denies any attempt to login. @@ -27,7 +29,7 @@ public String getName() } @Override - public UserIdentity login(String username, Object credentials, Request request) + public UserIdentity login(String username, Object credentials, Function getSession) { return null; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java index 660e94c5b700..f3462282fa00 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/IdentityService.java @@ -68,8 +68,10 @@ public interface IdentityService UserIdentity getSystemUserIdentity(); - interface Association extends Closeable + interface Association extends AutoCloseable { + @Override + void close(); } interface RunAsToken diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java index 3d260f88a21c..deb4d971ef66 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/LoginService.java @@ -13,7 +13,9 @@ package org.eclipse.jetty.security; -import org.eclipse.jetty.server.Request; +import java.util.function.Function; + +import org.eclipse.jetty.server.Session; /** * Login Service Interface. @@ -35,15 +37,15 @@ public interface LoginService * * @param username The username. * @param credentials The users credentials. - * @param request The request. + * @param getSession function to retrieve or create a session. * @return A UserIdentity if the credentials matched, otherwise null */ - UserIdentity login(String username, Object credentials, Request request); + UserIdentity login(String username, Object credentials, Function getSession); /** * Validate a user identity. * Validate that a UserIdentity previously created by a call - * to {@link #login(String, Object, Request)} is still valid. + * to {@link #login(String, Object, Function)} is still valid. * * @param user The user to validate * @return true if authentication has not been revoked for the user. diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java index 19df8f108658..7382e5253bf9 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/AuthorizationService.java @@ -13,22 +13,25 @@ package org.eclipse.jetty.security.authentication; +import java.util.function.Function; + import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; -import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; /** *

    A service to query for user roles.

    + * TODO do we need this interface? Can it be moved somewhere more private? */ @FunctionalInterface public interface AuthorizationService { /** - * @param request the current HTTP request * @param name the user name + * @param getSession Function to get or create a {@link Session} * @return a {@link UserIdentity} to query for roles of the given user */ - UserIdentity getUserIdentity(Request request, String name); + UserIdentity getUserIdentity(String name, Function getSession); /** *

    Wraps a {@link LoginService} as an AuthorizationService

    @@ -38,6 +41,6 @@ public interface AuthorizationService */ static AuthorizationService from(LoginService loginService, Object credentials) { - return (request, name) -> loginService.login(name, credentials, request); + return (name, getSession) -> loginService.login(name, credentials, getSession); } } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java index 93ed3c3186be..0dab21a4e62d 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -99,7 +99,7 @@ public void setAuthenticationDuration(Duration authenticationDuration) @Override public UserIdentity login(String username, Object password, Request request, Response response) { - SpnegoUserIdentity user = (SpnegoUserIdentity)_loginService.login(username, password, request); + SpnegoUserIdentity user = (SpnegoUserIdentity)_loginService.login(username, password, request::getSession); if (user != null && user.isEstablished()) { renewSession(request, response); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java index 3f0075d359aa..bb1bf38522db 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/LoginAuthenticator.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.security.authentication; +import java.util.function.Function; + import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; @@ -37,7 +39,7 @@ protected LoginAuthenticator() } /** - * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, Request)}, it + * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, Function)}, it * is assumed that the user is fully authenticated and we need to change the session id to prevent * session fixation vulnerability. If the UserIdentity is not necessarily fully * authenticated, then subclasses must override this method and @@ -49,7 +51,7 @@ protected LoginAuthenticator() */ public UserIdentity login(String username, Object password, Request request, Response response) { - UserIdentity user = _loginService.login(username, password, request); + UserIdentity user = _loginService.login(username, password, request::getSession); if (user != null) { renewSession(request, response); diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java index 1f2d7bea0b00..6b8191f9b0b5 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/jaas/JAASLoginService.java @@ -21,6 +21,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.function.Function; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; @@ -36,7 +37,7 @@ import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.security.jaas.callback.DefaultCallbackHandler; -import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.component.ContainerLifeCycle; @@ -181,7 +182,7 @@ protected void doStart() throws Exception } @Override - public UserIdentity login(final String username, final Object credentials, final Request request) + public UserIdentity login(String username, Object credentials, Function getSession) { try { @@ -197,7 +198,7 @@ public UserIdentity login(final String username, final Object credentials, final if (callbackHandler instanceof DefaultCallbackHandler) { DefaultCallbackHandler dch = (DefaultCallbackHandler)callbackHandler; - dch.setRequest(request); + // TODO dch.setRequest(request); dch.setCredential(credentials); dch.setUserName(username); } diff --git a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java index 6f5a64b84f01..5ad041254972 100644 --- a/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java +++ b/jetty-core/jetty-security/src/test/java/org/eclipse/jetty/security/AuthenticationTestHandler.java @@ -16,6 +16,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; +import java.util.function.Function; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.io.Content; @@ -25,6 +26,7 @@ import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Fields; @@ -138,7 +140,7 @@ public String getName() } @Override - public UserIdentity login(String username, Object credentials, Request request) + public UserIdentity login(String username, Object credentials, Function getSession) { if ("admin".equals(username) && "password".equals(credentials)) return new DefaultUserIdentity(null, new UserPrincipal("admin", null), new String[]{"admin"}); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java index f0b1b38af8c9..946f2b567cc8 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java @@ -465,6 +465,24 @@ public static void close(Closeable closeable) } } + /** + * Closes an arbitrary closable, and logs exceptions at ignore level + * + * @param closeable the closeable to close + */ + public static void close(AutoCloseable closeable) + { + try + { + if (closeable != null) + closeable.close(); + } + catch (Exception ignore) + { + LOG.trace("IGNORED", ignore); + } + } + /** * closes an input stream, and logs exceptions * diff --git a/jetty-ee8/jetty-ee8-openid/pom.xml b/jetty-ee8/jetty-ee8-openid/pom.xml index 7cc04b3a22bc..7940f790f400 100644 --- a/jetty-ee8/jetty-ee8-openid/pom.xml +++ b/jetty-ee8/jetty-ee8-openid/pom.xml @@ -37,6 +37,10 @@ org.eclipse.jetty jetty-server
    + + org.eclipse.jetty + jetty-openid + org.eclipse.jetty jetty-client diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJsp.java b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJsp.java index f538e86933e9..6d07e858459d 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJsp.java +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJsp.java @@ -17,8 +17,8 @@ import java.nio.file.Path; import org.eclipse.jetty.ee9.annotations.AnnotationConfiguration; -import org.eclipse.jetty.ee9.security.HashLoginService; import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.resource.Resource; diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandler.java b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandler.java index f5236afccae9..947b34dd9ec0 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandler.java +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandler.java @@ -14,16 +14,15 @@ package org.eclipse.jetty.ee9.demos; import java.io.FileNotFoundException; -import java.net.URL; import java.util.Collections; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.HashLoginService; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.servlet.ServletHolder; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.resource.Resource; import org.eclipse.jetty.util.resource.ResourceFactory; diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotations.java b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotations.java index a0550bddc6d1..f8041369f3ee 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotations.java +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotations.java @@ -14,7 +14,6 @@ package org.eclipse.jetty.ee9.demos; import java.io.FileNotFoundException; -import java.net.URL; import java.nio.file.Path; import javax.naming.NamingException; @@ -25,10 +24,9 @@ import org.eclipse.jetty.ee9.plus.jndi.Transaction; import org.eclipse.jetty.ee9.plus.webapp.EnvConfiguration; import org.eclipse.jetty.ee9.plus.webapp.PlusConfiguration; -import org.eclipse.jetty.ee9.security.HashLoginService; import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.resource.ResourceFactory; /** * ServerWithAnnotations diff --git a/jetty-ee9/jetty-ee9-jaas/pom.xml b/jetty-ee9/jetty-ee9-jaas/pom.xml deleted file mode 100644 index 5af03d2a9051..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/pom.xml +++ /dev/null @@ -1,153 +0,0 @@ - - - org.eclipse.jetty.ee9 - jetty-ee9 - 12.0.0-SNAPSHOT - - - 4.0.0 - jetty-ee9-jaas - EE9 :: JAAS - Jetty JAAS support - - - ${project.groupId}.jaas - 2.0.0.AM26 - 2.1.2 - 2.2.1 - org.eclipse.jetty.ee9.jaas.* - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - false - false - --add-opens java.base/sun.security.x509=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED - - - - - - - - org.eclipse.jetty.ee9 - jetty-ee9-security - - - - org.slf4j - slf4j-api - - - org.eclipse.jetty - jetty-slf4j-impl - test - - - org.eclipse.jetty.toolchain - jetty-test-helper - test - - - org.apache.directory.server - apacheds-test-framework - ${apacheds.version} - test - - - junit - junit - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.server - apacheds-server-integ - ${apacheds.version} - test - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.server - apacheds-core-integ - ${apacheds.version} - test - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.api - api-ldap-schema-data - ${apache.directory.api.version} - test - - - org.apache.directory.api - api-ldap-model - ${apache.directory.api.version} - - - org.apache.directory.api - api-util - ${apache.directory.api.version} - - - org.apache.directory.api - api-asn1-api - ${apache.directory.api.version} - - - org.apache.mina - mina-core - ${mina.core.version} - - - - org.junit.vintage - junit-vintage-engine - ${junit.version} - test - - - diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/config/etc/jetty-ee9-jaas.xml b/jetty-ee9/jetty-ee9-jaas/src/main/config/etc/jetty-ee9-jaas.xml deleted file mode 100644 index 881b23292a05..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/config/etc/jetty-ee9-jaas.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - java.security.auth.login.config - - - - - - - - - diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/config/modules/ee9-jaas.mod b/jetty-ee9/jetty-ee9-jaas/src/main/config/modules/ee9-jaas.mod deleted file mode 100644 index f5cf46a7b840..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/config/modules/ee9-jaas.mod +++ /dev/null @@ -1,21 +0,0 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - -[description] -Enables JAAS for deployed web applications. - -[environment] -ee9 - -[depend] -server - -[lib] -lib/jetty-ee9-jaas-${jetty.version}.jar - -[xml] -etc/jetty-ee9-jaas.xml - -[ini-template] -## The file location (relative to $jetty.base) for the -## JAAS "java.security.auth.login.config" system property -# jetty.jaas.login.conf=etc/login.conf diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java deleted file mode 100644 index 0ba2dee06c17..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java +++ /dev/null @@ -1,27 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -module org.eclipse.jetty.ee9.jaas -{ - requires org.slf4j; - requires org.eclipse.jetty.util; - - requires transitive org.eclipse.jetty.ee9.security; - - // Only required if using JDBCLoginModule. - requires static java.sql; - - exports org.eclipse.jetty.ee9.jaas; - exports org.eclipse.jetty.ee9.jaas.callback; - exports org.eclipse.jetty.ee9.jaas.spi; -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java deleted file mode 100644 index 6ef3bcfca43b..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java +++ /dev/null @@ -1,310 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import java.io.IOException; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.FailedLoginException; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; - -import jakarta.servlet.http.HttpServletRequest; -import org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler; -import org.eclipse.jetty.security.DefaultIdentityService; -import org.eclipse.jetty.security.IdentityService; -import org.eclipse.jetty.security.LoginService; -import org.eclipse.jetty.security.UserIdentity; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.util.ArrayUtil; -import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JAASLoginService - * - * - * Implementation of jetty's LoginService that works with JAAS for - * authorization and authentication. - */ -public class JAASLoginService extends ContainerLifeCycle implements LoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(JAASLoginService.class); - - public static final String DEFAULT_ROLE_CLASS_NAME = "org.eclipse.jetty.ee9.jaas.JAASRole"; - public static final String[] DEFAULT_ROLE_CLASS_NAMES = {DEFAULT_ROLE_CLASS_NAME}; - public static final ThreadLocal INSTANCE = new ThreadLocal<>(); - - protected String[] _roleClassNames = DEFAULT_ROLE_CLASS_NAMES; - protected String _callbackHandlerClass; - protected String _realmName; - protected String _loginModuleName; - protected JAASUserPrincipal _defaultUser = new JAASUserPrincipal(null, null, null); - protected IdentityService _identityService; - protected Configuration _configuration; - - public JAASLoginService() - { - } - - /** - * @param name the name of the realm - */ - public JAASLoginService(String name) - { - this(); - _realmName = name; - _loginModuleName = name; - } - - /** - * Get the name of the realm. - * - * @return name or null if not set. - */ - @Override - public String getName() - { - return _realmName; - } - - /** - * Set the name of the realm - * - * @param name a String value - */ - public void setName(String name) - { - _realmName = name; - } - - /** - * @return the configuration - */ - public Configuration getConfiguration() - { - return _configuration; - } - - /** - * @param configuration the configuration to set - */ - public void setConfiguration(Configuration configuration) - { - _configuration = configuration; - } - - /** - * Get the identityService. - * - * @return the identityService - */ - @Override - public IdentityService getIdentityService() - { - return _identityService; - } - - /** - * Set the identityService. - * - * @param identityService the identityService to set - */ - @Override - public void setIdentityService(IdentityService identityService) - { - _identityService = identityService; - } - - /** - * Set the name to use to index into the config - * file of LoginModules. - * - * @param name a String value - */ - public void setLoginModuleName(String name) - { - _loginModuleName = name; - } - - public void setCallbackHandlerClass(String classname) - { - _callbackHandlerClass = classname; - } - - public void setRoleClassNames(String[] classnames) - { - if (classnames == null || classnames.length == 0) - { - _roleClassNames = DEFAULT_ROLE_CLASS_NAMES; - return; - } - - _roleClassNames = ArrayUtil.addToArray(classnames, DEFAULT_ROLE_CLASS_NAME, String.class); - } - - public String[] getRoleClassNames() - { - return _roleClassNames; - } - - @Override - protected void doStart() throws Exception - { - if (_identityService == null) - _identityService = new DefaultIdentityService(); - addBean(new PropertyUserStoreManager()); - super.doStart(); - } - - @Override - public UserIdentity login(final String username, final Object credentials, final Request request) - { - try - { - CallbackHandler callbackHandler = null; - if (_callbackHandlerClass == null) - callbackHandler = new DefaultCallbackHandler(); - else - { - Class clazz = Loader.loadClass(_callbackHandlerClass); - callbackHandler = (CallbackHandler)clazz.getDeclaredConstructor().newInstance(); - } - - if (callbackHandler instanceof DefaultCallbackHandler) - { - DefaultCallbackHandler dch = (DefaultCallbackHandler)callbackHandler; - if (request instanceof HttpServletRequest httpServletRequest) - dch.setRequest(httpServletRequest); - dch.setCredential(credentials); - dch.setUserName(username); - } - - //set up the login context - Subject subject = new Subject(); - INSTANCE.set(this); - LoginContext loginContext = - (_configuration == null ? new LoginContext(_loginModuleName, subject, callbackHandler) - : new LoginContext(_loginModuleName, subject, callbackHandler, _configuration)); - - loginContext.login(); - - //login success - JAASUserPrincipal userPrincipal = new JAASUserPrincipal(getUserName(callbackHandler), subject, loginContext); - subject.getPrincipals().add(userPrincipal); - - return _identityService.newUserIdentity(subject, userPrincipal, getGroups(subject)); - } - catch (FailedLoginException e) - { - if (LOG.isDebugEnabled()) - LOG.debug("Login failed", e); - } - catch (Exception e) - { - if (LOG.isDebugEnabled()) - LOG.debug("Login error", e); - } - finally - { - INSTANCE.remove(); - } - - return null; - } - - @Override - public boolean validate(UserIdentity user) - { - // TODO optionally check user is still valid - return true; - } - - private String getUserName(CallbackHandler callbackHandler) throws IOException, UnsupportedCallbackException - { - NameCallback nameCallback = new NameCallback("foo"); - callbackHandler.handle(new Callback[]{nameCallback}); - return nameCallback.getName(); - } - - @Override - public void logout(UserIdentity user) - { - Set userPrincipals = user.getSubject().getPrincipals(JAASUserPrincipal.class); - LoginContext loginContext = userPrincipals.iterator().next().getLoginContext(); - try - { - loginContext.logout(); - } - catch (LoginException e) - { - LOG.warn("Failed to logout {}", user, e); - } - } - - /** - * Get all of the groups for the user. - * - * @param subject the Subject representing the user - * @return all the names of groups that the user is in, or 0 length array if none - */ - protected String[] getGroups(Subject subject) - { - Collection groups = new LinkedHashSet<>(); - for (Principal principal : subject.getPrincipals()) - { - if (isRoleClass(principal.getClass(), Arrays.asList(getRoleClassNames()))) - groups.add(principal.getName()); - } - - return groups.toArray(new String[groups.size()]); - } - - /** - * Check whether the class, its superclasses or any interfaces they implement - * is one of the classes that represents a role. - * - * @param clazz the class to check - * @param roleClassNames the list of classnames that represent roles - * @return true if the class is a role class - */ - private static boolean isRoleClass(Class clazz, List roleClassNames) - { - Class c = clazz; - - //add the class, its interfaces and superclasses to the list to test - List classnames = new ArrayList<>(); - while (c != null) - { - classnames.add(c.getName()); - Arrays.stream(c.getInterfaces()).map(Class::getName).forEach(classnames::add); - c = c.getSuperclass(); - } - - return roleClassNames.stream().anyMatch(classnames::contains); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASPrincipal.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASPrincipal.java deleted file mode 100644 index 0bd5ae9a038d..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASPrincipal.java +++ /dev/null @@ -1,63 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import java.io.Serializable; -import java.security.Principal; - -/** - * JAASPrincipal - *

    - * Impl class of Principal interface. - */ -public class JAASPrincipal implements Principal, Serializable -{ - private static final long serialVersionUID = -5538962177019315479L; - - private final String _name; - - public JAASPrincipal(String userName) - { - this._name = userName; - } - - @Override - public boolean equals(Object p) - { - if (!(p instanceof JAASPrincipal)) - return false; - - return getName().equals(((JAASPrincipal)p).getName()); - } - - @Override - public int hashCode() - { - return getName().hashCode(); - } - - @Override - public String getName() - { - return this._name; - } - - @Override - public String toString() - { - return getName(); - } -} - - diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASRole.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASRole.java deleted file mode 100644 index f5f82389d4c2..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASRole.java +++ /dev/null @@ -1,33 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -public class JAASRole extends JAASPrincipal -{ - private static final long serialVersionUID = 3465114254970134526L; - - public JAASRole(String name) - { - super(name); - } - - @Override - public boolean equals(Object o) - { - if (!(o instanceof JAASRole)) - return false; - - return getName().equals(((JAASRole)o).getName()); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java deleted file mode 100644 index 3fcfb9f1e6e0..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import java.security.Principal; -import javax.security.auth.Subject; -import javax.security.auth.login.LoginContext; - -/** - * JAASUserPrincipal - *

    - * Implements the JAAS version of the - * org.eclipse.jetty.security.UserPrincipal interface. - */ -public class JAASUserPrincipal implements Principal -{ - private final String _name; - private final Subject _subject; - private final LoginContext _loginContext; - - public JAASUserPrincipal(String name, Subject subject, LoginContext loginContext) - { - this._name = name; - this._subject = subject; - this._loginContext = loginContext; - } - - /** - * Get the name identifying the user - */ - @Override - public String getName() - { - return _name; - } - - /** - * Provide access to the Subject - * - * @return subject - */ - public Subject getSubject() - { - return this._subject; - } - - LoginContext getLoginContext() - { - return this._loginContext; - } - - @Override - public String toString() - { - return getName(); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/PropertyUserStoreManager.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/PropertyUserStoreManager.java deleted file mode 100644 index c4b8e6930a6b..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/PropertyUserStoreManager.java +++ /dev/null @@ -1,94 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import org.eclipse.jetty.ee9.security.PropertyUserStore; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * PropertyUserStoreManager - * - * Maintains a map of PropertyUserStores, keyed off the location of the property file containing - * the authentication and authorization information. - * - * This class is used to enable the PropertyUserStores to be cached and shared. This is essential - * for the PropertyFileLoginModules, whose lifecycle is controlled by the JAAS api and instantiated - * afresh whenever a user needs to be authenticated. Without this class, every PropertyFileLoginModule - * instantiation would re-read and reload in all the user information just to authenticate a single user. - */ -public class PropertyUserStoreManager extends AbstractLifeCycle -{ - private static final Logger LOG = LoggerFactory.getLogger(PropertyUserStoreManager.class); - /** - * Map of user authentication and authorization information loaded in from a property file. - * The map is keyed off the location of the file. - */ - private Map _propertyUserStores; - - public PropertyUserStore getPropertyUserStore(String file) - { - synchronized (this) - { - if (_propertyUserStores == null) - return null; - - return _propertyUserStores.get(file); - } - } - - public PropertyUserStore addPropertyUserStore(String file, PropertyUserStore store) - { - synchronized (this) - { - Objects.requireNonNull(_propertyUserStores); - PropertyUserStore existing = _propertyUserStores.get(file); - if (existing != null) - return existing; - - _propertyUserStores.put(file, store); - return store; - } - } - - @Override - protected void doStart() throws Exception - { - _propertyUserStores = new HashMap(); - super.doStart(); - } - - @Override - protected void doStop() throws Exception - { - for (Map.Entry entry : _propertyUserStores.entrySet()) - { - try - { - entry.getValue().stop(); - } - catch (Exception e) - { - LOG.warn("Error stopping PropertyUserStore at {}", entry.getKey(), e); - } - } - _propertyUserStores = null; - super.doStop(); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/AbstractCallbackHandler.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/AbstractCallbackHandler.java deleted file mode 100644 index 36bf8674dbfd..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/AbstractCallbackHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.callback; - -import java.io.IOException; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; - -public abstract class AbstractCallbackHandler implements CallbackHandler -{ - protected String _userName; - protected Object _credential; - - public void setUserName(String userName) - { - _userName = userName; - } - - public String getUserName() - { - return _userName; - } - - public void setCredential(Object credential) - { - _credential = credential; - } - - public Object getCredential() - { - return _credential; - } - - @Override - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException - { - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/DefaultCallbackHandler.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/DefaultCallbackHandler.java deleted file mode 100644 index a444cab05034..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/DefaultCallbackHandler.java +++ /dev/null @@ -1,74 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.callback; - -import java.io.IOException; -import java.util.Arrays; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; - -import jakarta.servlet.http.HttpServletRequest; - -/** - * DefaultCallbackHandler - * - * An implementation of the JAAS CallbackHandler. Users can provide - * their own implementation instead and set the name of its class on the JAASLoginService. - */ -public class DefaultCallbackHandler extends AbstractCallbackHandler -{ - private HttpServletRequest _request; - - public void setRequest(HttpServletRequest request) - { - _request = request; - } - - @Override - public void handle(Callback[] callbacks) - throws IOException, UnsupportedCallbackException - { - for (Callback callback : callbacks) - { - if (callback instanceof NameCallback) - { - ((NameCallback)callback).setName(getUserName()); - } - else if (callback instanceof ObjectCallback) - { - ((ObjectCallback)callback).setObject(getCredential()); - } - else if (callback instanceof PasswordCallback) - { - ((PasswordCallback)callback).setPassword(getCredential().toString().toCharArray()); - } - else if (callback instanceof RequestParameterCallback) - { - if (_request != null) - { - RequestParameterCallback rpc = (RequestParameterCallback)callback; - rpc.setParameterValues(Arrays.asList(_request.getParameterValues(rpc.getParameterName()))); - } - } - else if (callback instanceof ServletRequestCallback) - { - ((ServletRequestCallback)callback).setRequest(_request); - } - else - throw new UnsupportedCallbackException(callback); - } - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ObjectCallback.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ObjectCallback.java deleted file mode 100644 index 17a096b3ab3a..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ObjectCallback.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.callback; - -import javax.security.auth.callback.Callback; - -/** - * ObjectCallback - *

    - * Can be used as a LoginModule Callback to - * obtain a user's credential as an Object, rather than - * a char[], to which some credentials may not be able - * to be converted - */ -public class ObjectCallback implements Callback -{ - protected Object _object; - - public void setObject(Object o) - { - _object = o; - } - - public Object getObject() - { - return _object; - } - - public void clearObject() - { - _object = null; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/RequestParameterCallback.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/RequestParameterCallback.java deleted file mode 100644 index 0ac9748ccf17..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/RequestParameterCallback.java +++ /dev/null @@ -1,50 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.callback; - -import java.util.List; -import javax.security.auth.callback.Callback; - -/** - * RequestParameterCallback - *

    - * Allows a JAAS callback handler to access any parameter from the j_security_check FORM. - * This means that a LoginModule can access form fields other than the j_username and j_password - * fields, and use it, for example, to authenticate a user. - */ -public class RequestParameterCallback implements Callback -{ - private String _paramName; - private List _paramValues; - - public void setParameterName(String name) - { - _paramName = name; - } - - public String getParameterName() - { - return _paramName; - } - - public void setParameterValues(List values) - { - _paramValues = values; - } - - public List getParameterValues() - { - return _paramValues; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ServletRequestCallback.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ServletRequestCallback.java deleted file mode 100644 index 141e8652a1d5..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ServletRequestCallback.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.callback; - -import javax.security.auth.callback.Callback; - -import jakarta.servlet.ServletRequest; - -/** - * ServletRequestCallback - * - * Provides access to the request associated with the authentication. - */ -public class ServletRequestCallback implements Callback -{ - protected ServletRequest _request; - - public void setRequest(ServletRequest request) - { - _request = request; - } - - public ServletRequest getRequest() - { - return _request; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/package-info.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/package-info.java deleted file mode 100644 index 514c9e8b52ec..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -/** - * Jetty Jaas : Jaas Callbacks - */ -package org.eclipse.jetty.ee9.jaas.callback; - diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/package-info.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/package-info.java deleted file mode 100644 index 75b115223fd1..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -/** - * Jetty Jaas : Support for Jaas - */ -package org.eclipse.jetty.ee9.jaas; - diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java deleted file mode 100644 index a899c0456036..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java +++ /dev/null @@ -1,158 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; - -import org.eclipse.jetty.ee9.security.UserPrincipal; -import org.eclipse.jetty.util.security.Credential; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractDatabaseLoginModule - * - *

    - * Abstract base class for LoginModules that interact with a - * database to retrieve authentication and authorization information. - * Used by the JDBCLoginModule and DataSourceLoginModule. - *

    - */ -public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule -{ - private static final Logger LOG = LoggerFactory.getLogger(AbstractDatabaseLoginModule.class); - - private String userQuery; - private String rolesQuery; - private String dbUserTable; - private String dbUserTableUserField; - private String dbUserTableCredentialField; - private String dbUserRoleTable; - private String dbUserRoleTableUserField; - private String dbUserRoleTableRoleField; - - /** - * @return a java.sql.Connection from the database - * @throws Exception if unable to get the connection - */ - public abstract Connection getConnection() throws Exception; - - public class JDBCUser extends JAASUser - { - public JDBCUser(UserPrincipal user) - { - super(user); - } - - @Override - public List doFetchRoles() - throws Exception - { - return getRoles(getUserName()); - } - } - - /** - * Load info from database - * - * @param userName user info to load - * @throws Exception if unable to get the user info - */ - @Override - public JAASUser getUser(String userName) - throws Exception - { - try (Connection connection = getConnection()) - { - - //query for credential - String dbCredential = null; - try (PreparedStatement statement = connection.prepareStatement(userQuery)) - { - statement.setString(1, userName); - try (ResultSet results = statement.executeQuery()) - { - if (results.next()) - { - dbCredential = results.getString(1); - } - } - } - - if (dbCredential == null) - return null; - - return new JDBCUser(new UserPrincipal(userName, Credential.getCredential(dbCredential))); - } - } - - public List getRoles(String userName) - throws Exception - { - List roles = new ArrayList(); - - try (Connection connection = getConnection()) - { - //query for role names - - try (PreparedStatement statement = connection.prepareStatement(rolesQuery)) - { - statement.setString(1, userName); - try (ResultSet results = statement.executeQuery()) - { - while (results.next()) - { - String roleName = results.getString(1); - roles.add(roleName); - } - } - } - } - - return roles; - } - - @Override - public void initialize(Subject subject, - CallbackHandler callbackHandler, - Map sharedState, - Map options) - { - super.initialize(subject, callbackHandler, sharedState, options); - - //get the user credential query out of the options - dbUserTable = (String)options.get("userTable"); - dbUserTableUserField = (String)options.get("userField"); - dbUserTableCredentialField = (String)options.get("credentialField"); - - userQuery = "select " + dbUserTableCredentialField + " from " + dbUserTable + " where " + dbUserTableUserField + "=?"; - - //get the user roles query out of the options - dbUserRoleTable = (String)options.get("userRoleTable"); - dbUserRoleTableUserField = (String)options.get("userRoleUserField"); - dbUserRoleTableRoleField = (String)options.get("userRoleRoleField"); - - rolesQuery = "select " + dbUserRoleTableRoleField + " from " + dbUserRoleTable + " where " + dbUserRoleTableUserField + "=?"; - - if (LOG.isDebugEnabled()) - LOG.debug("userQuery = {} rolesQuery = {}", userQuery, rolesQuery); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java deleted file mode 100644 index 56bf43c509c7..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java +++ /dev/null @@ -1,291 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.FailedLoginException; -import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; - -import org.eclipse.jetty.ee9.jaas.JAASRole; -import org.eclipse.jetty.ee9.jaas.callback.ObjectCallback; -import org.eclipse.jetty.ee9.security.UserPrincipal; - -/** - * AbstractLoginModule - * - * Abstract base class for all LoginModules. Subclasses should - * just need to implement getUserInfo method. - */ -public abstract class AbstractLoginModule implements LoginModule -{ - private CallbackHandler callbackHandler; - - private boolean authState = false; - private boolean commitState = false; - private JAASUser currentUser; - private Subject subject; - - public abstract static class JAASUser - { - private final UserPrincipal _user; - private List _roles; - - public JAASUser(UserPrincipal u) - { - _user = u; - } - - public String getUserName() - { - return _user.getName(); - } - - /** - * @param subject The subject - */ - public void setJAASInfo(Subject subject) - { - if (_user == null) - return; - - _user.configureSubject(subject); - if (_roles != null) - subject.getPrincipals().addAll(_roles); - } - - /** - * @param subject The subject - */ - public void unsetJAASInfo(Subject subject) - { - if (_user == null) - return; - _user.deconfigureSubject(subject); - if (_roles != null) - subject.getPrincipals().removeAll(_roles); - } - - public boolean checkCredential(Object suppliedCredential) - { - return _user.authenticate(suppliedCredential); - } - - public void fetchRoles() throws Exception - { - List rolenames = doFetchRoles(); - if (rolenames != null) - _roles = rolenames.stream().map(JAASRole::new).collect(Collectors.toList()); - } - - public abstract List doFetchRoles() throws Exception; - } - - public abstract JAASUser getUser(String username) throws Exception; - - public Subject getSubject() - { - return this.subject; - } - - public void setSubject(Subject s) - { - this.subject = s; - } - - public JAASUser getCurrentUser() - { - return this.currentUser; - } - - public void setCurrentUser(JAASUser u) - { - this.currentUser = u; - } - - public CallbackHandler getCallbackHandler() - { - return this.callbackHandler; - } - - public void setCallbackHandler(CallbackHandler h) - { - this.callbackHandler = h; - } - - public boolean isAuthenticated() - { - return this.authState; - } - - public boolean isCommitted() - { - return this.commitState; - } - - public void setAuthenticated(boolean authState) - { - this.authState = authState; - } - - public void setCommitted(boolean commitState) - { - this.commitState = commitState; - } - - @Override - public boolean abort() throws LoginException - { - this.currentUser = null; - return (isAuthenticated() && isCommitted()); - } - - /** - * @return true if committed, false if not (likely not authenticated) - * @throws LoginException if unable to commit - * @see javax.security.auth.spi.LoginModule#commit() - */ - @Override - public boolean commit() throws LoginException - { - if (!isAuthenticated()) - { - currentUser = null; - setCommitted(false); - return false; - } - - setCommitted(true); - currentUser.setJAASInfo(subject); - return true; - } - - public Callback[] configureCallbacks() - { - Callback[] callbacks = new Callback[3]; - callbacks[0] = new NameCallback("Enter user name"); - callbacks[1] = new ObjectCallback(); - callbacks[2] = new PasswordCallback("Enter password", false); //only used if framework does not support the ObjectCallback - return callbacks; - } - - public boolean isIgnored() - { - return false; - } - - /** - * @return true if is authenticated, false otherwise - * @throws LoginException if unable to login - * @see javax.security.auth.spi.LoginModule#login() - */ - @Override - public boolean login() throws LoginException - { - try - { - if (isIgnored()) - return false; - - if (callbackHandler == null) - throw new LoginException("No callback handler"); - - Callback[] callbacks = configureCallbacks(); - callbackHandler.handle(callbacks); - - String webUserName = ((NameCallback)callbacks[0]).getName(); - Object webCredential = null; - - webCredential = ((ObjectCallback)callbacks[1]).getObject(); //first check if ObjectCallback has the credential - if (webCredential == null) - webCredential = ((PasswordCallback)callbacks[2]).getPassword(); //use standard PasswordCallback - - if ((webUserName == null) || (webCredential == null)) - { - setAuthenticated(false); - throw new FailedLoginException(); - } - - JAASUser user = getUser(webUserName); - - if (user == null) - { - setAuthenticated(false); - throw new FailedLoginException(); - } - - currentUser = user; - setAuthenticated(currentUser.checkCredential(webCredential)); - - if (isAuthenticated()) - { - currentUser.fetchRoles(); - return true; - } - else - throw new FailedLoginException(); - } - catch (IOException e) - { - throw new LoginException(e.toString()); - } - catch (UnsupportedCallbackException e) - { - throw new LoginException(e.toString()); - } - catch (Exception e) - { - if (e instanceof LoginException) - throw (LoginException)e; - throw new LoginException(e.toString()); - } - } - - /** - * @return true always - * @throws LoginException if unable to logout - * @see javax.security.auth.spi.LoginModule#logout() - */ - @Override - public boolean logout() throws LoginException - { - this.currentUser.unsetJAASInfo(this.subject); - this.currentUser = null; - return true; - } - - /** - * @param subject the subject - * @param callbackHandler the callback handler - * @param sharedState the shared state map - * @param options the option map - * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map) - */ - @Override - public void initialize(Subject subject, CallbackHandler callbackHandler, - Map sharedState, Map options) - { - this.callbackHandler = callbackHandler; - this.subject = subject; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/DataSourceLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/DataSourceLoginModule.java deleted file mode 100644 index 0ca8514afd3c..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/DataSourceLoginModule.java +++ /dev/null @@ -1,83 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.sql.Connection; -import java.util.Map; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; -import javax.sql.DataSource; - -/** - * DataSourceLoginModule - * - * A LoginModule that uses a DataSource to retrieve user authentication - * and authorisation information. - * - * @see JDBCLoginModule - */ -public class DataSourceLoginModule extends AbstractDatabaseLoginModule -{ - - private String dbJNDIName; - private DataSource dataSource; - - /** - * Init LoginModule. - *

    - * Called once by JAAS after new instance created. - * - * @param subject the subject - * @param callbackHandler the callback handler - * @param sharedState the shared state map - * @param options the option map - */ - @Override - public void initialize(Subject subject, - CallbackHandler callbackHandler, - Map sharedState, - Map options) - { - try - { - super.initialize(subject, callbackHandler, sharedState, options); - - //get the datasource jndi name - dbJNDIName = (String)options.get("dbJNDIName"); - - InitialContext ic = new InitialContext(); - dataSource = (DataSource)ic.lookup("java:comp/env/" + dbJNDIName); - } - catch (NamingException e) - { - throw new IllegalStateException(e.toString()); - } - } - - /** - * Get a connection from the DataSource - * - * @return the connection for the datasource - * @throws Exception if unable to get the connection - * @see AbstractDatabaseLoginModule#getConnection() - */ - @Override - public Connection getConnection() - throws Exception - { - return dataSource.getConnection(); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/JDBCLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/JDBCLoginModule.java deleted file mode 100644 index 76316f5bf4a6..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/JDBCLoginModule.java +++ /dev/null @@ -1,102 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.Map; -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; - -import org.eclipse.jetty.util.Loader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *

    JAAS LoginModule to retrieve user information from - * a database and authenticate the user.

    - *

    Notes

    - *

    This version uses plain old JDBC connections NOT DataSources.

    - */ -public class JDBCLoginModule extends AbstractDatabaseLoginModule -{ - private static final Logger LOG = LoggerFactory.getLogger(JDBCLoginModule.class); - - private String dbDriver; - private String dbUrl; - private String dbUserName; - private String dbPassword; - - /** - * Get a connection from the DriverManager - * - * @return the connection for this datasource - * @throws Exception if unable to get the connection - */ - @Override - public Connection getConnection() - throws Exception - { - if (!((dbDriver != null) && (dbUrl != null))) - throw new IllegalStateException("Database connection information not configured"); - - if (LOG.isDebugEnabled()) - LOG.debug("Connecting using dbDriver={} dbUserName={}, dbPassword={}", dbDriver, dbUserName, dbUrl); - - return DriverManager.getConnection(dbUrl, - dbUserName, - dbPassword); - } - - /** - * Init LoginModule. - *

    - * Called once by JAAS after new instance created. - * - * @param subject the subject - * @param callbackHandler the callback handler - * @param sharedState the shared state map - * @param options the options map - */ - @Override - public void initialize(Subject subject, - CallbackHandler callbackHandler, - Map sharedState, - Map options) - { - try - { - super.initialize(subject, callbackHandler, sharedState, options); - - //get the jdbc username/password, jdbc url out of the options - dbDriver = (String)options.get("dbDriver"); - dbUrl = (String)options.get("dbUrl"); - dbUserName = (String)options.get("dbUserName"); - dbPassword = (String)options.get("dbPassword"); - - if (dbUserName == null) - dbUserName = ""; - - if (dbPassword == null) - dbPassword = ""; - - if (dbDriver != null) - Loader.loadClass(dbDriver).getDeclaredConstructor().newInstance(); - } - catch (Exception e) - { - throw new IllegalStateException(e.toString()); - } - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/LdapLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/LdapLoginModule.java deleted file mode 100644 index 2ca40ac1595b..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/LdapLoginModule.java +++ /dev/null @@ -1,756 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Hashtable; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; -import javax.naming.AuthenticationException; -import javax.naming.Context; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.FailedLoginException; -import javax.security.auth.login.LoginException; - -import org.eclipse.jetty.ee9.jaas.callback.ObjectCallback; -import org.eclipse.jetty.ee9.security.UserPrincipal; -import org.eclipse.jetty.util.TypeUtil; -import org.eclipse.jetty.util.security.Credential; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A LdapLoginModule for use with JAAS setups - *

    - * The jvm should be started with the following parameter: - *

    - * -Djava.security.auth.login.config=etc/ldap-loginModule.conf
    - * 
    - * and an example of the ldap-loginModule.conf would be: - *
    - * ldaploginmodule {
    - *    org.eclipse.jetty.server.server.plus.jaas.spi.LdapLoginModule required
    - *    debug="true"
    - *    useLdaps="false"
    - *    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
    - *    hostname="ldap.example.com"
    - *    port="389"
    - *    bindDn="cn=Directory Manager"
    - *    bindPassword="directory"
    - *    authenticationMethod="simple"
    - *    forceBindingLogin="false"
    - *    userBaseDn="ou=people,dc=alcatel"
    - *    userRdnAttribute="uid"
    - *    userIdAttribute="uid"
    - *    userPasswordAttribute="userPassword"
    - *    userObjectClass="inetOrgPerson"
    - *    roleBaseDn="ou=groups,dc=example,dc=com"
    - *    roleNameAttribute="cn"
    - *    roleMemberAttribute="uniqueMember"
    - *    roleObjectClass="groupOfUniqueNames";
    - *    };
    - * 
    - */ -public class LdapLoginModule extends AbstractLoginModule -{ - private static final Logger LOG = LoggerFactory.getLogger(LdapLoginModule.class); - - /** - * hostname of the ldap server - */ - private String _hostname; - - /** - * port of the ldap server - */ - private int _port; - - /** - * Context.SECURITY_AUTHENTICATION - */ - private String _authenticationMethod; - - /** - * Context.INITIAL_CONTEXT_FACTORY - */ - private String _contextFactory; - - /** - * root DN used to connect to - */ - private String _bindDn; - - /** - * password used to connect to the root ldap context - */ - private String _bindPassword; - - /** - * object class of a user - */ - private String _userObjectClass = "inetOrgPerson"; - - /** - * attribute that the principal is located - */ - private String _userRdnAttribute = "uid"; - - /** - * attribute that the principal is located - */ - private String _userIdAttribute = "cn"; - - /** - * name of the attribute that a users password is stored under - *

    - * NOTE: not always accessible, see force binding login - */ - private String _userPasswordAttribute = "userPassword"; - - /** - * base DN where users are to be searched from - */ - private String _userBaseDn; - - /** - * base DN where role membership is to be searched from - */ - private String _roleBaseDn; - - /** - * object class of roles - */ - private String _roleObjectClass = "groupOfUniqueNames"; - - /** - * name of the attribute that a username would be under a role class - */ - private String _roleMemberAttribute = "uniqueMember"; - - /** - * the name of the attribute that a role would be stored under - */ - private String _roleNameAttribute = "roleName"; - - private boolean _debug; - - /** - * if the getUserInfo can pull a password off of the user then - * password comparison is an option for authn, to force binding - * login checks, set this to true - */ - private boolean _forceBindingLogin = false; - - /** - * When true changes the protocol to ldaps - */ - private boolean _useLdaps = false; - - private DirContext _rootContext; - - public class LDAPUser extends JAASUser - { - Attributes attributes; - - public LDAPUser(UserPrincipal user, Attributes attributes) - { - super(user); - this.attributes = attributes; - } - - @Override - public List doFetchRoles() throws Exception - { - return getUserRoles(_rootContext, getUserName(), attributes); - } - } - - public class LDAPBindingUser extends JAASUser - { - DirContext _context; - String _userDn; - - public LDAPBindingUser(UserPrincipal user, DirContext context, String userDn) - { - super(user); - _context = context; - _userDn = userDn; - } - - @Override - public List doFetchRoles() throws Exception - { - return getUserRolesByDn(_context, _userDn); - } - } - - /** - * get the available information about the user - *

    - * for this LoginModule, the credential can be null which will result in a - * binding ldap authentication scenario - *

    - * roles are also an optional concept if required - * - * @param username the user name - * @return the userinfo for the username - * @throws Exception if unable to get the user info - */ - @Override - public JAASUser getUser(String username) throws Exception - { - Attributes attributes = getUserAttributes(username); - String pwdCredential = getUserCredentials(attributes); - - if (pwdCredential == null) - return null; - - pwdCredential = convertCredentialLdapToJetty(pwdCredential); - Credential credential = Credential.getCredential(pwdCredential); - return new LDAPUser(new UserPrincipal(username, credential), attributes); - } - - protected String doRFC2254Encoding(String inputString) - { - StringBuffer buf = new StringBuffer(inputString.length()); - for (int i = 0; i < inputString.length(); i++) - { - char c = inputString.charAt(i); - switch (c) - { - case '\\': - buf.append("\\5c"); - break; - case '*': - buf.append("\\2a"); - break; - case '(': - buf.append("\\28"); - break; - case ')': - buf.append("\\29"); - break; - case '\0': - buf.append("\\00"); - break; - default: - buf.append(c); - break; - } - } - return buf.toString(); - } - - /** - * attempts to get the users LDAP attributes from the users context - *

    - * NOTE: this is not an user authenticated operation - * - * @return the {@link Attributes} from the user - */ - private Attributes getUserAttributes(String username) throws LoginException - { - SearchResult result = findUser(username); - Attributes attributes = result.getAttributes(); - return attributes; - } - - private String getUserCredentials(Attributes attributes) throws LoginException - { - String ldapCredential = null; - - Attribute attribute = attributes.get(_userPasswordAttribute); - if (attribute != null) - { - try - { - byte[] value = (byte[])attribute.get(); - - ldapCredential = new String(value); - } - catch (NamingException e) - { - LOG.debug("no password available under attribute: {}", _userPasswordAttribute); - } - } - - if (LOG.isDebugEnabled()) - LOG.debug("user cred is: {}", ldapCredential); - - return ldapCredential; - } - - /** - * attempts to get the users roles from the root context - *

    - * NOTE: this is not an user authenticated operation - */ - private List getUserRoles(DirContext dirContext, String username, Attributes attributes) throws LoginException, NamingException - { - String rdnValue = username; - Attribute attribute = attributes.get(_userRdnAttribute); - if (attribute != null) - { - try - { - rdnValue = (String)attribute.get(); // switch to the value stored in the _userRdnAttribute if we can - } - catch (NamingException ignored) - { - } - } - - String filter = "({0}={1})"; - - Object[] filterArguments = new Object[]{ - _userRdnAttribute, - rdnValue - }; - - SearchResult searchResult = findUser(dirContext, filter, filterArguments); - - return getUserRolesByDn(dirContext, searchResult.getNameInNamespace()); - } - - private List getUserRolesByDn(DirContext dirContext, String userDn) throws NamingException - { - List roleList = new ArrayList<>(); - - if (dirContext == null || _roleBaseDn == null || _roleMemberAttribute == null || _roleObjectClass == null) - { - return roleList; - } - - SearchControls ctls = new SearchControls(); - ctls.setDerefLinkFlag(true); - ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); - ctls.setReturningAttributes(new String[]{_roleNameAttribute}); - - String filter = "(&(objectClass={0})({1}={2}))"; - Object[] filterArguments = {_roleObjectClass, _roleMemberAttribute, userDn}; - NamingEnumeration results = dirContext.search(_roleBaseDn, filter, filterArguments, ctls); - - if (LOG.isDebugEnabled()) - LOG.debug("Found user roles?: {}", results.hasMoreElements()); - - while (results.hasMoreElements()) - { - SearchResult result = results.nextElement(); - - Attributes attributes = result.getAttributes(); - - if (attributes == null) - { - continue; - } - - Attribute roleAttribute = attributes.get(_roleNameAttribute); - - if (roleAttribute == null) - { - continue; - } - - NamingEnumeration roles = roleAttribute.getAll(); - while (roles.hasMore()) - { - roleList.add(roles.next().toString()); - } - } - - return roleList; - } - - /** - * since ldap uses a context bind for valid authentication checking, we override login() - *

    - * if credentials are not available from the users context or if we are forcing the binding check - * then we try a binding authentication check, otherwise if we have the users encoded password then - * we can try authentication via that mechanic - * - * @return true if authenticated, false otherwise - * @throws LoginException if unable to login - */ - @Override - public boolean login() throws LoginException - { - try - { - if (getCallbackHandler() == null) - { - throw new LoginException("No callback handler"); - } - - Callback[] callbacks = configureCallbacks(); - getCallbackHandler().handle(callbacks); - - String webUserName = ((NameCallback)callbacks[0]).getName(); - Object webCredential = ((ObjectCallback)callbacks[1]).getObject(); - - if (webUserName == null || webCredential == null) - { - setAuthenticated(false); - return isAuthenticated(); - } - - boolean authed = false; - - if (_forceBindingLogin) - { - authed = bindingLogin(webUserName, webCredential); - } - else - { - // This sets read and the credential - JAASUser userInfo = getUser(webUserName); - - if (userInfo == null) - { - setAuthenticated(false); - return false; - } - - setCurrentUser(userInfo); - - if (webCredential instanceof String) - authed = credentialLogin(Credential.getCredential((String)webCredential)); - else - authed = credentialLogin(webCredential); - } - - //only fetch roles if authenticated - if (authed) - getCurrentUser().fetchRoles(); - - return authed; - } - catch (UnsupportedCallbackException e) - { - throw new LoginException("Error obtaining callback information."); - } - catch (IOException e) - { - if (_debug) - LOG.info("Login failure", e); - throw new LoginException("IO Error performing login."); - } - catch (AuthenticationException e) - { - if (_debug) - LOG.info("Login failure", e); - return false; - } - catch (LoginException e) - { - throw e; - } - catch (Exception e) - { - if (_debug) - LOG.info("Login failure", e); - throw new LoginException("Error obtaining user info"); - } - } - - /** - * password supplied authentication check - * - * @param webCredential the web credential - * @return true if authenticated - * @throws LoginException if unable to login - */ - protected boolean credentialLogin(Object webCredential) throws LoginException - { - setAuthenticated(getCurrentUser().checkCredential(webCredential)); - return isAuthenticated(); - } - - /** - * binding authentication check - * This method of authentication works only if the user branch of the DIT (ldap tree) - * has an ACI (access control instruction) that allow the access to any user or at least - * for the user that logs in. - * - * @param username the user name - * @param password the password - * @return true always - * @throws LoginException if unable to bind the login - */ - public boolean bindingLogin(String username, Object password) throws LoginException - { - SearchResult searchResult = findUser(username); - - String userDn = searchResult.getNameInNamespace(); - - LOG.info("Attempting authentication: {}", userDn); - - Hashtable environment = getEnvironment(); - - if (userDn == null || "".equals(userDn)) - { - throw new FailedLoginException("username may not be empty"); - } - environment.put(Context.SECURITY_PRINCIPAL, userDn); - // RFC 4513 section 6.3.1, protect against ldap server implementations that allow successful binding on empty passwords - if (password == null || "".equals(password)) - { - throw new FailedLoginException("password may not be empty"); - } - environment.put(Context.SECURITY_CREDENTIALS, password); - - try - { - DirContext dirContext = new InitialDirContext(environment); - setCurrentUser(new LDAPBindingUser(new UserPrincipal(username, null), dirContext, userDn)); - setAuthenticated(true); - return true; - } - catch (javax.naming.AuthenticationException e) - { - throw new FailedLoginException(e.getMessage()); - } - catch (NamingException e) - { - throw new FailedLoginException(e.getMessage()); - } - } - - private SearchResult findUser(String username) throws LoginException - { - String filter = "(&(objectClass={0})({1}={2}))"; - - if (LOG.isDebugEnabled()) - LOG.debug("Searching for user {} with filter: \'{}\' from base dn: {}", username, filter, _userBaseDn); - - Object[] filterArguments = new Object[]{ - _userObjectClass, - _userIdAttribute, - username - }; - - return findUser(_rootContext, filter, filterArguments); - } - - private SearchResult findUser(DirContext dirContext, String filter, Object[] filterArguments) throws LoginException - { - SearchControls ctls = new SearchControls(); - ctls.setDerefLinkFlag(true); - ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); - - NamingEnumeration results; - try - { - results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls); - } - catch (NamingException ex) - { - throw new FailedLoginException(ex.getMessage()); - } - - if (LOG.isDebugEnabled()) - LOG.debug("Found user?: {}", results.hasMoreElements()); - - if (!results.hasMoreElements()) - throw new FailedLoginException("User not found."); - - SearchResult searchResult = (SearchResult)results.nextElement(); - if (results.hasMoreElements()) - throw new FailedLoginException("Search result contains ambiguous entries"); - - return searchResult; - } - - /** - * Init LoginModule. - *

    - * Called once by JAAS after new instance is created. - * - * @param subject the subect - * @param callbackHandler the callback handler - * @param sharedState the shared state map - * @param options the option map - */ - @Override - public void initialize(Subject subject, - CallbackHandler callbackHandler, - Map sharedState, - Map options) - { - super.initialize(subject, callbackHandler, sharedState, options); - - _hostname = (String)options.get("hostname"); - _port = Integer.parseInt((String)options.get("port")); - _contextFactory = (String)options.get("contextFactory"); - _bindDn = (String)options.get("bindDn"); - _bindPassword = (String)options.get("bindPassword"); - _authenticationMethod = (String)options.get("authenticationMethod"); - - _userBaseDn = (String)options.get("userBaseDn"); - - _roleBaseDn = (String)options.get("roleBaseDn"); - - if (options.containsKey("forceBindingLogin")) - { - _forceBindingLogin = Boolean.parseBoolean((String)options.get("forceBindingLogin")); - } - - if (options.containsKey("useLdaps")) - { - _useLdaps = Boolean.parseBoolean((String)options.get("useLdaps")); - } - - _userObjectClass = getOption(options, "userObjectClass", _userObjectClass); - _userRdnAttribute = getOption(options, "userRdnAttribute", _userRdnAttribute); - _userIdAttribute = getOption(options, "userIdAttribute", _userIdAttribute); - _userPasswordAttribute = getOption(options, "userPasswordAttribute", _userPasswordAttribute); - _roleObjectClass = getOption(options, "roleObjectClass", _roleObjectClass); - _roleMemberAttribute = getOption(options, "roleMemberAttribute", _roleMemberAttribute); - _roleNameAttribute = getOption(options, "roleNameAttribute", _roleNameAttribute); - _debug = Boolean.parseBoolean(String.valueOf(getOption(options, "debug", Boolean.toString(_debug)))); - - try - { - _rootContext = new InitialDirContext(getEnvironment()); - } - catch (NamingException ex) - { - throw new IllegalStateException("Unable to establish root context", ex); - } - } - - @Override - public boolean commit() throws LoginException - { - try - { - _rootContext.close(); - } - catch (NamingException e) - { - throw new LoginException("error closing root context: " + e.getMessage()); - } - - return super.commit(); - } - - @Override - public boolean abort() throws LoginException - { - try - { - _rootContext.close(); - } - catch (NamingException e) - { - throw new LoginException("error closing root context: " + e.getMessage()); - } - - return super.abort(); - } - - private String getOption(Map options, String key, String defaultValue) - { - Object value = options.get(key); - - if (value == null) - { - return defaultValue; - } - - return (String)value; - } - - /** - * get the context for connection - * - * @return the environment details for the context - */ - public Hashtable getEnvironment() - { - Properties env = new Properties(); - - env.put(Context.INITIAL_CONTEXT_FACTORY, _contextFactory); - - if (_hostname != null) - { - env.put(Context.PROVIDER_URL, (_useLdaps ? "ldaps://" : "ldap://") + _hostname + (_port == 0 ? "" : ":" + _port) + "/"); - } - - if (_authenticationMethod != null) - { - env.put(Context.SECURITY_AUTHENTICATION, _authenticationMethod); - } - - if (_bindDn != null) - { - env.put(Context.SECURITY_PRINCIPAL, _bindDn); - } - - if (_bindPassword != null) - { - env.put(Context.SECURITY_CREDENTIALS, _bindPassword); - } - - return env; - } - - public static String convertCredentialLdapToJetty(String encryptedPassword) - { - if (encryptedPassword == null) - { - return null; - } - - if (encryptedPassword.toUpperCase(Locale.ENGLISH).startsWith("{MD5}")) - { - String src = encryptedPassword.substring("{MD5}".length(), encryptedPassword.length()); - return "MD5:" + base64ToHex(src); - } - - if (encryptedPassword.toUpperCase(Locale.ENGLISH).startsWith("{CRYPT}")) - { - return "CRYPT:" + encryptedPassword.substring("{CRYPT}".length(), encryptedPassword.length()); - } - - return encryptedPassword; - } - - private static String base64ToHex(String src) - { - byte[] bytes = Base64.getDecoder().decode(src); - return TypeUtil.toString(bytes, 16); - } - - private static String hexToBase64(String src) - { - byte[] bytes = TypeUtil.fromHexString(src); - return Base64.getEncoder().encodeToString(bytes); - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModule.java deleted file mode 100644 index 823a617d8e00..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModule.java +++ /dev/null @@ -1,143 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; - -import org.eclipse.jetty.ee9.jaas.JAASLoginService; -import org.eclipse.jetty.ee9.jaas.PropertyUserStoreManager; -import org.eclipse.jetty.ee9.security.PropertyUserStore; -import org.eclipse.jetty.ee9.security.RolePrincipal; -import org.eclipse.jetty.ee9.security.UserPrincipal; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * PropertyFileLoginModule - */ -public class PropertyFileLoginModule extends AbstractLoginModule -{ - public static final String DEFAULT_FILENAME = "realm.properties"; - private static final Logger LOG = LoggerFactory.getLogger(PropertyFileLoginModule.class); - - private PropertyUserStore _store; - - /** - * Use a PropertyUserStore to read the authentication and authorizaton information contained in - * the file named by the option "file". - * - * @param subject the subject - * @param callbackHandler the callback handler - * @param sharedState the shared state map - * @param options the options map - * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, - * java.util.Map) - */ - @Override - public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) - { - super.initialize(subject, callbackHandler, sharedState, options); - setupPropertyUserStore(options); - } - - /** - * Get an existing, or create a new PropertyUserStore to read the - * authentication and authorization information from the file named by - * the option "file". - * - * @param options configuration options - */ - private void setupPropertyUserStore(Map options) - { - String filename = (String)options.get("file"); - filename = (filename == null ? DEFAULT_FILENAME : filename); - - PropertyUserStoreManager mgr = JAASLoginService.INSTANCE.get().getBean(PropertyUserStoreManager.class); - if (mgr == null) - throw new IllegalStateException("No PropertyUserStoreManager"); - - _store = mgr.getPropertyUserStore(filename); - if (_store == null) - { - int refreshInterval = 0; - String tmp = (String)options.get("refreshInterval"); - if (tmp != null) - { - try - { - refreshInterval = Integer.parseInt(tmp); - } - catch (NumberFormatException e) - { - LOG.warn("'refreshInterval' is not an integer"); - } - } - else - { - tmp = (String)options.get("hotReload"); - if (tmp != null) - { - LOG.warn("Use 'refreshInterval' boolean property instead of 'hotReload'"); - refreshInterval = Boolean.parseBoolean(tmp) ? 1 : 0; - } - } - PropertyUserStore newStore = new PropertyUserStore(); - ResourceFactory resourceFactory = ResourceFactory.of(newStore); - Resource config = resourceFactory.newResource(filename); - newStore.setConfig(config); - newStore.setRefreshInterval(refreshInterval); - _store = mgr.addPropertyUserStore(filename, newStore); - try - { - _store.start(); - } - catch (Exception e) - { - LOG.warn("Exception starting propertyUserStore {} ", config, e); - } - } - } - - /** - * @param userName the user name - * @throws Exception if unable to get the user information - */ - @Override - public JAASUser getUser(String userName) throws Exception - { - if (LOG.isDebugEnabled()) - LOG.debug("Checking PropertyUserStore {} for {}", _store.getConfig(), userName); - UserPrincipal up = _store.getUserPrincipal(userName); - if (up == null) - return null; - - List rps = _store.getRolePrincipals(userName); - List roles = rps == null ? Collections.emptyList() : rps.stream().map(RolePrincipal::getName).collect(Collectors.toList()); - return new JAASUser(up) - { - @Override - public List doFetchRoles() - { - return roles; - } - }; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/package-info.java b/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/package-info.java deleted file mode 100644 index ca4cca5d720c..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -/** - * Jetty Jaas : Various Jaas Implementations for Jetty - */ -package org.eclipse.jetty.ee9.jaas.spi; - diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLdapLoginServiceTest.java b/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLdapLoginServiceTest.java deleted file mode 100644 index 32c574d9dd5f..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLdapLoginServiceTest.java +++ /dev/null @@ -1,217 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import org.junit.jupiter.api.Disabled; - -/** - * JAASLdapLoginServiceTest - */ -//@RunWith(FrameworkRunner.class) -//@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAP")}) -//@CreateDS(allowAnonAccess = false, partitions = { -// @CreatePartition(name = "Users Partition", suffix = "ou=people,dc=jetty,dc=org"), -// @CreatePartition(name = "Groups Partition", suffix = "ou=groups,dc=jetty,dc=org") -//}) -//@ApplyLdifs({ -// // Entry 1 -// "dn: ou=people,dc=jetty,dc=org", -// "objectClass: organizationalunit", -// "objectClass: top", -// "ou: people", -// // Entry # 2 -// "dn:uid=someone,ou=people,dc=jetty,dc=org", -// "objectClass: inetOrgPerson", -// "cn: someone", -// "sn: sn test", -// "userPassword: complicatedpassword", -// // Entry # 3 -// "dn:uid=someoneelse,ou=people,dc=jetty,dc=org", -// "objectClass: inetOrgPerson", -// "cn: someoneelse", -// "sn: sn test", -// "userPassword: verycomplicatedpassword", -// // Entry 4 -// "dn: ou=groups,dc=jetty,dc=org", -// "objectClass: organizationalunit", -// "objectClass: top", -// "ou: groups", -// // Entry 5 -// "dn: ou=subdir,ou=people,dc=jetty,dc=org", -// "objectClass: organizationalunit", -// "objectClass: top", -// "ou: subdir", -// // Entry # 6 -// "dn:uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", -// "objectClass: inetOrgPerson", -// "cn: uniqueuser", -// "sn: unique user", -// "userPassword: hello123", -// // Entry # 7 -// "dn:uid=ambiguousone,ou=people,dc=jetty,dc=org", -// "objectClass: inetOrgPerson", -// "cn: ambiguous1", -// "sn: ambiguous user", -// "userPassword: foobar", -// // Entry # 8 -// "dn:uid=ambiguousone,ou=subdir,ou=people,dc=jetty,dc=org", -// "objectClass: inetOrgPerson", -// "cn: ambiguous2", -// "sn: ambiguous subdir user", -// "userPassword: barfoo", -// // Entry 9 -// "dn: cn=developers,ou=groups,dc=jetty,dc=org", -// "objectClass: groupOfUniqueNames", -// "objectClass: top", -// "ou: groups", -// "description: People who try to build good software", -// "uniquemember: uid=someone,ou=people,dc=jetty,dc=org", -// "uniquemember: uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", -// "cn: developers", -// // Entry 10 -// "dn: cn=admin,ou=groups,dc=jetty,dc=org", -// "objectClass: groupOfUniqueNames", -// "objectClass: top", -// "ou: groups", -// "description: People who try to run software build by developers", -// "uniquemember: uid=someone,ou=people,dc=jetty,dc=org", -// "uniquemember: uid=someoneelse,ou=people,dc=jetty,dc=org", -// "uniquemember: uid=uniqueuser,ou=subdir,ou=people,dc=jetty,dc=org", -// "cn: admin" -//}) -@Disabled // TODO -public class JAASLdapLoginServiceTest -{ - /* TODO need to test without mock request - private static LdapServer _ldapServer; - - private JAASLoginService jaasLoginService(String name) - { - JAASLoginService ls = new JAASLoginService("foo"); - ls.setCallbackHandlerClass("org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(new TestConfiguration(true)); - return ls; - } - - private UserIdentity doLogin(String username, String password) throws Exception - { - JAASLoginService ls = jaasLoginService("foo"); - Request request = new Request(null, null); - return ls.login(username, password, request); - } - - public static LdapServer getLdapServer() - { - return _ldapServer; - } - - public static void setLdapServer(LdapServer ldapServer) - { - _ldapServer = ldapServer; - } - - public static class TestConfiguration extends Configuration - { - private boolean forceBindingLogin; - - public TestConfiguration(boolean forceBindingLogin) - { - this.forceBindingLogin = forceBindingLogin; - } - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) - { - Map options = new HashMap<>(); - options.put("hostname", "localhost"); - options.put("port", Integer.toString(_ldapServer.getTransports()[0].getPort())); - options.put("contextFactory", "com.sun.jndi.ldap.LdapCtxFactory"); - options.put("bindDn", "uid=admin,ou=system"); - options.put("bindPassword", "secret"); - options.put("userBaseDn", "ou=people,dc=jetty,dc=org"); - options.put("roleBaseDn", "ou=groups,dc=jetty,dc=org"); - options.put("roleNameAttribute", "cn"); - options.put("forceBindingLogin", Boolean.toString(forceBindingLogin)); - AppConfigurationEntry entry = new AppConfigurationEntry(LdapLoginModule.class.getCanonicalName(), LoginModuleControlFlag.REQUIRED, options); - - return new AppConfigurationEntry[]{entry}; - } - } - - @Test - public void testLdapUserIdentity() throws Exception - { - JAASLoginService ls = new JAASLoginService("foo"); - ls.setCallbackHandlerClass("org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(new TestConfiguration(false)); - Request request = new Request(null, null); - UserIdentity userIdentity = ls.login("someone", "complicatedpassword", request); - assertNotNull(userIdentity); - assertTrue(userIdentity.isUserInRole("developers", null)); - assertTrue(userIdentity.isUserInRole("admin", null)); - assertFalse(userIdentity.isUserInRole("blabla", null)); - - userIdentity = ls.login("someoneelse", "verycomplicatedpassword", request); - assertNotNull(userIdentity); - assertFalse(userIdentity.isUserInRole("developers", null)); - assertTrue(userIdentity.isUserInRole("admin", null)); - assertFalse(userIdentity.isUserInRole("blabla", null)); - } - - @Test - public void testLdapUserIdentityBindingLogin() throws Exception - { - JAASLoginService ls = new JAASLoginService("foo"); - ls.setCallbackHandlerClass("org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(new TestConfiguration(true)); - Request request = new Request(null, null); - UserIdentity userIdentity = ls.login("someone", "complicatedpassword", request); - assertNotNull(userIdentity); - assertTrue(userIdentity.isUserInRole("developers", null)); - assertTrue(userIdentity.isUserInRole("admin", null)); - assertFalse(userIdentity.isUserInRole("blabla", null)); - - userIdentity = ls.login("someone", "wrongpassword", request); - assertNull(userIdentity); - } - - @Test - public void testLdapBindingSubdirUniqueUserName() throws Exception - { - UserIdentity userIdentity = doLogin("uniqueuser", "hello123"); - assertNotNull(userIdentity); - assertTrue(userIdentity.isUserInRole("developers", null)); - assertTrue(userIdentity.isUserInRole("admin", null)); - assertFalse(userIdentity.isUserInRole("blabla", null)); - } - - @Test - public void testLdapBindingAmbiguousUserName() throws Exception - { - UserIdentity userIdentity = doLogin("ambiguousone", "foobar"); - assertNull(userIdentity); - } - - @Test - public void testLdapBindingSubdirAmbiguousUserName() throws Exception - { - UserIdentity userIdentity = doLogin("ambiguousone", "barfoo"); - assertNull(userIdentity); - } - - */ -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLoginServiceTest.java b/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLoginServiceTest.java deleted file mode 100644 index 3e267645858b..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLoginServiceTest.java +++ /dev/null @@ -1,161 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import org.junit.jupiter.api.Disabled; - -/** - * JAASLoginServiceTest - */ -@Disabled // TODO -public class JAASLoginServiceTest -{ - /* TODO need to test without mock request - interface SomeRole - { - - } - - public class TestRole implements Principal, SomeRole - { - String _name; - - public TestRole(String name) - { - _name = name; - } - - public String getName() - { - return _name; - } - } - - public class AnotherTestRole extends TestRole - { - public AnotherTestRole(String name) - { - super(name); - } - } - - public class NotTestRole implements Principal - { - String _name; - - public NotTestRole(String n) - { - _name = n; - } - - public String getName() - { - return _name; - } - } - - @Test - public void testServletRequestCallback() throws Exception - { - Configuration config = new Configuration() - { - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) - { - return new AppConfigurationEntry[] { - new AppConfigurationEntry(TestLoginModule.class.getCanonicalName(), - LoginModuleControlFlag.REQUIRED, - Collections.emptyMap()) - }; - } - }; - - //Test with the DefaultCallbackHandler - JAASLoginService ls = new JAASLoginService("foo"); - ls.setCallbackHandlerClass("org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(config); - Request request = new Request(null, null); - ls.login("aaardvaark", "aaa", request); - - //Test with the fallback CallbackHandler - ls = new JAASLoginService("foo"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(config); - ls.login("aaardvaark", "aaa", request); - } - - @Test - public void testLoginServiceRoles() throws Exception - { - JAASLoginService ls = new JAASLoginService("foo"); - - //test that we always add in the DEFAULT ROLE CLASSNAME - ls.setRoleClassNames(new String[]{"arole", "brole"}); - String[] roles = ls.getRoleClassNames(); - assertEquals(3, roles.length); - assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, roles[2]); - - ls.setRoleClassNames(new String[]{}); - assertEquals(1, ls.getRoleClassNames().length); - assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, ls.getRoleClassNames()[0]); - - ls.setRoleClassNames(null); - assertEquals(1, ls.getRoleClassNames().length); - assertEquals(JAASLoginService.DEFAULT_ROLE_CLASS_NAME, ls.getRoleClassNames()[0]); - - //test a custom role class where some of the roles are subclasses of it - ls.setRoleClassNames(new String[]{TestRole.class.getName()}); - Subject subject = new Subject(); - subject.getPrincipals().add(new NotTestRole("w")); - subject.getPrincipals().add(new TestRole("x")); - subject.getPrincipals().add(new TestRole("y")); - subject.getPrincipals().add(new AnotherTestRole("z")); - - String[] groups = ls.getGroups(subject); - assertThat(Arrays.asList(groups), containsInAnyOrder("x", "y", "z")); - - //test a custom role class - ls.setRoleClassNames(new String[]{AnotherTestRole.class.getName()}); - Subject subject2 = new Subject(); - subject2.getPrincipals().add(new NotTestRole("w")); - subject2.getPrincipals().add(new TestRole("x")); - subject2.getPrincipals().add(new TestRole("y")); - subject2.getPrincipals().add(new AnotherTestRole("z")); - String[] s2groups = ls.getGroups(subject2); - assertThat(s2groups, is(notNullValue())); - assertThat(Arrays.asList(s2groups), containsInAnyOrder("z")); - - //test a custom role class that implements an interface - ls.setRoleClassNames(new String[]{SomeRole.class.getName()}); - Subject subject3 = new Subject(); - subject3.getPrincipals().add(new NotTestRole("w")); - subject3.getPrincipals().add(new TestRole("x")); - subject3.getPrincipals().add(new TestRole("y")); - subject3.getPrincipals().add(new AnotherTestRole("z")); - String[] s3groups = ls.getGroups(subject3); - assertThat(s3groups, is(notNullValue())); - assertThat(Arrays.asList(s3groups), containsInAnyOrder("x", "y", "z")); - - //test a class that doesn't match - ls.setRoleClassNames(new String[]{NotTestRole.class.getName()}); - Subject subject4 = new Subject(); - subject4.getPrincipals().add(new TestRole("x")); - subject4.getPrincipals().add(new TestRole("y")); - subject4.getPrincipals().add(new AnotherTestRole("z")); - assertEquals(0, ls.getGroups(subject4).length); - } - - */ -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java b/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java deleted file mode 100644 index ccd07efe5771..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java +++ /dev/null @@ -1,59 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas; - -import java.util.Collections; -import java.util.List; -import javax.security.auth.callback.Callback; -import javax.security.auth.login.LoginException; - -import org.eclipse.jetty.ee9.jaas.callback.ServletRequestCallback; -import org.eclipse.jetty.ee9.jaas.spi.AbstractLoginModule; -import org.eclipse.jetty.ee9.security.UserPrincipal; -import org.eclipse.jetty.util.ArrayUtil; -import org.eclipse.jetty.util.security.Password; - -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class TestLoginModule extends AbstractLoginModule -{ - public ServletRequestCallback _callback = new ServletRequestCallback(); - - @Override - public JAASUser getUser(String username) throws Exception - { - return new JAASUser(new UserPrincipal(username, new Password("aaa"))) - { - @Override - public List doFetchRoles() throws Exception - { - return Collections.emptyList(); - } - }; - } - - @Override - public Callback[] configureCallbacks() - { - return ArrayUtil.addToArray(super.configureCallbacks(), _callback, Callback.class); - } - - @Override - public boolean login() throws LoginException - { - boolean result = super.login(); - assertNotNull(_callback.getRequest()); - return result; - } -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java b/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java deleted file mode 100644 index 2ad62a2f6fc4..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.jaas.spi; - -import org.junit.jupiter.api.Disabled; - -@Disabled // TODO -public class PropertyFileLoginModuleTest -{ - /* TODO need to test without mock request - @Test - public void testPropertyFileLoginModule() throws Exception - { - //configure for PropertyFileLoginModule - File loginProperties = MavenTestingUtils.getTestResourceFile("login.properties"); - - Configuration testConfig = new Configuration() - { - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) - { - return new AppConfigurationEntry[]{new AppConfigurationEntry(PropertyFileLoginModule.class.getName(), - LoginModuleControlFlag.REQUIRED, - Collections.singletonMap("file", loginProperties.getAbsolutePath()))}; - } - }; - - JAASLoginService ls = new JAASLoginService("foo"); - ls.setCallbackHandlerClass("org.eclipse.jetty.ee9.jaas.callback.DefaultCallbackHandler"); - ls.setIdentityService(new DefaultIdentityService()); - ls.setConfiguration(testConfig); - ls.start(); - - //test that the manager is created when the JAASLoginService starts - PropertyUserStoreManager mgr = ls.getBean(PropertyUserStoreManager.class); - assertThat(mgr, notNullValue()); - - //test the PropertyFileLoginModule authentication and authorization - Request request = new Request(null, null); - UserIdentity uid = ls.login("fred", "pwd", request); - assertThat(uid.isUserInRole("role1", null), is(true)); - assertThat(uid.isUserInRole("role2", null), is(true)); - assertThat(uid.isUserInRole("role3", null), is(true)); - assertThat(uid.isUserInRole("role4", null), is(false)); - - //Test that the PropertyUserStore is created by the PropertyFileLoginModule - PropertyUserStore store = mgr.getPropertyUserStore(loginProperties.getAbsolutePath()); - assertThat(store, is(notNullValue())); - assertThat(store.isRunning(), is(true)); - assertThat(store.isHotReload(), is(false)); - - //test that the PropertyUserStoreManager is stopped and all PropertyUserStores stopped - ls.stop(); - assertThat(mgr.isStopped(), is(true)); - assertThat(mgr.getPropertyUserStore(loginProperties.getAbsolutePath()), is(nullValue())); - assertThat(store.isStopped(), is(true)); - } - - */ -} diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/resources/jetty-logging.properties b/jetty-ee9/jetty-ee9-jaas/src/test/resources/jetty-logging.properties deleted file mode 100644 index f0773d90fa57..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/resources/jetty-logging.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Jetty Logging using jetty-slf4j-impl -org.eclipse.jetty.LEVEL=INFO -org.apache.directory.LEVEL=ERROR \ No newline at end of file diff --git a/jetty-ee9/jetty-ee9-jaas/src/test/resources/login.properties b/jetty-ee9/jetty-ee9-jaas/src/test/resources/login.properties deleted file mode 100644 index 22a4bedc7b7b..000000000000 --- a/jetty-ee9/jetty-ee9-jaas/src/test/resources/login.properties +++ /dev/null @@ -1 +0,0 @@ -fred=pwd,role1,role2,role3 \ No newline at end of file diff --git a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java index 60cfae695b11..9468f4ff2129 100644 --- a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java +++ b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java @@ -35,15 +35,16 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.eclipse.jetty.ee9.nested.Authentication; -import org.eclipse.jetty.ee9.security.EmptyLoginService; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.ee9.nested.SessionHandler; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.ee9.security.WrappedAuthConfiguration; import org.eclipse.jetty.ee9.security.authentication.DeferredAuthentication; import org.eclipse.jetty.ee9.security.authentication.LoginAuthenticator; import org.eclipse.jetty.ee9.security.authentication.SessionAuthentication; +import org.eclipse.jetty.security.EmptyLoginService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; import static org.eclipse.jetty.ee9.security.jaspi.JaspiAuthenticatorFactory.MESSAGE_LAYER; @@ -138,7 +139,7 @@ public String getAuthMethod() @Override public UserIdentity login(String username, Object password, ServletRequest request) { - UserIdentity user = _loginService.login(username, password, request); + UserIdentity user = _loginService.login(username, password, SessionHandler.ServletSessionApi.newGetSession(request)); if (user != null) { renewSession((HttpServletRequest)request, null); diff --git a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticatorFactory.java b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticatorFactory.java index b3eb3d935c48..f2cf58f95e19 100644 --- a/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticatorFactory.java +++ b/jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticatorFactory.java @@ -23,8 +23,8 @@ import org.eclipse.jetty.ee9.security.Authenticator; import org.eclipse.jetty.ee9.security.Authenticator.AuthConfiguration; import org.eclipse.jetty.ee9.security.DefaultAuthenticatorFactory; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.StringUtil; import org.slf4j.Logger; diff --git a/jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/JaspiTest.java b/jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/JaspiTest.java index e852a8fb5bf4..0efc3f66f473 100644 --- a/jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/JaspiTest.java +++ b/jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/JaspiTest.java @@ -28,11 +28,11 @@ import org.eclipse.jetty.ee9.nested.AbstractHandler; import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.security.AbstractLoginService; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.RolePrincipal; -import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.security.AbstractLoginService; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandlerCollection; @@ -77,13 +77,13 @@ public void putUser(String username, Credential credential, String[] roles) } @Override - protected List loadRoleInfo(UserPrincipal user) + protected List loadRoleInfo(org.eclipse.jetty.security.UserPrincipal user) { return _roles.get(user.getName()); } @Override - protected UserPrincipal loadUserInfo(String username) + protected org.eclipse.jetty.security.UserPrincipal loadUserInfo(String username) { return _users.get(username); } diff --git a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractWebAppMojo.java b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractWebAppMojo.java index bee5ea7a3b34..50a63aa961e3 100644 --- a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractWebAppMojo.java +++ b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractWebAppMojo.java @@ -48,7 +48,7 @@ import org.codehaus.plexus.util.StringUtils; import org.eclipse.aether.RepositorySystem; import org.eclipse.jetty.ee9.maven.plugin.utils.MavenProjectHelper; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; diff --git a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEmbedder.java b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEmbedder.java index 3650c77ce492..17e56da04084 100644 --- a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEmbedder.java +++ b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEmbedder.java @@ -23,7 +23,7 @@ import org.eclipse.jetty.ee9.quickstart.QuickStartConfiguration; import org.eclipse.jetty.ee9.quickstart.QuickStartConfiguration.Mode; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ShutdownMonitor; diff --git a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerSupport.java b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerSupport.java index c144c1b3378a..ded99115ec7c 100644 --- a/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerSupport.java +++ b/jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerSupport.java @@ -19,9 +19,9 @@ import java.util.List; import java.util.Map; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.webapp.Configurations; import org.eclipse.jetty.ee9.webapp.WebAppContext; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.RequestLog; import org.eclipse.jetty.server.Server; diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java index 98f0bc9a1bb1..9ddef3ccb3ba 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java @@ -21,10 +21,12 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; import jakarta.servlet.DispatcherType; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; import jakarta.servlet.SessionCookieConfig; import jakarta.servlet.SessionTrackingMode; import jakarta.servlet.http.HttpServletRequest; @@ -693,6 +695,20 @@ public void onSessionPassivation(Session session) public class ServletSessionApi implements HttpSession, Session.API { + public static Function newGetSession(ServletRequest servletRequest) + { + return createSession -> + { + if (servletRequest instanceof HttpServletRequest request) + { + HttpSession session = request.getSession(createSession); + if (session instanceof SessionHandler.ServletSessionApi sessionApi) + return sessionApi.getSession(); + } + return null; + }; + } + private final ManagedSession _session; private ServletSessionApi(ManagedSession session) diff --git a/jetty-ee9/jetty-ee9-openid/pom.xml b/jetty-ee9/jetty-ee9-openid/pom.xml index 582e54193f7c..006fc9bef8f3 100644 --- a/jetty-ee9/jetty-ee9-openid/pom.xml +++ b/jetty-ee9/jetty-ee9-openid/pom.xml @@ -36,6 +36,14 @@ org.eclipse.jetty jetty-server + + org.eclipse.jetty + jetty-security + + + org.eclipse.jetty + jetty-openid + org.eclipse.jetty jetty-client diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/module-info.java b/jetty-ee9/jetty-ee9-openid/src/main/java/module-info.java index a54ee4a5ef88..6005830a02ad 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/module-info.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/module-info.java @@ -14,10 +14,11 @@ import org.eclipse.jetty.ee9.security.Authenticator; import org.eclipse.jetty.ee9.security.openid.OpenIdAuthenticatorFactory; -module org.eclipse.jetty.security.openid +module org.eclipse.jetty.ee9.security.openid { requires org.eclipse.jetty.util.ajax; - + requires transitive org.eclipse.jetty.security; + requires transitive org.eclipse.jetty.security.openid; requires transitive org.eclipse.jetty.client; requires transitive org.eclipse.jetty.ee9.nested; requires transitive org.eclipse.jetty.ee9.security; diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/JwtDecoder.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/JwtDecoder.java deleted file mode 100644 index fd2862cc6ddd..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/JwtDecoder.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Base64; -import java.util.Map; - -import org.eclipse.jetty.util.ajax.JSON; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Used to decode the ID Token from the base64 encrypted JSON Web Token (JWT). - */ -public class JwtDecoder -{ - private static final Logger LOG = LoggerFactory.getLogger(JwtDecoder.class); - - /** - * Decodes a JSON Web Token (JWT) into a Map of claims. - * - * @param jwt the JWT to decode. - * @return the map of claims encoded in the JWT. - */ - @SuppressWarnings("unchecked") - public static Map decode(String jwt) - { - if (LOG.isDebugEnabled()) - LOG.debug("decode {}", jwt); - - String[] sections = jwt.split("\\."); - if (sections.length != 3) - throw new IllegalArgumentException("JWT does not contain 3 sections"); - - Base64.Decoder decoder = Base64.getUrlDecoder(); - String jwtHeaderString = new String(decoder.decode(padJWTSection(sections[0])), StandardCharsets.UTF_8); - String jwtClaimString = new String(decoder.decode(padJWTSection(sections[1])), StandardCharsets.UTF_8); - String jwtSignature = sections[2]; - - JSON json = new JSON(); - - Object parsedJwtHeader = json.fromJSON(jwtHeaderString); - if (!(parsedJwtHeader instanceof Map)) - throw new IllegalStateException("Invalid JWT header"); - Map jwtHeader = (Map)parsedJwtHeader; - if (LOG.isDebugEnabled()) - LOG.debug("JWT Header: {}", jwtHeader); - - /* If the ID Token is received via direct communication between the Client - and the Token Endpoint (which it is in this flow), the TLS server validation - MAY be used to validate the issuer in place of checking the token signature. */ - if (LOG.isDebugEnabled()) - LOG.debug("JWT signature not validated {}", jwtSignature); - - Object parsedClaims = json.fromJSON(jwtClaimString); - if (!(parsedClaims instanceof Map)) - throw new IllegalStateException("Could not decode JSON for JWT claims."); - return (Map)parsedClaims; - } - - static byte[] padJWTSection(String unpaddedEncodedJwtSection) - { - // If already padded just use what we are given. - if (unpaddedEncodedJwtSection.endsWith("=")) - return unpaddedEncodedJwtSection.getBytes(); - - int length = unpaddedEncodedJwtSection.length(); - int remainder = length % 4; - - // A valid base-64-encoded string will have a remainder of 0, 2 or 3. Never 1! - if (remainder == 1) - throw new IllegalArgumentException("Not a valid Base64-encoded string"); - - byte[] paddedEncodedJwtSection; - if (remainder > 0) - { - int paddingNeeded = (4 - remainder) % 4; - paddedEncodedJwtSection = Arrays.copyOf(unpaddedEncodedJwtSection.getBytes(), length + paddingNeeded); - Arrays.fill(paddedEncodedJwtSection, length, paddedEncodedJwtSection.length, (byte)'='); - } - else - { - paddedEncodedJwtSection = unpaddedEncodedJwtSection.getBytes(); - } - - return paddedEncodedJwtSection; - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthConfiguration.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthConfiguration.java index 78d47c6b2de5..f5f59a97bb9c 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthConfiguration.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthConfiguration.java @@ -14,8 +14,10 @@ package org.eclipse.jetty.ee9.security.openid; import org.eclipse.jetty.ee9.security.Authenticator; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.WrappedAuthConfiguration; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; +import org.eclipse.jetty.security.openid.OpenIdLoginService; /** *

    This class is used to wrap the {@link Authenticator.AuthConfiguration} given to the {@link OpenIdAuthenticator}.

    diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java index 6d6af046042e..b3d378d6d301 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java @@ -30,7 +30,6 @@ import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.nested.Response; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.ServerAuthException; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.ee9.security.authentication.DeferredAuthentication; @@ -38,7 +37,11 @@ import org.eclipse.jetty.ee9.security.authentication.SessionAuthentication; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.MimeTypes; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; +import org.eclipse.jetty.security.openid.OpenIdCredentials; +import org.eclipse.jetty.security.openid.OpenIdLoginService; import org.eclipse.jetty.util.MultiMap; import org.eclipse.jetty.util.URIUtil; import org.eclipse.jetty.util.UrlEncoded; diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticatorFactory.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticatorFactory.java index 89b72cc4dbb4..c5763e10808b 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticatorFactory.java +++ b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticatorFactory.java @@ -17,8 +17,10 @@ import jakarta.servlet.ServletContext; import org.eclipse.jetty.ee9.security.Authenticator; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; +import org.eclipse.jetty.security.openid.OpenIdLoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.security.Constraint; diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdConfiguration.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdConfiguration.java deleted file mode 100644 index 93a738e94470..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdConfiguration.java +++ /dev/null @@ -1,291 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP; -import org.eclipse.jetty.io.ClientConnector; -import org.eclipse.jetty.util.ajax.JSON; -import org.eclipse.jetty.util.annotation.Name; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Holds the configuration for an OpenID Connect service. - * - * This uses the OpenID Provider URL with the path {@link #CONFIG_PATH} to discover - * the required information about the OIDC service. - */ -public class OpenIdConfiguration extends ContainerLifeCycle -{ - private static final Logger LOG = LoggerFactory.getLogger(OpenIdConfiguration.class); - private static final String CONFIG_PATH = "/.well-known/openid-configuration"; - private static final String AUTHORIZATION_ENDPOINT = "authorization_endpoint"; - private static final String TOKEN_ENDPOINT = "token_endpoint"; - private static final String END_SESSION_ENDPOINT = "end_session_endpoint"; - private static final String ISSUER = "issuer"; - - private final HttpClient httpClient; - private final String issuer; - private final String clientId; - private final String clientSecret; - private final List scopes = new ArrayList<>(); - private final String authMethod; - private String authEndpoint; - private String tokenEndpoint; - private String endSessionEndpoint; - private boolean authenticateNewUsers = false; - - /** - * Create an OpenID configuration for a specific OIDC provider. - * @param provider The URL of the OpenID provider. - * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. - * @param clientSecret The client secret known only by the Client and the Authorization Server. - */ - public OpenIdConfiguration(String provider, String clientId, String clientSecret) - { - this(provider, null, null, clientId, clientSecret, null); - } - - /** - * Create an OpenID configuration for a specific OIDC provider. - * @param issuer The URL of the OpenID provider. - * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. - * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. - * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. - * @param clientSecret The client secret known only by the Client and the Authorization Server. - * @param httpClient The {@link HttpClient} instance to use. - */ - public OpenIdConfiguration(String issuer, String authorizationEndpoint, String tokenEndpoint, - String clientId, String clientSecret, HttpClient httpClient) - { - this(issuer, authorizationEndpoint, tokenEndpoint, clientId, clientSecret, "client_secret_post", httpClient); - } - - /** - * Create an OpenID configuration for a specific OIDC provider. - * @param issuer The URL of the OpenID provider. - * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. - * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. - * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. - * @param clientSecret The client secret known only by the Client and the Authorization Server. - * @param authMethod Authentication method to use with the Token Endpoint. - * @param httpClient The {@link HttpClient} instance to use. - */ - public OpenIdConfiguration(@Name("issuer") String issuer, - @Name("authorizationEndpoint") String authorizationEndpoint, - @Name("tokenEndpoint") String tokenEndpoint, - @Name("clientId") String clientId, - @Name("clientSecret") String clientSecret, - @Name("authMethod") String authMethod, - @Name("httpClient") HttpClient httpClient) - { - this(issuer, authorizationEndpoint, tokenEndpoint, null, clientId, clientSecret, authMethod, httpClient); - } - - /** - * Create an OpenID configuration for a specific OIDC provider. - * @param issuer The URL of the OpenID provider. - * @param authorizationEndpoint the URL of the OpenID provider's authorization endpoint if configured. - * @param tokenEndpoint the URL of the OpenID provider's token endpoint if configured. - * @param endSessionEndpoint the URL of the OpdnID provider's end session endpoint if configured. - * @param clientId OAuth 2.0 Client Identifier valid at the Authorization Server. - * @param clientSecret The client secret known only by the Client and the Authorization Server. - * @param authMethod Authentication method to use with the Token Endpoint. - * @param httpClient The {@link HttpClient} instance to use. - */ - public OpenIdConfiguration(@Name("issuer") String issuer, - @Name("authorizationEndpoint") String authorizationEndpoint, - @Name("tokenEndpoint") String tokenEndpoint, - @Name("endSessionEndpoint") String endSessionEndpoint, - @Name("clientId") String clientId, - @Name("clientSecret") String clientSecret, - @Name("authMethod") String authMethod, - @Name("httpClient") HttpClient httpClient) - { - this.issuer = issuer; - this.clientId = clientId; - this.clientSecret = clientSecret; - this.authEndpoint = authorizationEndpoint; - this.endSessionEndpoint = endSessionEndpoint; - this.tokenEndpoint = tokenEndpoint; - this.httpClient = httpClient != null ? httpClient : newHttpClient(); - this.authMethod = authMethod == null ? "client_secret_post" : authMethod; - - if (this.issuer == null) - throw new IllegalArgumentException("Issuer was not configured"); - - addBean(this.httpClient); - } - - @Override - protected void doStart() throws Exception - { - super.doStart(); - - if (authEndpoint == null || tokenEndpoint == null) - { - Map discoveryDocument = fetchOpenIdConnectMetadata(); - processMetadata(discoveryDocument); - } - } - - /** - * Process the OpenID Connect metadata discovered by {@link #fetchOpenIdConnectMetadata()}. - * By default, only the {@link #AUTHORIZATION_ENDPOINT} and {@link #TOKEN_ENDPOINT} claims are extracted. - * @see OpenID Connect Discovery 1.0 - * @throws IllegalStateException if a required field is not present in the metadata. - */ - protected void processMetadata(Map discoveryDocument) - { - authEndpoint = (String)discoveryDocument.get(AUTHORIZATION_ENDPOINT); - if (authEndpoint == null) - throw new IllegalStateException(AUTHORIZATION_ENDPOINT); - - tokenEndpoint = (String)discoveryDocument.get(TOKEN_ENDPOINT); - if (tokenEndpoint == null) - throw new IllegalStateException(TOKEN_ENDPOINT); - - // End session endpoint is optional. - if (endSessionEndpoint == null) - endSessionEndpoint = (String)discoveryDocument.get(END_SESSION_ENDPOINT); - - // We are lenient and not throw here as some major OIDC providers do not conform to this. - if (!Objects.equals(discoveryDocument.get(ISSUER), issuer)) - LOG.warn("The issuer in the metadata is not correct."); - } - - /** - * Obtain the JSON metadata from OpenID Connect Discovery Configuration Endpoint. - * @return a set of Claims about the OpenID Provider's configuration in JSON format. - * @throws IllegalStateException if metadata could not be fetched from the OP. - */ - protected Map fetchOpenIdConnectMetadata() - { - String provider = issuer; - if (provider.endsWith("/")) - provider = provider.substring(0, provider.length() - 1); - - try - { - Map result; - String responseBody = httpClient.GET(provider + CONFIG_PATH).getContentAsString(); - Object parsedResult = new JSON().fromJSON(responseBody); - - if (parsedResult instanceof Map) - { - Map rawResult = (Map)parsedResult; - result = rawResult.entrySet().stream() - .filter(entry -> entry.getValue() != null) - .collect(Collectors.toMap(it -> it.getKey().toString(), Map.Entry::getValue)); - if (LOG.isDebugEnabled()) - LOG.debug("discovery document {}", result); - return result; - } - else - { - LOG.warn("OpenID provider did not return a proper JSON object response. Result was '{}'", responseBody); - throw new IllegalStateException("Could not parse OpenID provider's malformed response"); - } - } - catch (Exception e) - { - throw new IllegalStateException("invalid identity provider " + provider, e); - } - } - - public HttpClient getHttpClient() - { - return httpClient; - } - - public String getAuthEndpoint() - { - return authEndpoint; - } - - public String getClientId() - { - return clientId; - } - - public String getClientSecret() - { - return clientSecret; - } - - public String getIssuer() - { - return issuer; - } - - public String getTokenEndpoint() - { - return tokenEndpoint; - } - - public String getEndSessionEndpoint() - { - return endSessionEndpoint; - } - - public String getAuthMethod() - { - return authMethod; - } - - public void addScopes(String... scopes) - { - if (scopes != null) - Collections.addAll(this.scopes, scopes); - } - - public List getScopes() - { - return scopes; - } - - public boolean isAuthenticateNewUsers() - { - return authenticateNewUsers; - } - - public void setAuthenticateNewUsers(boolean authenticateNewUsers) - { - this.authenticateNewUsers = authenticateNewUsers; - } - - private static HttpClient newHttpClient() - { - ClientConnector connector = new ClientConnector(); - connector.setSslContextFactory(new SslContextFactory.Client(false)); - return new HttpClient(new HttpClientTransportOverHTTP(connector)); - } - - @Override - public String toString() - { - return String.format("%s@%x{iss=%s, clientId=%s, authEndpoint=%s, authMethod=%s, tokenEndpoint=%s, scopes=%s, authNewUsers=%s}", - getClass().getSimpleName(), hashCode(), issuer, clientId, authEndpoint, authMethod, tokenEndpoint, scopes, authenticateNewUsers); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentials.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentials.java deleted file mode 100644 index 6d5495af37c6..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentials.java +++ /dev/null @@ -1,213 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.io.Serializable; -import java.net.URI; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.client.Authentication; -import org.eclipse.jetty.client.BasicAuthentication; -import org.eclipse.jetty.client.ContentResponse; -import org.eclipse.jetty.client.FormRequestContent; -import org.eclipse.jetty.client.Request; -import org.eclipse.jetty.util.Fields; -import org.eclipse.jetty.util.ajax.JSON; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - *

    The credentials of an user to be authenticated with OpenID Connect. This will contain - * the OpenID ID Token and the OAuth 2.0 Access Token.

    - * - *

    - * This is constructed with an authorization code from the authentication request. This authorization code - * is then exchanged using {@link #redeemAuthCode(OpenIdConfiguration)} for a response containing the ID Token and Access Token. - * The response is then validated against the {@link OpenIdConfiguration}. - *

    - */ -public class OpenIdCredentials implements Serializable -{ - private static final Logger LOG = LoggerFactory.getLogger(OpenIdCredentials.class); - private static final long serialVersionUID = 4766053233370044796L; - - private final String redirectUri; - private String authCode; - private Map response; - private Map claims; - private boolean verified = false; - - public OpenIdCredentials(Map claims) - { - this.redirectUri = null; - this.authCode = null; - this.claims = claims; - } - - public OpenIdCredentials(String authCode, String redirectUri) - { - this.authCode = authCode; - this.redirectUri = redirectUri; - } - - public String getUserId() - { - return (String)claims.get("sub"); - } - - public Map getClaims() - { - return claims; - } - - public Map getResponse() - { - return response; - } - - public void redeemAuthCode(OpenIdConfiguration configuration) throws Exception - { - if (LOG.isDebugEnabled()) - LOG.debug("redeemAuthCode() {}", this); - - if (authCode != null) - { - try - { - response = claimAuthCode(configuration); - if (LOG.isDebugEnabled()) - LOG.debug("response: {}", response); - - String idToken = (String)response.get("id_token"); - if (idToken == null) - throw new AuthenticationException("no id_token"); - - String accessToken = (String)response.get("access_token"); - if (accessToken == null) - throw new AuthenticationException("no access_token"); - - String tokenType = (String)response.get("token_type"); - if (!"Bearer".equalsIgnoreCase(tokenType)) - throw new AuthenticationException("invalid token_type"); - - claims = JwtDecoder.decode(idToken); - if (LOG.isDebugEnabled()) - LOG.debug("claims {}", claims); - } - finally - { - // reset authCode as it can only be used once - authCode = null; - } - } - - if (!verified) - { - validateClaims(configuration); - verified = true; - } - } - - private void validateClaims(OpenIdConfiguration configuration) throws Exception - { - // Issuer Identifier for the OpenID Provider MUST exactly match the value of the iss (issuer) Claim. - if (!configuration.getIssuer().equals(claims.get("iss"))) - throw new AuthenticationException("Issuer Identifier MUST exactly match the iss Claim"); - - // The aud (audience) Claim MUST contain the client_id value. - validateAudience(configuration); - - // If an azp (authorized party) Claim is present, verify that its client_id is the Claim Value. - Object azp = claims.get("azp"); - if (azp != null && !configuration.getClientId().equals(azp)) - throw new AuthenticationException("Authorized party claim value should be the client_id"); - - // Check that the ID token has not expired by checking the exp claim. - long expiry = (Long)claims.get("exp"); - long currentTimeSeconds = (long)(System.currentTimeMillis() / 1000F); - if (currentTimeSeconds > expiry) - throw new AuthenticationException("ID Token has expired"); - } - - private void validateAudience(OpenIdConfiguration configuration) throws AuthenticationException - { - Object aud = claims.get("aud"); - String clientId = configuration.getClientId(); - boolean isString = aud instanceof String; - boolean isList = aud instanceof Object[]; - boolean isValidType = isString || isList; - - if (isString && !clientId.equals(aud)) - throw new AuthenticationException("Audience Claim MUST contain the client_id value"); - else if (isList) - { - List list = Arrays.asList((Object[])aud); - if (!list.contains(clientId)) - throw new AuthenticationException("Audience Claim MUST contain the client_id value"); - - if (list.size() > 1 && claims.get("azp") == null) - throw new AuthenticationException("A multi-audience ID token needs to contain an azp claim"); - } - else if (!isValidType) - throw new AuthenticationException("Audience claim was not valid"); - } - - @SuppressWarnings("unchecked") - private Map claimAuthCode(OpenIdConfiguration configuration) throws Exception - { - Fields fields = new Fields(); - fields.add("code", authCode); - fields.add("redirect_uri", redirectUri); - fields.add("grant_type", "authorization_code"); - - Request request = configuration.getHttpClient().POST(configuration.getTokenEndpoint()); - switch (configuration.getAuthMethod()) - { - case "client_secret_basic": - URI uri = URI.create(configuration.getTokenEndpoint()); - Authentication.Result authentication = new BasicAuthentication.BasicResult(uri, configuration.getClientId(), configuration.getClientSecret()); - authentication.apply(request); - break; - case "client_secret_post": - fields.add("client_id", configuration.getClientId()); - fields.add("client_secret", configuration.getClientSecret()); - break; - default: - throw new IllegalStateException(configuration.getAuthMethod()); - } - - FormRequestContent formContent = new FormRequestContent(fields); - request = request.body(formContent).timeout(10, TimeUnit.SECONDS); - ContentResponse response = request.send(); - String responseBody = response.getContentAsString(); - if (LOG.isDebugEnabled()) - LOG.debug("Authentication response: {}", responseBody); - - Object parsedResponse = new JSON().fromJSON(responseBody); - if (!(parsedResponse instanceof Map)) - throw new AuthenticationException("Malformed response from OpenID Provider"); - return (Map)parsedResponse; - } - - public static class AuthenticationException extends Exception - { - public AuthenticationException(String message) - { - super(message); - } - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java deleted file mode 100644 index 53256bbcfb77..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java +++ /dev/null @@ -1,167 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.util.Objects; -import javax.security.auth.Subject; - -import jakarta.servlet.ServletRequest; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.LoginService; -import org.eclipse.jetty.security.UserIdentity; -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * The implementation of {@link LoginService} required to use OpenID Connect. - * - *

    - * Can contain an optional wrapped {@link LoginService} which is used to store role information about users. - *

    - */ -public class OpenIdLoginService extends ContainerLifeCycle implements LoginService -{ - private static final Logger LOG = LoggerFactory.getLogger(OpenIdLoginService.class); - - private final OpenIdConfiguration configuration; - private final LoginService loginService; - private IdentityService identityService; - private boolean authenticateNewUsers; - - public OpenIdLoginService(OpenIdConfiguration configuration) - { - this(configuration, null); - } - - /** - * Use a wrapped {@link LoginService} to store information about user roles. - * Users in the wrapped loginService must be stored with their username as - * the value of the sub (subject) Claim, and a credentials value of the empty string. - * @param configuration the OpenID configuration to use. - * @param loginService the wrapped LoginService to defer to for user roles. - */ - public OpenIdLoginService(OpenIdConfiguration configuration, LoginService loginService) - { - this.configuration = Objects.requireNonNull(configuration); - this.loginService = loginService; - addBean(this.configuration); - addBean(this.loginService); - - setAuthenticateNewUsers(configuration.isAuthenticateNewUsers()); - } - - @Override - public String getName() - { - return configuration.getIssuer(); - } - - public OpenIdConfiguration getConfiguration() - { - return configuration; - } - - @Override - public UserIdentity login(String identifier, Object credentials, ServletRequest req) - { - if (LOG.isDebugEnabled()) - LOG.debug("login({}, {}, {})", identifier, credentials, req); - - OpenIdCredentials openIdCredentials = (OpenIdCredentials)credentials; - try - { - openIdCredentials.redeemAuthCode(configuration); - } - catch (Throwable e) - { - LOG.warn("Unable to redeem auth code", e); - return null; - } - - OpenIdUserPrincipal userPrincipal = new OpenIdUserPrincipal(openIdCredentials); - Subject subject = new Subject(); - subject.getPrincipals().add(userPrincipal); - subject.getPrivateCredentials().add(credentials); - subject.setReadOnly(); - - IdentityService identityService = getIdentityService(); - if (loginService != null) - { - UserIdentity userIdentity = loginService.login(openIdCredentials.getUserId(), "", req); - if (userIdentity == null) - { - if (isAuthenticateNewUsers()) - return identityService.newUserIdentity(subject, userPrincipal, new String[0]); - return null; - } - return new OpenIdUserIdentity(subject, userPrincipal, userIdentity); - } - - return identityService.newUserIdentity(subject, userPrincipal, new String[0]); - } - - public boolean isAuthenticateNewUsers() - { - return authenticateNewUsers; - } - - /** - * This setting is only meaningful if a wrapped {@link LoginService} has been set. - *

    - * If set to true, any users not found by the wrapped {@link LoginService} will still - * be authenticated but with no roles, if set to false users will not be - * authenticated unless they are discovered by the wrapped {@link LoginService}. - *

    - * @param authenticateNewUsers whether to authenticate users not found by a wrapping LoginService - */ - public void setAuthenticateNewUsers(boolean authenticateNewUsers) - { - this.authenticateNewUsers = authenticateNewUsers; - } - - @Override - public boolean validate(UserIdentity user) - { - if (!(user.getUserPrincipal() instanceof OpenIdUserPrincipal)) - return false; - - return loginService == null || loginService.validate(user); - } - - @Override - public IdentityService getIdentityService() - { - return loginService == null ? identityService : loginService.getIdentityService(); - } - - @Override - public void setIdentityService(IdentityService service) - { - if (isRunning()) - throw new IllegalStateException("Running"); - - if (loginService != null) - loginService.setIdentityService(service); - else - identityService = service; - } - - @Override - public void logout(UserIdentity user) - { - if (loginService != null) - loginService.logout(user); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java deleted file mode 100644 index 92a529f1f6e3..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java +++ /dev/null @@ -1,51 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.security.UserIdentity; - -public class OpenIdUserIdentity implements UserIdentity -{ - private final Subject subject; - private final Principal userPrincipal; - private final UserIdentity userIdentity; - - public OpenIdUserIdentity(Subject subject, Principal userPrincipal, UserIdentity userIdentity) - { - this.subject = subject; - this.userPrincipal = userPrincipal; - this.userIdentity = userIdentity; - } - - @Override - public Subject getSubject() - { - return subject; - } - - @Override - public Principal getUserPrincipal() - { - return userPrincipal; - } - - @Override - public boolean isUserInRole(String role, Scope scope) - { - return userIdentity != null && userIdentity.isUserInRole(role, scope); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserPrincipal.java b/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserPrincipal.java deleted file mode 100644 index 9d2b6285e688..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserPrincipal.java +++ /dev/null @@ -1,45 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.io.Serializable; -import java.security.Principal; - -public class OpenIdUserPrincipal implements Principal, Serializable -{ - private static final long serialVersionUID = 1521094652756670469L; - private final OpenIdCredentials _credentials; - - public OpenIdUserPrincipal(OpenIdCredentials credentials) - { - _credentials = credentials; - } - - public OpenIdCredentials getCredentials() - { - return _credentials; - } - - @Override - public String getName() - { - return _credentials.getUserId(); - } - - @Override - public String toString() - { - return _credentials.getUserId(); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtDecoderTest.java b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtDecoderTest.java deleted file mode 100644 index 65b982045aa5..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtDecoderTest.java +++ /dev/null @@ -1,117 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.util.Map; -import java.util.stream.Stream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class JwtDecoderTest -{ - public static Stream paddingExamples() - { - return Stream.of( - Arguments.of("XXXX", "XXXX"), - Arguments.of("XXX", "XXX="), - Arguments.of("XX", "XX=="), - Arguments.of("XXX=", "XXX="), - Arguments.of("X-X", "X-X="), - Arguments.of("@#", "@#=="), - Arguments.of("X=", "X="), - Arguments.of("XX=", "XX="), - Arguments.of("XX==", "XX=="), - Arguments.of("XXX=", "XXX="), - Arguments.of("", "") - ); - } - - public static Stream badPaddingExamples() - { - return Stream.of( - Arguments.of("X"), - Arguments.of("XXXXX") - ); - } - - @ParameterizedTest - @MethodSource("paddingExamples") - public void testPaddingBase64(String input, String expected) - { - byte[] actual = JwtDecoder.padJWTSection(input); - assertThat(actual, is(expected.getBytes())); - } - - @ParameterizedTest - @MethodSource("badPaddingExamples") - public void testPaddingInvalidBase64(String input) - { - IllegalArgumentException error = assertThrows(IllegalArgumentException.class, - () -> JwtDecoder.padJWTSection(input)); - - assertThat(error.getMessage(), is("Not a valid Base64-encoded string")); - } - - @Test - public void testEncodeDecode() - { - String issuer = "example.com"; - String subject = "1234"; - String clientId = "1234.client.id"; - String name = "Bob"; - long expiry = 123; - - // Create a fake ID Token. - String claims = JwtEncoder.createIdToken(issuer, clientId, subject, name, expiry); - String idToken = JwtEncoder.encode(claims); - - // Decode the ID Token and verify the claims are the same. - Map decodedClaims = JwtDecoder.decode(idToken); - assertThat(decodedClaims.get("iss"), is(issuer)); - assertThat(decodedClaims.get("sub"), is(subject)); - assertThat(decodedClaims.get("aud"), is(clientId)); - assertThat(decodedClaims.get("name"), is(name)); - assertThat(decodedClaims.get("exp"), is(expiry)); - } - - @Test - public void testDecodeMissingPadding() - { - // Example given in Issue #4128 which requires the re-adding the B64 padding to decode. - String jwt = "eyJraWQiOiIxNTU1OTM0ODQ3IiwieDV0IjoiOWdCOW9zRldSRHRSMkhtNGNmVnJnWTBGcmZRIiwiYWxnIjoiUlMyNTYifQ" + - ".eyJhdF9oYXNoIjoiQTA0NUoxcE5YRk1nYzlXN2wxSk1fUSIsImRlbGVnYXRpb25faWQiOiJjZTBhNjRlNS0xYWY3LTQ2MzEtOGUz" + - "NC1mNDE5N2JkYzVjZTAiLCJhY3IiOiJ1cm46c2U6Y3VyaXR5OmF1dGhlbnRpY2F0aW9uOmh0bWwtZm9ybTpodG1sLXByaW1hcnkiL" + - "CJzX2hhc2giOiIwc1FtRG9YY3FwcnM4NWUzdy0wbHdBIiwiYXpwIjoiNzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYz" + - "c2IiwiYXV0aF90aW1lIjoxNTY5NjU4MDk1LCJleHAiOjE1Njk2NjE5OTUsIm5iZiI6MTU2OTY1ODM5NSwianRpIjoiZjJkNWI2YzE" + - "tNTIxYi00Y2Y5LThlNWEtOTg5NGJhNmE0MzkyIiwiaXNzIjoiaHR0cHM6Ly9ub3JkaWNhcGlzLmN1cml0eS5pby9-IiwiYXVkIjoi" + - "NzZiZTc5Y2ItM2E1Ni00ZTE3LTg3NzYtNDI1Nzc5MjRjYzc2Iiwic3ViIjoibmlrb3MiLCJpYXQiOjE1Njk2NTgzOTUsInB1cnBvc" + - "2UiOiJpZCJ9.Wd458zNmXggpkDN6vbS3-aiajh4-VbkmcStLYUqahYJUp9p-AUI_RZttWvwh3UDMG9rWww_ya8KFK_SkPfKooEaSN" + - "OjOhw0ox4d-9lgti3J49eRyO20RViXvRHyLVtcjv5IaqvMXgwW60Thubv19OION7DstyArffcxNNSpiqDq6wjd0T2DJ3gSXXlJHLT" + - "Wrry3svqu1j_GCbHc04XYGicxsusKgc3n22dh4I6p4trdo0Gu5Un0bZ8Yov7IzWItqTgm9X5r9gZlAOLcAuK1WTwkzAwZJ24HgvxK" + - "muYfV_4ZCg_VPN2Op8YPuRAQOgUERpeTv1RDFTOG9GKZIMBVR0A"; - - // Decode the ID Token and verify the claims are the correct. - Map decodedClaims = JwtDecoder.decode(jwt); - assertThat(decodedClaims.get("sub"), is("nikos")); - assertThat(decodedClaims.get("aud"), is("76be79cb-3a56-4e17-8776-42577924cc76")); - assertThat(decodedClaims.get("exp"), is(1569661995L)); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticationTest.java b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticationTest.java index bdb82fc1aea8..700b586ca989 100644 --- a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticationTest.java +++ b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticationTest.java @@ -28,6 +28,7 @@ import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.session.FileSessionDataStoreFactory; diff --git a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentialsTest.java b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentialsTest.java deleted file mode 100644 index c12a390df9c0..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentialsTest.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.jetty.client.HttpClient; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -public class OpenIdCredentialsTest -{ - @Test - public void testSingleAudienceValueInArray() throws Exception - { - String issuer = "myIssuer123"; - String clientId = "myClientId456"; - OpenIdConfiguration configuration = new OpenIdConfiguration(issuer, "", "", clientId, "", new HttpClient()); - - Map claims = new HashMap<>(); - claims.put("iss", issuer); - claims.put("aud", new String[]{clientId}); - claims.put("exp", System.currentTimeMillis() + 5000); - - assertDoesNotThrow(() -> new OpenIdCredentials(claims).redeemAuthCode(configuration)); - } -} diff --git a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdProvider.java b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdProvider.java index 9041abeb39df..eea298f9f697 100644 --- a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdProvider.java +++ b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdProvider.java @@ -34,6 +34,7 @@ import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.servlet.ServletHolder; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.StringUtil; diff --git a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdReamNameTest.java b/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdReamNameTest.java deleted file mode 100644 index cf4dd2b9bd97..000000000000 --- a/jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdReamNameTest.java +++ /dev/null @@ -1,184 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security.openid; - -import org.eclipse.jetty.ee9.security.Authenticator; -import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.LoginService; -import org.eclipse.jetty.ee9.servlet.ServletContextHandler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandlerCollection; -import org.eclipse.jetty.util.security.Constraint; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertThrows; - -public class OpenIdReamNameTest -{ - private final Server server = new Server(); - - public static ServletContextHandler configureOpenIdContext(String realmName) - { - ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler(); - assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); - securityHandler.setAuthMethod(Constraint.__OPENID_AUTH); - securityHandler.setRealmName(realmName); - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/" + realmName); - context.setSecurityHandler(securityHandler); - return context; - } - - @Test - public void testSingleConfiguration() throws Exception - { - // Add some OpenID configurations. - OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", - "", "", "", "", null); - server.addBean(config1); - - // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext("This doesn't matter if only 1 OpenIdConfiguration"); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - contextHandlerCollection.addHandler(context1); - server.setHandler(contextHandlerCollection); - - try - { - server.start(); - - // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); - assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); - LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); - assertThat(loginService, instanceOf(OpenIdLoginService.class)); - assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); - } - finally - { - server.stop(); - } - } - - @Test - public void testSingleConfigurationNoRealmName() throws Exception - { - // Add some OpenID configurations. - OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", - "", "", "", "", null); - server.addBean(config1); - - // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext(null); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - contextHandlerCollection.addHandler(context1); - server.setHandler(contextHandlerCollection); - - try - { - server.start(); - - // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); - assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); - LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); - assertThat(loginService, instanceOf(OpenIdLoginService.class)); - assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); - } - finally - { - server.stop(); - } - } - - @Test - public void testMultipleConfiguration() throws Exception - { - // Add some OpenID configurations. - OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", - "", "", "", "", null); - OpenIdConfiguration config2 = new OpenIdConfiguration("provider2", - "", "", "", "", null); - server.addBean(config1); - server.addBean(config2); - - // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext(config1.getIssuer()); - ServletContextHandler context2 = configureOpenIdContext(config2.getIssuer()); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - contextHandlerCollection.addHandler(context1); - contextHandlerCollection.addHandler(context2); - server.setHandler(contextHandlerCollection); - - try - { - server.start(); - - // The OpenIdConfiguration from context1 matches to config1. - Authenticator authenticator = context1.getSecurityHandler().getAuthenticator(); - assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); - LoginService loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); - assertThat(loginService, instanceOf(OpenIdLoginService.class)); - assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config1)); - - // The OpenIdConfiguration from context2 matches to config2. - authenticator = context2.getSecurityHandler().getAuthenticator(); - assertThat(authenticator, instanceOf(OpenIdAuthenticator.class)); - loginService = ((OpenIdAuthenticator)authenticator).getLoginService(); - assertThat(loginService, instanceOf(OpenIdLoginService.class)); - assertThat(((OpenIdLoginService)loginService).getConfiguration(), Matchers.is(config2)); - } - finally - { - server.stop(); - } - } - - @Test - public void testMultipleConfigurationNoMatch() throws Exception - { - // Add some OpenID configurations. - OpenIdConfiguration config1 = new OpenIdConfiguration("provider1", - "", "", "", "", null); - OpenIdConfiguration config2 = new OpenIdConfiguration("provider2", - "", "", "", "", null); - server.addBean(config1); - server.addBean(config2); - - // Configure two webapps to select configs based on realm name. - ServletContextHandler context1 = configureOpenIdContext("provider3"); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - contextHandlerCollection.addHandler(context1); - server.setHandler(contextHandlerCollection); - - // Multiple OpenIdConfigurations were available and didn't match one based on realm name. - assertThrows(IllegalStateException.class, server::start); - } - - @Test - public void testNoConfiguration() throws Exception - { - ServletContextHandler context1 = configureOpenIdContext(null); - ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection(); - contextHandlerCollection.addHandler(context1); - server.setHandler(contextHandlerCollection); - - // If no OpenIdConfigurations are present it is bad configuration. - assertThrows(IllegalStateException.class, server::start); - } -} diff --git a/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java b/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java index 1af55d3155ae..237978845fd5 100644 --- a/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java +++ b/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java @@ -29,10 +29,10 @@ import javax.sql.DataSource; import org.eclipse.jetty.ee9.plus.jndi.NamingEntryUtil; -import org.eclipse.jetty.ee9.security.AbstractLoginService; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.RolePrincipal; -import org.eclipse.jetty.ee9.security.UserPrincipal; +import org.eclipse.jetty.security.AbstractLoginService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.security.Credential; import org.slf4j.Logger; diff --git a/jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java b/jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java index 719ebf6d4801..d75eefc3bdb7 100644 --- a/jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java +++ b/jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java @@ -32,12 +32,12 @@ import org.eclipse.jetty.ee9.nested.SessionHandler; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.HashLoginService; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.webapp.MetaInfConfiguration; import org.eclipse.jetty.ee9.webapp.WebAppContext; import org.eclipse.jetty.io.ConnectionStatistics; +import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.CustomRequestLog; diff --git a/jetty-ee9/jetty-ee9-security/pom.xml b/jetty-ee9/jetty-ee9-security/pom.xml index 76ef21310aa8..1cf8dedb9650 100644 --- a/jetty-ee9/jetty-ee9-security/pom.xml +++ b/jetty-ee9/jetty-ee9-security/pom.xml @@ -35,6 +35,10 @@ org.eclipse.jetty.ee9 jetty-ee9-nested + + org.eclipse.jetty + jetty-security + org.slf4j slf4j-api diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RolePrincipal.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RolePrincipal.java deleted file mode 100644 index 005d29da660b..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RolePrincipal.java +++ /dev/null @@ -1,47 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.Serializable; -import java.security.Principal; -import javax.security.auth.Subject; - -/** - * RolePrincipal - * - * Represents a role. This class can be added to a Subject to represent a role that the - * Subject has. - * - */ -public class RolePrincipal implements Principal, Serializable -{ - private static final long serialVersionUID = 2998397924051854402L; - private final String _roleName; - - public RolePrincipal(String name) - { - _roleName = name; - } - - @Override - public String getName() - { - return _roleName; - } - - public void configureForSubject(Subject subject) - { - subject.getPrincipals().add(this); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java deleted file mode 100644 index f85173938d7a..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java +++ /dev/null @@ -1,38 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -/** - * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ - */ -public class RoleRunAsToken implements RunAsToken -{ - private final String _runAsRole; - - public RoleRunAsToken(String runAsRole) - { - this._runAsRole = runAsRole; - } - - public String getRunAsRole() - { - return _runAsRole; - } - - @Override - public String toString() - { - return "RoleRunAsToken(" + _runAsRole + ")"; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RunAsToken.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RunAsToken.java deleted file mode 100644 index e28cc732be67..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RunAsToken.java +++ /dev/null @@ -1,23 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -/** - * marker interface for run-as-role tokens - * - * @version $Rev: 4701 $ $Date: 2009-03-03 13:01:26 +0100 (Tue, 03 Mar 2009) $ - */ -public interface RunAsToken -{ -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java index d70ffab49057..cc20ad6e38e4 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java @@ -39,6 +39,7 @@ import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.component.DumpableCollection; import org.slf4j.Logger; @@ -503,7 +504,7 @@ public void handle(String pathInContext, Request baseRequest, HttpServletRequest } // check authentication - Object previousIdentity = null; + IdentityService.Association identityAssociation = null; try { Authentication authentication = baseRequest.getAuthentication(); @@ -525,7 +526,7 @@ else if (authentication instanceof Authentication.User) Authentication.User userAuth = (Authentication.User)authentication; baseRequest.setAuthentication(authentication); if (_identityService != null) - previousIdentity = _identityService.associate(userAuth.getUserIdentity()); + identityAssociation = _identityService.associate(userAuth.getUserIdentity()); if (isAuthMandatory) { @@ -553,7 +554,7 @@ else if (authentication instanceof Authentication.Deferred) } finally { - previousIdentity = deferred.getPreviousAssociation(); + identityAssociation = deferred.getAssociation(); } if (authenticator != null) @@ -577,7 +578,7 @@ else if (isAuthMandatory) { baseRequest.setAuthentication(authentication); if (_identityService != null) - previousIdentity = _identityService.associate(null); + identityAssociation = _identityService.associate(null); handler.handle(pathInContext, baseRequest, request, response); if (authenticator != null) authenticator.secureResponse(request, response, isAuthMandatory, null); @@ -591,8 +592,7 @@ else if (isAuthMandatory) } finally { - if (_identityService != null) - _identityService.disassociate(previousIdentity); + IO.close(identityAssociation); } } else @@ -622,11 +622,7 @@ public void logout(Authentication.User user) IdentityService identityService = getIdentityService(); if (identityService != null) - { - // TODO recover previous from threadlocal (or similar) - Object previous = null; - identityService.disassociate(previous); - } + identityService.logout(user.getUserIdentity()); } protected abstract RoleInfo prepareConstraintInfo(String pathInContext, Request request); diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserPrincipal.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserPrincipal.java deleted file mode 100644 index 544025bc79f9..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserPrincipal.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.Serializable; -import java.security.Principal; -import javax.security.auth.Subject; - -import org.eclipse.jetty.util.security.Credential; - -/** - * UserPrincipal - * - * Represents a user with a credential. - * Instances of this class can be added to a Subject to - * present the user, while the credentials can be added - * directly to the Subject. - */ -public class UserPrincipal implements Principal, Serializable -{ - private static final long serialVersionUID = -6226920753748399662L; - private final String _name; - protected final Credential _credential; - - public UserPrincipal(String name, Credential credential) - { - _name = name; - _credential = credential; - } - - public boolean authenticate(Object credentials) - { - return _credential != null && _credential.check(credentials); - } - - public boolean authenticate(Credential c) - { - return (_credential != null && c != null && _credential.equals(c)); - } - - public boolean authenticate(UserPrincipal u) - { - return (u != null && authenticate(u._credential)); - } - - public void configureSubject(Subject subject) - { - if (subject == null) - return; - - subject.getPrincipals().add(this); - if (_credential != null) - subject.getPrivateCredentials().add(_credential); - } - - public void deconfigureSubject(Subject subject) - { - if (subject == null) - return; - subject.getPrincipals().remove(this); - if (_credential != null) - subject.getPrivateCredentials().remove(_credential); - } - - @Override - public String getName() - { - return _name; - } - - @Override - public String toString() - { - return _name; - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserStore.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserStore.java deleted file mode 100644 index 3e0062a1187b..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserStore.java +++ /dev/null @@ -1,87 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import org.eclipse.jetty.util.component.ContainerLifeCycle; -import org.eclipse.jetty.util.security.Credential; - -/** - * Store of user authentication and authorization information. - * - */ -public class UserStore extends ContainerLifeCycle -{ - protected final Map _users = new ConcurrentHashMap<>(); - - protected class User - { - protected UserPrincipal _userPrincipal; - protected List _rolePrincipals = Collections.emptyList(); - - protected User(String username, Credential credential, String[] roles) - { - _userPrincipal = new UserPrincipal(username, credential); - - _rolePrincipals = Collections.emptyList(); - - if (roles != null) - _rolePrincipals = Arrays.stream(roles).map(RolePrincipal::new).collect(Collectors.toList()); - } - - protected UserPrincipal getUserPrincipal() - { - return _userPrincipal; - } - - protected List getRolePrincipals() - { - return _rolePrincipals; - } - } - - public void addUser(String username, Credential credential, String[] roles) - { - _users.put(username, new User(username, credential, roles)); - } - - public void removeUser(String username) - { - _users.remove(username); - } - - public UserPrincipal getUserPrincipal(String username) - { - User user = _users.get(username); - return (user == null ? null : user.getUserPrincipal()); - } - - public List getRolePrincipals(String username) - { - User user = _users.get(username); - return (user == null ? null : user.getRolePrincipals()); - } - - @Override - public String toString() - { - return String.format("%s@%x[users.count=%d]", getClass().getSimpleName(), hashCode(), _users.size()); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java index fd26ae42a171..1c16efe451b9 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java @@ -27,17 +27,19 @@ import org.eclipse.jetty.ee9.nested.Authentication.User; import org.eclipse.jetty.ee9.nested.Request; import org.eclipse.jetty.ee9.security.ServerAuthException; -import org.eclipse.jetty.ee9.security.SpnegoUserIdentity; -import org.eclipse.jetty.ee9.security.SpnegoUserPrincipal; import org.eclipse.jetty.ee9.security.UserAuthentication; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.security.ConfigurableSpnegoLoginService; +import org.eclipse.jetty.security.SpnegoUserIdentity; +import org.eclipse.jetty.security.SpnegoUserPrincipal; import org.eclipse.jetty.security.UserIdentity; import org.eclipse.jetty.util.security.Constraint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.eclipse.jetty.ee9.nested.SessionHandler.ServletSessionApi.newGetSession; + /** *

    A LoginAuthenticator that uses SPNEGO and the GSS API to authenticate requests.

    *

    A successful authentication from a client is cached for a configurable @@ -102,7 +104,7 @@ public void setAuthenticationDuration(Duration authenticationDuration) @Override public UserIdentity login(String username, Object password, ServletRequest servletRequest) { - SpnegoUserIdentity user = (SpnegoUserIdentity)_loginService.login(username, password, servletRequest); + SpnegoUserIdentity user = (SpnegoUserIdentity)_loginService.login(username, password, newGetSession(servletRequest)); if (user != null && user.isEstablished()) { Request request = Request.getBaseRequest(servletRequest); diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java index 6d2ce34b70e8..34973b0cb819 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java @@ -41,7 +41,7 @@ public class DeferredAuthentication implements Authentication.Deferred { private static final Logger LOG = LoggerFactory.getLogger(DeferredAuthentication.class); protected final LoginAuthenticator _authenticator; - private Object _previousAssociation; + private IdentityService.Association _association; public DeferredAuthentication(LoginAuthenticator authenticator) { @@ -62,7 +62,7 @@ public Authentication authenticate(ServletRequest request) IdentityService identityService = loginService.getIdentityService(); if (identityService != null) - _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); return authentication; } @@ -85,7 +85,7 @@ public Authentication authenticate(ServletRequest request, ServletResponse respo Authentication authentication = _authenticator.validateRequest(request, response, true); if (authentication instanceof Authentication.User && identityService != null) - _previousAssociation = identityService.associate(((Authentication.User)authentication).getUserIdentity()); + _association = identityService.associate(((Authentication.User)authentication).getUserIdentity()); return authentication; } catch (ServerAuthException e) @@ -107,7 +107,7 @@ public Authentication login(String username, Object password, ServletRequest req IdentityService identityService = _authenticator.getLoginService().getIdentityService(); UserAuthentication authentication = new UserAuthentication("API", identity); if (identityService != null) - _previousAssociation = identityService.associate(identity); + _association = identityService.associate(identity); return authentication; } return null; @@ -127,9 +127,9 @@ public Authentication logout(ServletRequest request) return Authentication.UNAUTHENTICATED; } - public Object getPreviousAssociation() + public IdentityService.Association getAssociation() { - return _previousAssociation; + return _association; } /** diff --git a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java index 3bcea42ab0c8..a2825bbf4593 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java +++ b/jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java @@ -13,6 +13,8 @@ package org.eclipse.jetty.ee9.security.authentication; +import java.util.function.Function; + import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -28,6 +30,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.eclipse.jetty.ee9.nested.SessionHandler.ServletSessionApi.newGetSession; + public abstract class LoginAuthenticator implements Authenticator { private static final Logger LOG = LoggerFactory.getLogger(LoginAuthenticator.class); @@ -47,7 +51,7 @@ public void prepareRequest(ServletRequest request) } /** - * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, ServletRequest)}, it + * If the UserIdentity is not null after this method calls {@link LoginService#login(String, Object, Function)}, it * is assumed that the user is fully authenticated and we need to change the session id to prevent * session fixation vulnerability. If the UserIdentity is not necessarily fully * authenticated, then subclasses must override this method and @@ -59,7 +63,7 @@ public void prepareRequest(ServletRequest request) */ public UserIdentity login(String username, Object password, ServletRequest servletRequest) { - UserIdentity user = _loginService.login(username, password, servletRequest); + UserIdentity user = _loginService.login(username, password, newGetSession(servletRequest)); if (user != null) { Request request = Request.getBaseRequest(servletRequest); diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ClientCertAuthenticatorTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ClientCertAuthenticatorTest.java index 980974657735..68fa584032ac 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ClientCertAuthenticatorTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ClientCertAuthenticatorTest.java @@ -28,6 +28,7 @@ import org.eclipse.jetty.ee9.nested.AbstractHandler; import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; +import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConfiguration; import org.eclipse.jetty.server.HttpConnectionFactory; diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java index cee7b6c7a99e..1a473b840c1f 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java @@ -15,9 +15,9 @@ import java.io.IOException; import java.util.Arrays; +import java.util.function.Function; import jakarta.servlet.ServletException; -import jakarta.servlet.ServletRequest; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.AbstractHandler; @@ -28,11 +28,16 @@ import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpURI; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.internal.DefaultUserIdentity; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.security.Constraint; import org.hamcrest.Matchers; import org.junit.jupiter.api.AfterEach; @@ -434,7 +439,7 @@ public String getName() } @Override - public UserIdentity login(String username, Object credentials, ServletRequest request) + public UserIdentity login(String username, Object credentials, Function getSession) { if ("admin".equals(username) && "password".equals(credentials)) return new DefaultUserIdentity(null, null, new String[]{"admin"}); diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java index 9ea397f3f6e0..81ed34f45722 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java @@ -17,6 +17,8 @@ import jakarta.servlet.ServletResponse; import org.eclipse.jetty.ee9.nested.Authentication; import org.eclipse.jetty.ee9.nested.ContextHandler; +import org.eclipse.jetty.security.DefaultIdentityService; +import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.server.Server; import org.junit.jupiter.api.Test; diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/HashLoginServiceTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/HashLoginServiceTest.java deleted file mode 100644 index 5d3ff161fb8c..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/HashLoginServiceTest.java +++ /dev/null @@ -1,85 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.nio.file.Path; - -import org.eclipse.jetty.toolchain.test.MavenTestingUtils; -import org.eclipse.jetty.util.resource.FileSystemPool; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Tests of the HashLoginService. - */ -public class HashLoginServiceTest -{ - @BeforeEach - public void beforeEach() - { - assertThat(FileSystemPool.INSTANCE.mounts(), empty()); - } - - @AfterEach - public void afterEach() - { - assertThat(FileSystemPool.INSTANCE.mounts(), empty()); - } - - @Test - public void testAutoCreatedUserStore() throws Exception - { - Path fooPropsFile = MavenTestingUtils.getTargetPath("test-classes/foo.properties"); - Resource fooResource = ResourceFactory.root().newResource(fooPropsFile); - HashLoginService loginService = new HashLoginService("foo", fooResource); - assertThat(loginService.getIdentityService(), is(notNullValue())); - loginService.start(); - assertTrue(loginService.getUserStore().isStarted()); - assertTrue(loginService.isUserStoreAutoCreate()); - - loginService.stop(); - assertFalse(loginService.isUserStoreAutoCreate()); - assertThat(loginService.getUserStore(), is(nullValue())); - } - - @Test - public void testProvidedUserStore() throws Exception - { - HashLoginService loginService = new HashLoginService("foo"); - assertThat(loginService.getIdentityService(), is(notNullValue())); - UserStore store = new UserStore(); - loginService.setUserStore(store); - assertFalse(store.isStarted()); - loginService.start(); - assertTrue(loginService.getUserStore().isStarted()); - assertFalse(loginService.isUserStoreAutoCreate()); - - loginService.stop(); - - assertFalse(loginService.isUserStoreAutoCreate()); - assertFalse(store.isStarted()); - assertThat(loginService.getUserStore(), is(notNullValue())); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java deleted file mode 100644 index 408c9c6a9bf5..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java +++ /dev/null @@ -1,334 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Writer; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; - -import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; -import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension; -import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.NanoTime; -import org.eclipse.jetty.util.Scanner; -import org.eclipse.jetty.util.URIUtil; -import org.eclipse.jetty.util.resource.FileSystemPool; -import org.eclipse.jetty.util.resource.Resource; -import org.eclipse.jetty.util.resource.ResourceFactory; -import org.eclipse.jetty.util.security.Credential; -import org.hamcrest.Matcher; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.OS; -import org.junit.jupiter.api.extension.ExtendWith; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -@ExtendWith(WorkDirExtension.class) -public class PropertyUserStoreTest -{ - private static final class UserCount implements PropertyUserStore.UserListener - { - private final AtomicInteger userCount = new AtomicInteger(); - private final List users = new ArrayList<>(); - - private UserCount() - { - } - - @Override - public void update(String username, Credential credential, String[] roleArray) - { - if (!users.contains(username)) - { - users.add(username); - userCount.getAndIncrement(); - } - } - - @Override - public void remove(String username) - { - users.remove(username); - userCount.getAndDecrement(); - } - - public void awaitCount(int expectedCount) throws InterruptedException - { - long start = NanoTime.now(); - while (userCount.get() != expectedCount && NanoTime.secondsSince(start) < 10) - { - TimeUnit.MILLISECONDS.sleep(100); - } - - assertThatCount(is(expectedCount)); - } - - public void assertThatCount(Matcher matcher) - { - assertThat("User count", userCount.get(), matcher); - } - - public void assertThatUsers(Matcher> matcher) - { - assertThat("Users list", users, matcher); - } - } - - public WorkDir testdir; - - @BeforeEach - public void beforeEach() - { - assertThat(FileSystemPool.INSTANCE.mounts(), empty()); - } - - @AfterEach - public void afterEach() - { - assertThat(FileSystemPool.INSTANCE.mounts(), empty()); - } - - private Path initUsersText() throws Exception - { - Path dir = testdir.getPath(); - Path users = dir.resolve("users.txt"); - Files.deleteIfExists(users); - - writeUser(users); - return users; - } - - private URI initUsersPackedFileText() - throws Exception - { - Path dir = testdir.getPath(); - Path users = dir.resolve("users.txt"); - writeUser(users); - Path usersJar = dir.resolve("users.jar"); - String entryPath = "mountain_goat/pale_ale.txt"; - try (InputStream fileInputStream = Files.newInputStream(users)) - { - try (OutputStream outputStream = Files.newOutputStream(usersJar)) - { - try (JarOutputStream jarOutputStream = new JarOutputStream(outputStream)) - { - // add fake entry - jarOutputStream.putNextEntry(new JarEntry("foo/wine")); - - JarEntry jarEntry = new JarEntry(entryPath); - jarOutputStream.putNextEntry(jarEntry); - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = fileInputStream.read(buffer)) != -1) - { - jarOutputStream.write(buffer, 0, bytesRead); - } - // add fake entry - jarOutputStream.putNextEntry(new JarEntry("foo/cheese")); - } - } - } - return URIUtil.uriJarPrefix(usersJar.toUri(), "!/" + entryPath); - } - - private void writeUser(File usersFile) throws IOException - { - writeUser(usersFile.toPath()); - } - - private void writeUser(Path usersFile) throws IOException - { - try (Writer writer = Files.newBufferedWriter(usersFile, UTF_8)) - { - writer.append("tom: tom, roleA\n"); - writer.append("dick: dick, roleB\n"); - writer.append("harry: harry, roleA, roleB\n"); - } - } - - private void addAdditionalUser(Path usersFile, String userRef) throws Exception - { - Thread.sleep(1001); - try (Writer writer = Files.newBufferedWriter(usersFile, UTF_8, StandardOpenOption.APPEND)) - { - writer.append(userRef); - } - } - - @Test - public void testPropertyUserStoreLoad() throws Exception - { - testdir.ensureEmpty(); - - final UserCount userCount = new UserCount(); - final Path usersFile = initUsersText(); - - PropertyUserStore store = new PropertyUserStore(); - store.setConfig(ResourceFactory.root().newResource(usersFile)); - - store.registerUserListener(userCount); - - store.start(); - - assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("tom"), notNullValue()); - assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("dick"), notNullValue()); - assertThat("Failed to retrieve user directly from PropertyUserStore", store.getUserPrincipal("harry"), notNullValue()); - userCount.assertThatCount(is(3)); - userCount.awaitCount(3); - } - - @Test - public void testPropertyUserStoreFails() - { - assertThrows(IllegalStateException.class, () -> - { - PropertyUserStore store = new PropertyUserStore(); - Resource doesNotExist = ResourceFactory.root().newResource("file:///this/file/does/not/exist.txt"); - store.setConfig(doesNotExist); - store.start(); - }); - } - - @Test - public void testPropertyUserStoreLoadFromJarFile() throws Exception - { - testdir.ensureEmpty(); - - final UserCount userCount = new UserCount(); - final URI usersFile = initUsersPackedFileText(); - - try (ResourceFactory.Closeable resourceFactory = ResourceFactory.closeable()) - { - Resource jarResource = resourceFactory.newResource(usersFile); - PropertyUserStore store = new PropertyUserStore(); - store.setConfig(jarResource); - - store.registerUserListener(userCount); - - store.start(); - - assertThat("Failed to retrieve user directly from PropertyUserStore", // - store.getUserPrincipal("tom"), notNullValue()); - assertThat("Failed to retrieve user directly from PropertyUserStore", // - store.getUserPrincipal("dick"), notNullValue()); - assertThat("Failed to retrieve user directly from PropertyUserStore", // - store.getUserPrincipal("harry"), notNullValue()); - userCount.assertThatCount(is(3)); - userCount.awaitCount(3); - } - } - - @Test - public void testPropertyUserStoreLoadUpdateUser() throws Exception - { - testdir.ensureEmpty(); - - final UserCount userCount = new UserCount(); - final Path usersFile = initUsersText(); - final AtomicInteger loadCount = new AtomicInteger(0); - PropertyUserStore store = new PropertyUserStore() - { - @Override - protected void loadUsers() throws IOException - { - loadCount.incrementAndGet(); - super.loadUsers(); - } - }; - store.setRefreshInterval(1); - store.setConfig(ResourceFactory.root().newResource(usersFile)); - store.registerUserListener(userCount); - - store.start(); - - userCount.assertThatCount(is(3)); - assertThat(loadCount.get(), is(1)); - - addAdditionalUser(usersFile, "skip: skip, roleA\n"); - userCount.awaitCount(4); - assertThat(loadCount.get(), is(2)); - assertThat(store.getUserPrincipal("skip"), notNullValue()); - userCount.assertThatCount(is(4)); - userCount.assertThatUsers(hasItem("skip")); - - if (OS.LINUX.isCurrentOs()) - Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt"), - PosixFilePermissions.asFileAttribute(EnumSet.noneOf(PosixFilePermission.class))); - else - Files.createFile(testdir.getPath().toRealPath().resolve("unrelated.txt")); - - Scanner scanner = store.getBean(Scanner.class); - CountDownLatch latch = new CountDownLatch(2); - scanner.scan(Callback.from(latch::countDown)); - scanner.scan(Callback.from(latch::countDown)); - assertTrue(latch.await(5, TimeUnit.SECONDS)); - assertThat(loadCount.get(), is(2)); - - userCount.assertThatCount(is(4)); - userCount.assertThatUsers(hasItem("skip")); - } - - @Test - public void testPropertyUserStoreLoadRemoveUser() throws Exception - { - testdir.ensureEmpty(); - - final UserCount userCount = new UserCount(); - // initial user file (3) users - final Path usersFile = initUsersText(); - - // adding 4th user - addAdditionalUser(usersFile, "skip: skip, roleA\n"); - - PropertyUserStore store = new PropertyUserStore(); - store.setHotReload(true); - store.setConfig(ResourceFactory.root().newResource(usersFile)); - - store.registerUserListener(userCount); - - store.start(); - - userCount.assertThatCount(is(4)); - - // rewrite file with original 3 users - initUsersText(); - - userCount.awaitCount(3); - } -} diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/SpecExampleConstraintTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/SpecExampleConstraintTest.java index fdb6b5a17db4..1ec515097314 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/SpecExampleConstraintTest.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/SpecExampleConstraintTest.java @@ -68,7 +68,7 @@ public static void startServer() TestLoginService loginService = new TestLoginService(TEST_REALM); - loginService.putUser("fred", new Password("password"), IdentityService.NO_ROLES); + loginService.putUser("fred", new Password("password"), new String[0]); loginService.putUser("harry", new Password("password"), new String[]{"HOMEOWNER"}); loginService.putUser("chris", new Password("password"), new String[]{"CONTRACTOR"}); loginService.putUser("steven", new Password("password"), new String[]{"SALESCLERK"}); diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/TestLoginService.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/TestLoginService.java index c3e04822101c..072a26d0b44c 100644 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/TestLoginService.java +++ b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/TestLoginService.java @@ -15,6 +15,10 @@ import java.util.List; +import org.eclipse.jetty.security.AbstractLoginService; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; +import org.eclipse.jetty.security.UserStore; import org.eclipse.jetty.util.security.Credential; /** @@ -23,7 +27,7 @@ public class TestLoginService extends AbstractLoginService { - UserStore userStore = new UserStore(); + org.eclipse.jetty.security.UserStore userStore = new UserStore(); public TestLoginService(String name) { diff --git a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java b/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java deleted file mode 100644 index d60027dd33c9..000000000000 --- a/jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java +++ /dev/null @@ -1,56 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.ee9.security; - -import java.util.List; - -import org.eclipse.jetty.util.security.Credential; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; - -public class UserStoreTest -{ - UserStore userStore; - - @BeforeEach - public void setup() - { - userStore = new UserStore(); - } - - @Test - public void addUser() - { - userStore.addUser("foo", Credential.getCredential("beer"), new String[]{"pub"}); - assertNotNull(userStore.getUserPrincipal("foo")); - - List rps = userStore.getRolePrincipals("foo"); - assertNotNull(rps); - assertNotNull(rps.get(0)); - assertEquals("pub", rps.get(0).getName()); - } - - @Test - public void removeUser() - { - this.userStore.addUser("foo", Credential.getCredential("beer"), new String[]{"pub"}); - assertNotNull(userStore.getUserPrincipal("foo")); - userStore.removeUser("foo"); - assertNull(userStore.getUserPrincipal("foo")); - } -} diff --git a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java index d5513e9d42ac..581b79feae6d 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java +++ b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java @@ -50,7 +50,7 @@ import org.eclipse.jetty.ee9.nested.ServletPathMapping; import org.eclipse.jetty.ee9.nested.ServletRequestHttpWrapper; import org.eclipse.jetty.ee9.nested.ServletResponseHttpWrapper; -import org.eclipse.jetty.ee9.security.IdentityService; +import org.eclipse.jetty.ee9.nested.UserIdentityScope; import org.eclipse.jetty.ee9.security.SecurityHandler; import org.eclipse.jetty.http.pathmap.MappedResource; import org.eclipse.jetty.http.pathmap.MatchedPath; @@ -58,7 +58,7 @@ import org.eclipse.jetty.http.pathmap.PathMappings; import org.eclipse.jetty.http.pathmap.PathSpec; import org.eclipse.jetty.http.pathmap.ServletPathSpec; -import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.IdentityService; import org.eclipse.jetty.util.ArrayUtil; import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.MultiMap; @@ -458,7 +458,7 @@ public void doScope(String target, Request baseRequest, HttpServletRequest reque final ServletPathMapping old_servlet_path_mapping = baseRequest.getServletPathMapping(); ServletHolder servletHolder = null; - UserIdentity.Scope oldScope = null; + UserIdentityScope oldScope = null; MatchedResource matched = getMatchedServlet(target); if (matched != null) diff --git a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java index d46a9d122499..079261903955 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java +++ b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java @@ -45,9 +45,10 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.nested.ContextHandler; import org.eclipse.jetty.ee9.nested.Request; -import org.eclipse.jetty.ee9.security.IdentityService; -import org.eclipse.jetty.ee9.security.RunAsToken; -import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.ee9.nested.UserIdentityScope; +import org.eclipse.jetty.security.IdentityService; +import org.eclipse.jetty.security.IdentityService.Association; +import org.eclipse.jetty.security.IdentityService.RunAsToken; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.NanoTime; import org.eclipse.jetty.util.StringUtil; @@ -68,7 +69,7 @@ * requested. */ @ManagedObject("Servlet Holder") -public class ServletHolder extends Holder implements UserIdentity.Scope, Comparable +public class ServletHolder extends Holder implements UserIdentityScope, Comparable { private static final Logger LOG = LoggerFactory.getLogger(ServletHolder.class); private int _initOrder = -1; @@ -1351,43 +1352,28 @@ public RunAs(Servlet servlet, IdentityService identityService, RunAsToken runAsT @Override public void init(ServletConfig config) throws ServletException { - Object oldRunAs = _identityService.setRunAs(_identityService.getSystemUserIdentity(), _runAsToken); - try + try(Association ignored = _identityService.associate(_identityService.getSystemUserIdentity(), _runAsToken)) { getWrapped().init(config); } - finally - { - _identityService.unsetRunAs(oldRunAs); - } } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - Object oldRunAs = _identityService.setRunAs(_identityService.getSystemUserIdentity(), _runAsToken); - try + try (Association ignored = _identityService.associate(_identityService.getSystemUserIdentity(), _runAsToken)) { getWrapped().service(req, res); } - finally - { - _identityService.unsetRunAs(oldRunAs); - } } @Override public void destroy() { - Object oldRunAs = _identityService.setRunAs(_identityService.getSystemUserIdentity(), _runAsToken); - try + try (Association ignored = _identityService.associate(_identityService.getSystemUserIdentity(), _runAsToken)) { getWrapped().destroy(); } - finally - { - _identityService.unsetRunAs(oldRunAs); - } } } diff --git a/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CustomRequestLogTest.java b/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CustomRequestLogTest.java index 609b032a83d0..97791850dcf6 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CustomRequestLogTest.java +++ b/jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CustomRequestLogTest.java @@ -26,10 +26,10 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.HashLoginService; -import org.eclipse.jetty.ee9.security.UserStore; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.http.HttpHeader; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.UserStore; import org.eclipse.jetty.server.CustomRequestLog; import org.eclipse.jetty.server.LocalConnector; import org.eclipse.jetty.server.RequestLog; diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DigestPostTest.java b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DigestPostTest.java index d76f1fabfc42..7ed33cb0eb89 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DigestPostTest.java +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DigestPostTest.java @@ -37,14 +37,14 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.Request; import org.eclipse.jetty.client.StringRequestContent; -import org.eclipse.jetty.ee9.security.AbstractLoginService; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.RolePrincipal; -import org.eclipse.jetty.ee9.security.UserPrincipal; import org.eclipse.jetty.ee9.security.authentication.DigestAuthenticator; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.http.HttpMethod; +import org.eclipse.jetty.security.AbstractLoginService; +import org.eclipse.jetty.security.RolePrincipal; +import org.eclipse.jetty.security.UserPrincipal; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DatabaseLoginServiceTestServer.java b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DatabaseLoginServiceTestServer.java index 00e6ac3e1735..04b4defeab28 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DatabaseLoginServiceTestServer.java +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DatabaseLoginServiceTestServer.java @@ -35,12 +35,12 @@ import jakarta.servlet.http.HttpServletResponse; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.servlet.DefaultServlet; import org.eclipse.jetty.ee9.servlet.FilterHolder; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.servlet.ServletHolder; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.util.IO; diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/JdbcLoginServiceTest.java b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/JdbcLoginServiceTest.java index f4479057734d..e5c243316c97 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/JdbcLoginServiceTest.java +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/JdbcLoginServiceTest.java @@ -29,10 +29,10 @@ import org.eclipse.jetty.client.ContentResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.Request; -import org.eclipse.jetty.ee9.security.JDBCLoginService; -import org.eclipse.jetty.ee9.security.LoginService; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.security.JDBCLoginService; +import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.IO; diff --git a/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java b/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java index 792bba63f07f..807b097a000c 100644 --- a/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java +++ b/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java @@ -29,12 +29,12 @@ import jakarta.websocket.WebSocketContainer; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.HashLoginService; import org.eclipse.jetty.ee9.security.SecurityHandler; -import org.eclipse.jetty.ee9.security.UserStore; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.UserStore; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.security.Constraint; diff --git a/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketServletExamplesTest.java b/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketServletExamplesTest.java index 3574e25f3de1..69b9a7497e23 100644 --- a/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketServletExamplesTest.java +++ b/jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketServletExamplesTest.java @@ -21,9 +21,7 @@ import org.eclipse.jetty.client.BasicAuthentication; import org.eclipse.jetty.ee9.security.ConstraintMapping; import org.eclipse.jetty.ee9.security.ConstraintSecurityHandler; -import org.eclipse.jetty.ee9.security.HashLoginService; import org.eclipse.jetty.ee9.security.SecurityHandler; -import org.eclipse.jetty.ee9.security.UserStore; import org.eclipse.jetty.ee9.security.authentication.BasicAuthenticator; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.websocket.api.Session; @@ -33,6 +31,8 @@ import org.eclipse.jetty.ee9.websocket.tests.examples.MyAdvancedEchoServlet; import org.eclipse.jetty.ee9.websocket.tests.examples.MyAuthedServlet; import org.eclipse.jetty.ee9.websocket.tests.examples.MyEchoServlet; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.UserStore; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.security.Constraint; diff --git a/jetty-ee9/pom.xml b/jetty-ee9/pom.xml index 5bc1058eb66e..b0646ccb91a4 100644 --- a/jetty-ee9/pom.xml +++ b/jetty-ee9/pom.xml @@ -58,7 +58,6 @@ jetty-ee9-glassfish-jstl jetty-ee9-annotations jetty-ee9-cdi - jetty-ee9-jaas jetty-ee9-jaspi jetty-ee9-jndi jetty-ee9-jspc-maven-plugin diff --git a/pom.xml b/pom.xml index 3243743eff90..a9848c8290e8 100644 --- a/pom.xml +++ b/pom.xml @@ -1260,6 +1260,11 @@ jetty-nosql ${project.version} + + org.eclipse.jetty + jetty-openid + ${project.version} + org.eclipse.jetty jetty-osgi diff --git a/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/OpenIdProvider.java b/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/OpenIdProvider.java index 35a30c94e774..7fbfdf10a596 100644 --- a/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/OpenIdProvider.java +++ b/tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/OpenIdProvider.java @@ -28,10 +28,10 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.eclipse.jetty.ee9.security.openid.OpenIdConfiguration; import org.eclipse.jetty.ee9.servlet.ServletContextHandler; import org.eclipse.jetty.ee9.servlet.ServletHolder; import org.eclipse.jetty.http.HttpVersion; +import org.eclipse.jetty.security.openid.OpenIdConfiguration; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.util.StringUtil; From 3015c490e76941b110bef7a134aa4b460ecd10e6 Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 7 Apr 2023 16:51:10 +0200 Subject: [PATCH 029/129] WIP to using core for EE9 --- .../java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java index aad0cbd16056..866dd5c74176 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentityScope.java @@ -50,7 +50,7 @@ static String deRefRole(UserIdentityScope scope, String role) if (scope == null) return role; - Map roleRefMap = scope.getRoleRefMap(); + Map roleRefMap = scope.getRoleRefMap(); if (roleRefMap == null || roleRefMap.isEmpty()) return role; From e654b3a458cacc85a7cc1a8b9cd7d4af5cb23d34 Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 7 Apr 2023 18:12:36 +0200 Subject: [PATCH 030/129] WIP to using core for EE9 --- .../main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java index 079261903955..b683d4e4bf77 100644 --- a/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java +++ b/jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java @@ -1352,7 +1352,7 @@ public RunAs(Servlet servlet, IdentityService identityService, RunAsToken runAsT @Override public void init(ServletConfig config) throws ServletException { - try(Association ignored = _identityService.associate(_identityService.getSystemUserIdentity(), _runAsToken)) + try (Association ignored = _identityService.associate(_identityService.getSystemUserIdentity(), _runAsToken)) { getWrapped().init(config); } From 071e29b92a6068ad4e43a92b969b97da1fedd63b Mon Sep 17 00:00:00 2001 From: gregw Date: Fri, 7 Apr 2023 23:30:19 +0200 Subject: [PATCH 031/129] WIP to using core for EE9 --- inceptionDates.csv | 16 ++++++++-------- .../jetty-ee8-demo-jetty-webapp/pom.xml | 2 +- .../embedded-jetty-web-for-webbundle.xml | 2 +- .../jetty-ee8-demo-spec-webapp/pom.xml | 2 +- .../jetty-ee9-demo-jetty-webapp/pom.xml | 2 +- .../embedded-jetty-web-for-webbundle.xml | 2 +- .../jetty-ee9-demo-spec-webapp/pom.xml | 2 +- .../templates/annotations-context-header.xml | 2 +- .../src/test/config/etc/jetty-testrealm.xml | 2 +- .../src/test/resources/login-service.xml | 2 +- .../src/test/resources/test-spec.xml | 2 +- .../src/test/resources/test.xml | 2 +- .../modules/demo.d/jetty-ee8-demo-realm.xml | 2 +- .../modules/demo.d/jetty-ee9-demo-realm.xml | 2 +- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/inceptionDates.csv b/inceptionDates.csv index 5c3d1ef87b6b..b97de0f8f868 100644 --- a/inceptionDates.csv +++ b/inceptionDates.csv @@ -328,9 +328,9 @@ jetty-ee9/jetty-ee9-jndi/src/main/java/org/eclipse/jetty/ee9/jndi/factories/Mail jetty-ee9/jetty-ee9-jndi/src/main/java/org/eclipse/jetty/ee9/jndi/factories/package-info.java, 2012-11-02 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java, 2007-04-19 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java, 2010-10-12 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/TestLoginService.java, 2015-11-26 +jetty-ee9/jetty-ee9-security/src/test/java/org.eclipse.jetty.security.TestLoginService.java, 2015-11-26 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java, 2012-01-17 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/HashLoginServiceTest.java, 2019-05-07 +jetty-ee9/jetty-ee9-security/src/test/java/org.eclipse.jetty.security.HashLoginServiceTest.java, 2019-05-07 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java, 2021-08-25 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UnauthenticatedTest.java, 2021-08-20 jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java, 2017-04-20 @@ -354,20 +354,20 @@ jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserDa jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java, 2002-06-05 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java, 2021-08-18 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoginService.java, 2009-03-24 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.LoginService.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintMapping.java, 2005-11-27 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintAware.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractLoginService.java, 2015-11-26 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.AbstractLoginService.java, 2015-11-26 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java, 2019-03-20 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/EmptyLoginService.java, 2011-08-11 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/JDBCLoginService.java, 2009-03-24 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.EmptyLoginService.java, 2011-08-11 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.JDBCLoginService.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/HashLoginService.java, 2009-03-24 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.HashLoginService.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java, 2009-03-24 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleInfo.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConfigurableSpnegoLoginService.java, 2018-09-14 +jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.ConfigurableSpnegoLoginService.java, 2018-09-14 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java, 2013-04-19 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java, 2018-09-14 jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java, 2009-03-24 diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/pom.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/pom.xml index 285a300e3358..0f156bb0abce 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/pom.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/pom.xml @@ -115,7 +115,7 @@ ${project.build.directory}/work - + Test Realm ${project.build.testOutputDirectory}/test-realm.properties diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml index 3db8c129e553..85875386a6be 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml @@ -49,7 +49,7 @@ detected. - + Test Realm /ee9-demo-realm.properties diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-spec/jetty-ee8-demo-spec-webapp/pom.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-spec/jetty-ee8-demo-spec-webapp/pom.xml index b15d131dd73e..b9ed8c653668 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-spec/jetty-ee8-demo-spec-webapp/pom.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-spec/jetty-ee8-demo-spec-webapp/pom.xml @@ -204,7 +204,7 @@ ${basedir}/src/main/webapp/WEB-INF/jetty-env.xml - + Test Realm ${project.build.directory}/realm.properties diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/pom.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/pom.xml index 01e1c3a0169d..5033a9f95dd3 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/pom.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/pom.xml @@ -115,7 +115,7 @@ ${project.build.directory}/work - + Test Realm src/test/resources/test-realm.properties diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml index 3db8c129e553..85875386a6be 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml @@ -49,7 +49,7 @@ detected. - + Test Realm /ee9-demo-realm.properties diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/pom.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/pom.xml index 7c092536c00e..1f24ccae49c4 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/pom.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/pom.xml @@ -166,7 +166,7 @@ ${basedir}/src/main/webapp/WEB-INF/jetty-env.xml - + Test Realm src/etc/realm.properties diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/templates/annotations-context-header.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/templates/annotations-context-header.xml index ae043febc604..b252ddea8198 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/templates/annotations-context-header.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/templates/annotations-context-header.xml @@ -21,7 +21,7 @@ - + Test Realm /etc/ee9-demo-realm.properties diff --git a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml index c5c21b3b3267..2ce036e69ec8 100644 --- a/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml +++ b/jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/config/etc/jetty-testrealm.xml @@ -17,7 +17,7 @@ - + Test Realm false diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/resources/login-service.xml b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/resources/login-service.xml index 96dfd33e6511..a8650d63dd44 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/resources/login-service.xml +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/resources/login-service.xml @@ -20,7 +20,7 @@ - + Test Realm false diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test-spec.xml b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test-spec.xml index 074f28cc900c..94655c3c4f64 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test-spec.xml +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test-spec.xml @@ -18,7 +18,7 @@ - + Test Realm diff --git a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test.xml b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test.xml index 68ec0605ae58..e3045c623387 100644 --- a/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test.xml +++ b/jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/resources/test.xml @@ -23,7 +23,7 @@ detected. - + Test Realm diff --git a/jetty-home/src/main/resources/modules/demo.d/jetty-ee8-demo-realm.xml b/jetty-home/src/main/resources/modules/demo.d/jetty-ee8-demo-realm.xml index 1e240e43220f..58f748d399e7 100644 --- a/jetty-home/src/main/resources/modules/demo.d/jetty-ee8-demo-realm.xml +++ b/jetty-home/src/main/resources/modules/demo.d/jetty-ee8-demo-realm.xml @@ -18,7 +18,7 @@ - + Test Realm false diff --git a/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.xml b/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.xml index 874bda5748a6..52845ed2c7d5 100644 --- a/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.xml +++ b/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.xml @@ -19,7 +19,7 @@ - + Test Realm false From 15455d192c7371a8946783859d97dd0528ec0d78 Mon Sep 17 00:00:00 2001 From: gregw Date: Sat, 8 Apr 2023 10:00:39 +0200 Subject: [PATCH 032/129] Added core library to modules --- .../jetty-ee8-openid/src/main/config/modules/ee8-openid.mod | 1 + .../jetty-ee8-security/src/main/config/modules/ee8-security.mod | 1 + .../jetty-ee9-openid/src/main/config/modules/ee9-openid.mod | 1 + .../jetty-ee9-security/src/main/config/modules/ee9-security.mod | 1 + 4 files changed, 4 insertions(+) diff --git a/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod b/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod index 8c0627fbba05..a9500102607c 100644 --- a/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod +++ b/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod @@ -8,6 +8,7 @@ ee8-security client [lib] +lib/jetty-openid-${jetty.version}.jar lib/jetty-ee8-openid-${jetty.version}.jar lib/jetty-util-ajax-${jetty.version}.jar diff --git a/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod b/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod index 51d52c74d83c..4336e61464b8 100644 --- a/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod +++ b/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod @@ -11,4 +11,5 @@ server ee8-servlet [lib] +lib/jetty-security-${jetty.version}.jar lib/jetty-ee8-security-${jetty.version}.jar diff --git a/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod b/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod index 20853180cf25..64bdc751d17a 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod +++ b/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod @@ -11,6 +11,7 @@ ee9-security client [lib] +lib/jetty-openid-${jetty.version}.jar lib/jetty-ee9-openid-${jetty.version}.jar lib/jetty-util-ajax-${jetty.version}.jar diff --git a/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod b/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod index a84ceff540f6..fa1440447b1b 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod +++ b/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod @@ -11,4 +11,5 @@ server ee9-servlet [lib] +lib/jetty-security-${jetty.version}.jar lib/jetty-ee9-security-${jetty.version}.jar From daa026397b7caa5f0ef9adaabbf8e87cc5ea0b3f Mon Sep 17 00:00:00 2001 From: gregw Date: Sat, 8 Apr 2023 13:28:56 +0200 Subject: [PATCH 033/129] Added core library to modules --- .../jetty-server/src/main/config/modules/openid.mod | 10 ++++++++++ .../jetty-server/src/main/config/modules/security.mod | 10 ++++++++++ .../src/main/config/modules/ee8-openid.mod | 2 +- .../src/main/config/modules/ee8-security.mod | 2 +- .../src/main/config/modules/ee9-openid.mod | 2 +- .../src/main/config/modules/ee9-security.mod | 2 +- 6 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 jetty-core/jetty-server/src/main/config/modules/openid.mod create mode 100644 jetty-core/jetty-server/src/main/config/modules/security.mod diff --git a/jetty-core/jetty-server/src/main/config/modules/openid.mod b/jetty-core/jetty-server/src/main/config/modules/openid.mod new file mode 100644 index 000000000000..9cf4906be548 --- /dev/null +++ b/jetty-core/jetty-server/src/main/config/modules/openid.mod @@ -0,0 +1,10 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Adds core openid handling to the classpath. + +[depend] +security + +[lib] +lib/jetty-openid-${jetty.version}.jar diff --git a/jetty-core/jetty-server/src/main/config/modules/security.mod b/jetty-core/jetty-server/src/main/config/modules/security.mod new file mode 100644 index 000000000000..c428e06765fb --- /dev/null +++ b/jetty-core/jetty-server/src/main/config/modules/security.mod @@ -0,0 +1,10 @@ +# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html + +[description] +Adds core security handling to the classpath. + +[depend] +server + +[lib] +lib/jetty-security-${jetty.version}.jar diff --git a/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod b/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod index a9500102607c..aaad1ff3cc1b 100644 --- a/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod +++ b/jetty-ee8/jetty-ee8-openid/src/main/config/modules/ee8-openid.mod @@ -5,10 +5,10 @@ Adds OpenId Connect authentication to the server. [depend] ee8-security +openid client [lib] -lib/jetty-openid-${jetty.version}.jar lib/jetty-ee8-openid-${jetty.version}.jar lib/jetty-util-ajax-${jetty.version}.jar diff --git a/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod b/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod index 4336e61464b8..c471df388ba6 100644 --- a/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod +++ b/jetty-ee8/jetty-ee8-security/src/main/config/modules/ee8-security.mod @@ -8,8 +8,8 @@ ee8 [depend] server +security ee8-servlet [lib] -lib/jetty-security-${jetty.version}.jar lib/jetty-ee8-security-${jetty.version}.jar diff --git a/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod b/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod index 64bdc751d17a..14d4af7df712 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod +++ b/jetty-ee9/jetty-ee9-openid/src/main/config/modules/ee9-openid.mod @@ -8,10 +8,10 @@ ee9 [depend] ee9-security +openid client [lib] -lib/jetty-openid-${jetty.version}.jar lib/jetty-ee9-openid-${jetty.version}.jar lib/jetty-util-ajax-${jetty.version}.jar diff --git a/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod b/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod index fa1440447b1b..ee58b7d32b0a 100644 --- a/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod +++ b/jetty-ee9/jetty-ee9-security/src/main/config/modules/ee9-security.mod @@ -8,8 +8,8 @@ ee9 [depend] server +security ee9-servlet [lib] -lib/jetty-security-${jetty.version}.jar lib/jetty-ee9-security-${jetty.version}.jar From 0ef2f50fb78a36476b48a47ae4cf2b14ddb89cf2 Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 9 Apr 2023 12:33:00 +0200 Subject: [PATCH 034/129] fixed mod files --- .../operations-guide/jaas/chapter.adoc | 42 +++++++++---------- inceptionDates.csv | 12 +++--- .../jetty/ee10/webapp/JaasConfiguration.java | 2 +- .../jetty/ee10/webapp/JndiConfiguration.java | 2 +- jetty-ee8/jetty-ee8-jaas/pom.xml | 2 +- .../jetty-ee9-demo-jaas-webapp/pom.xml | 2 +- .../config/modules/demo.d/ee9-demo-jaas.xml | 2 +- .../jetty/ee9/webapp/JaasConfiguration.java | 4 +- .../jetty/ee9/webapp/JndiConfiguration.java | 2 +- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc index d22f6f666519..812c21438203 100644 --- a/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc +++ b/documentation/jetty-documentation/src/main/asciidoc/operations-guide/jaas/chapter.adoc @@ -56,7 +56,7 @@ See more about the contents of this file in the xref:og-jaas-loginconf[Configuri [[og-jaas-webapp]] ===== Configure the webapp for JAAS -The `` in `web.xml` will be used to identify the `org.eclipse.jetty.jaas.JAASLoginService` declaration that integrates JAAS with Jetty. +The `` in `web.xml` will be used to identify the `org.eclipse.jetty.security.jaas.JAASLoginService` declaration that integrates JAAS with Jetty. For example, this `web.xml` contains a realm called `Test JAAS Realm`: @@ -71,14 +71,14 @@ For example, this `web.xml` contains a realm called `Test JAAS Realm`: ---- -<1> The name of the realm, which must be _identical_ to the name of an `org.eclipse.jetty.jaas.JAASLoginService` declaration. +<1> The name of the realm, which must be _identical_ to the name of an `org.eclipse.jetty.security.jaas.JAASLoginService` declaration. -We now need to declare an `org.eclipse.jetty.jaas.JAASLoginService` that references the realm name of `Test JAAS Realm`. +We now need to declare an `org.eclipse.jetty.security.jaas.JAASLoginService` that references the realm name of `Test JAAS Realm`. Here's an example of a suitable XML snippet: [source,xml,subs=verbatim] ---- - + Test JAAS Realm xyz @@ -86,9 +86,9 @@ Here's an example of a suitable XML snippet: <1> The name is the _same_ as that declared in the `` in `web.xml`. <2> The name that identifies a set of `javax.security.auth.spi.LoginModule` configurations that comprise the xref:og-jaas-loginconf[JAAS config file] identified in the `jetty.jaas.login.conf` property of the xref:og-jaas-module[`jaas` module]. -The `org.eclipse.jetty.jaas.JAASLoginService` can be declared in a couple of different places, pick whichever suits your purposes best: +The `org.eclipse.jetty.security.jaas.JAASLoginService` can be declared in a couple of different places, pick whichever suits your purposes best: -* If you have more than one webapp that you would like to use the same security infrastructure, then you can declare your `org.eclipse.jetty.jaas.JAASLoginService` as a bean that is added to the `org.eclipse.jetty.server.Server`. +* If you have more than one webapp that you would like to use the same security infrastructure, then you can declare your `org.eclipse.jetty.security.jaas.JAASLoginService` as a bean that is added to the `org.eclipse.jetty.server.Server`. The file in which you declare this needs to be on Jetty's execution path. The recommended procedure is to create a file in your `$jetty.base/etc` directory and then ensure it is on the classpath either by adding it to the Jetty xref:og-start-jar[start command line], or more conveniently to a xref:custom-modules[custom module]. + @@ -101,7 +101,7 @@ Here's an example of this type of XML file: - + Test JAAS Realm xyz @@ -110,7 +110,7 @@ Here's an example of this type of XML file: ---- -* Alternatively, if you want to use JAAS with a specific webapp only, you declare your `org.eclipse.jetty.jaas.JAASLoginService` in a context XLM file specific to that webapp: +* Alternatively, if you want to use JAAS with a specific webapp only, you declare your `org.eclipse.jetty.security.jaas.JAASLoginService` in a context XLM file specific to that webapp: + [source,xml] ---- @@ -120,7 +120,7 @@ Here's an example of this type of XML file: - + Test JAAS Realm xyz @@ -145,7 +145,7 @@ xyz { <1> com.other.OtherLoginModule optional; <3> }; ---- -<1> The name of the configuration _exactly_ as specified in your `org.eclipse.jetty.jaas.JAASLoginService` declaration. +<1> The name of the configuration _exactly_ as specified in your `org.eclipse.jetty.security.jaas.JAASLoginService` declaration. <2> The first `LoginModule` declaration, containing the classname of the `LoginModule` and its configuration properties. <3> A second `LoginModule` declaration. You can provide as many `LoginModule` alternatives as you like, with a minimum of one. @@ -154,10 +154,10 @@ Refer to the link:https://docs.oracle.com/javase/7/docs/api/javax/security/auth/ [[og-jaas-loginmodules]] ==== Provided LoginModules -* link:{javadoc-url}/org/eclipse/jetty/jaas/spi/JDBCLoginModule.html[`org.eclipse.jetty.jaas.spi.JDBCLoginModule`] -* link:{javadoc-url}/org/eclipse/jetty/jaas/spi/PropertyFileLoginModule.html[`org.eclipse.jetty.jaas.spi.PropertyFileLoginModule`] -* link:{javadoc-url}/org/eclipse/jetty/jaas/spi/DataSourceLoginModule.html[`org.eclipse.jetty.jaas.spi.DataSourceLoginModule`] -* link:{javadoc-url}/org/eclipse/jetty/jaas/spi/LdapLoginModule.html[`org.eclipse.jetty.jaas.ldap.LdapLoginModule`] +* link:{javadoc-url}/org.eclipse.jetty.security.jaas/spi/JDBCLoginModule.html[`org.eclipse.jetty.security.jaas.spi.JDBCLoginModule`] +* link:{javadoc-url}/org.eclipse.jetty.security.jaas/spi/PropertyFileLoginModule.html[`org.eclipse.jetty.security.jaas.spi.PropertyFileLoginModule`] +* link:{javadoc-url}/org.eclipse.jetty.security.jaas/spi/DataSourceLoginModule.html[`org.eclipse.jetty.security.jaas.spi.DataSourceLoginModule`] +* link:{javadoc-url}/org.eclipse.jetty.security.jaas/spi/LdapLoginModule.html[`org.eclipse.jetty.security.jaas.ldap.LdapLoginModule`] [NOTE] ==== @@ -167,7 +167,7 @@ The class link:{javadoc-url}/org/eclipse/jetty/util/security/Password.html[`org. ===== JDBCLoginModule -The `org.eclipse.jetty.jaas.spi.JDBCLoginModule` stores user passwords and roles in a database accessed via JDBC calls. +The `org.eclipse.jetty.security.jaas.spi.JDBCLoginModule` stores user passwords and roles in a database accessed via JDBC calls. You can configure the JDBC connection information, as well as the names of the table and columns storing the username and credential, and the names of the table and columns storing the roles. Here is an example xref:og-jaas-loginconf[login module configuration file] entry for it using an HSQLDB driver: @@ -175,7 +175,7 @@ Here is an example xref:og-jaas-loginconf[login module configuration file] entry [source,subs=verbatim] ---- jdbc { <1> - org.eclipse.jetty.jaas.spi.JDBCLoginModule required <2><3> + org.eclipse.jetty.security.jaas.spi.JDBCLoginModule required <2><3> dbUrl="jdbc:hsqldb:." <4> dbUserName="sa" <5> dbDriver="org.hsqldb.jdbcDriver" <6> @@ -216,7 +216,7 @@ Note that passwords can be stored in the database in plain text or encoded forma ===== DataSourceLoginModule -Similar to the `org.eclipse.jetty.jaas.spi.JDBCLoginModule`, but using a `javax.sql.DataSource` to connect to the database instead of a JDBC driver. +Similar to the `org.eclipse.jetty.security.jaas.spi.JDBCLoginModule`, but using a `javax.sql.DataSource` to connect to the database instead of a JDBC driver. The `javax.sql.DataSource` is obtained at runtime by performing a JNDI lookup on `java:comp/env/${dnJNDIName}`. A sample login module configuration for this `LoginModule`: @@ -224,7 +224,7 @@ A sample login module configuration for this `LoginModule`: [source,subs=verbatim] ---- ds { <1> - org.eclipse.jetty.jaas.spi.DataSourceLoginModule required <2><3> + org.eclipse.jetty.security.jaas.spi.DataSourceLoginModule required <2><3> dbJNDIName="ds" <4> userTable="myusers" <5> userField="myuser" <6> @@ -252,7 +252,7 @@ With this login module implementation, the authentication and role information i [source,subs=verbatim] ---- props { <1> - org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required <2><3> + org.eclipse.jetty.security.jaas.spi.PropertyFileLoginModule required <2><3> file="/somewhere/somefile.props"; <4> }; ---- @@ -281,7 +281,7 @@ The contents of the file are fully read in and cached in memory the first time a ===== LdapLoginModule -The `org.eclipse.jetty.jaas.spi.LdapLoginModule` uses LDAP to access authentication and authorization information stored in a directory. +The `org.eclipse.jetty.security.jaas.spi.LdapLoginModule` uses LDAP to access authentication and authorization information stored in a directory. The LDAP connection information and structure of the authentication/authorization data can be configured. Here's an example: @@ -289,7 +289,7 @@ Here's an example: [source,subs=verbatim] ---- example { <1> - org.eclipse.jetty.jaas.spi.LdapLoginModule required <2><3> + org.eclipse.jetty.security.jaas.spi.LdapLoginModule required <2><3> contextFactory="com.sun.jndi.ldap.LdapCtxFactory" <4> hostname="ldap.example.com" <5> port="389" <6> diff --git a/inceptionDates.csv b/inceptionDates.csv index b97de0f8f868..65dec64bdd92 100644 --- a/inceptionDates.csv +++ b/inceptionDates.csv @@ -291,10 +291,10 @@ jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/package-in jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java, 2012-08-29 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java, 2019-07-01 jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java, 2018-05-01 -jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLdapLoginServiceTest.java, 2018-08-30 -jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/JAASLoginServiceTest.java, 2018-04-17 +jetty-ee9/jetty-ee9-jaas/src/test/java/org.eclipse.jetty.security.jaas.JAASLdapLoginServiceTest.java, 2018-08-30 +jetty-ee9/jetty-ee9-jaas/src/test/java/org.eclipse.jetty.security.jaas.JAASLoginServiceTest.java, 2018-04-17 jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASLoginService.java, 2009-03-24 +jetty-ee9/jetty-ee9-jaas/src/main/java/org.eclipse.jetty.security.jaas.JAASLoginService.java, 2009-03-24 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java, 2003-04-30 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java, 2009-03-24 jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java, 2009-03-24 @@ -1409,9 +1409,9 @@ jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/ecl jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/AbstractTest.java, 2022-08-17 jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/WebSocketClientServlet.java, 2020-09-29 jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/EchoEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DatabaseLoginServiceTestServer.java, 2014-07-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/JdbcLoginServiceTest.java, 2010-05-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org/eclipse/jetty/ee9/loginservice/DataSourceLoginServiceTest.java, 2014-07-17 +jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.DatabaseLoginServiceTestServer.java, 2014-07-17 +jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.JdbcLoginServiceTest.java, 2010-05-29 +jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.DataSourceLoginServiceTest.java, 2014-07-17 jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/HazelcastClusteredInvalidationSessionTest.java, 2010-01-26 jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/client/ClientOrphanedSessionTest.java, 2017-05-29 jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/client/HazelcastSessionDataStoreTest.java, 2018-03-28 diff --git a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaasConfiguration.java b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaasConfiguration.java index c91fdfb45865..06e9912683de 100644 --- a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaasConfiguration.java +++ b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaasConfiguration.java @@ -20,7 +20,7 @@ /** *

    JAAS Configuration

    *

    This configuration configures the WebAppContext server/system classes to - * be able to see the org.eclipse.jetty.jaas package. + * be able to see the org.eclipse.jetty.security.jaas package. * This class is defined in the webapp package, as it implements the {@link Configuration} interface, * which is unknown to the jaas package. *

    diff --git a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JndiConfiguration.java b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JndiConfiguration.java index cf45a02207ad..c48a5a929f88 100644 --- a/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JndiConfiguration.java +++ b/jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JndiConfiguration.java @@ -20,7 +20,7 @@ /** *

    JNDI Configuration

    *

    This configuration configures the WebAppContext system/server classes to - * be able to see the org.eclipse.jetty.jaas package. + * be able to see the org.eclipse.jetty.security.jaas package. * This class is defined in the webapp package, as it implements the {@link Configuration} interface, * which is unknown to the jndi package. *

    diff --git a/jetty-ee8/jetty-ee8-jaas/pom.xml b/jetty-ee8/jetty-ee8-jaas/pom.xml index 98ae94676792..bb6719f7a7dd 100644 --- a/jetty-ee8/jetty-ee8-jaas/pom.xml +++ b/jetty-ee8/jetty-ee8-jaas/pom.xml @@ -16,7 +16,7 @@ 2.0.0.AM26 2.1.2 2.2.1 - org.eclipse.jetty.jaas.* + org.eclipse.jetty.security.jaas.* diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/pom.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/pom.xml index 9f7bec16b422..c4a44804aee2 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/pom.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/pom.xml @@ -28,7 +28,7 @@ /test-jaas - + Test JAAS Realm ee9-xyz diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/demo.d/ee9-demo-jaas.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/demo.d/ee9-demo-jaas.xml index 5f76f45841e3..5e8bc457132b 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/demo.d/ee9-demo-jaas.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/demo.d/ee9-demo-jaas.xml @@ -14,7 +14,7 @@ - + Demo JAAS Realm ee9-xyz diff --git a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java index 5fb968655447..5b9cd9b13548 100644 --- a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java +++ b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java @@ -20,7 +20,7 @@ /** *

    JAAS Configuration

    *

    This configuration configures the WebAppContext server/system classes to - * be able to see the org.eclipse.jetty.jaas package. + * be able to see the org.eclipse.jetty.security.jaas package. * This class is defined in the webapp package, as it implements the {@link Configuration} interface, * which is unknown to the jaas package. *

    @@ -41,7 +41,7 @@ public boolean isAvailable() { try { - return Loader.loadClass("org.eclipse.jetty.ee9.jaas.JAASLoginService") != null; + return Loader.loadClass("org.eclipse.jetty.security.jaas.JAASLoginService") != null; } catch (Throwable e) { diff --git a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JndiConfiguration.java b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JndiConfiguration.java index e7948e2d4f0b..84eb1174931a 100644 --- a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JndiConfiguration.java +++ b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JndiConfiguration.java @@ -20,7 +20,7 @@ /** *

    JNDI Configuration

    *

    This configuration configures the WebAppContext system/server classes to - * be able to see the org.eclipse.jetty.jaas package. + * be able to see the org.eclipse.jetty.security.jaas package. * This class is defined in the webapp package, as it implements the {@link Configuration} interface, * which is unknown to the jndi package. *

    From e306c5718d9ae4e7293b9edefba944ce4ed8d38c Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 9 Apr 2023 13:27:05 +0200 Subject: [PATCH 035/129] fixed ee8 files --- jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml | 2 +- .../src/main/config/modules/demo.d/ee8-demo-jaas.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml index 05e001c041ff..ea1ee596c79c 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml @@ -29,7 +29,7 @@ /test-jaas - + Test JAAS Realm ee8-xyz diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml index 9879b09db6bd..51fd9dad1e3f 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml @@ -14,7 +14,7 @@ - + Demo JAAS Realm ee8-xyz From e1034e6411a9867a5c90863b75e7fb623ede6362 Mon Sep 17 00:00:00 2001 From: gregw Date: Sun, 9 Apr 2023 21:02:41 +0200 Subject: [PATCH 036/129] fixed ee8 jaas --- jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml | 2 +- .../src/main/config/modules/demo.d/ee8-demo-jaas.xml | 2 +- .../java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml index ea1ee596c79c..c08d1651adb2 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/pom.xml @@ -29,7 +29,7 @@ /test-jaas - + Test JAAS Realm ee8-xyz diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml index 51fd9dad1e3f..9b2f6e9dbbd5 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml @@ -14,7 +14,7 @@ - + Demo JAAS Realm ee8-xyz diff --git a/jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java b/jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java index d22faf3aeec8..06cf91348082 100644 --- a/jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java +++ b/jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java @@ -202,6 +202,7 @@ public void testConfigurationOrder() expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.WebXmlConfiguration"); expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.MetaInfConfiguration"); expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.FragmentConfiguration"); + expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.JaasConfiguration"); expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.WebAppConfiguration"); expectedConfigurations.add("org.eclipse.jetty.ee9.webapp.JettyWebXmlConfiguration"); From c485ccb830828a6e0898d37bdbb15f28ad0a9e04 Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 10 Apr 2023 09:50:57 +0200 Subject: [PATCH 037/129] static --- .../eclipse/jetty/ee9/plus/security/DataSourceLoginService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java b/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java index 237978845fd5..a4719e5ff52f 100644 --- a/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java +++ b/jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java @@ -67,7 +67,7 @@ public class DataSourceLoginService extends AbstractLoginService /** * DBUser */ - public class DBUserPrincipal extends UserPrincipal + public static class DBUserPrincipal extends UserPrincipal { private int _key; From 7c985147f96e8fbbbd74a317911c667f3c509600 Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 10 Apr 2023 10:42:30 +0200 Subject: [PATCH 038/129] fixed jaas modules --- .../src/main/config/etc/jetty-jaas.xml | 0 .../src/main/config/modules/jaas.mod | 5 +- jetty-ee8/jetty-ee8-bom/pom.xml | 5 - jetty-ee8/jetty-ee8-home/pom.xml | 5 - jetty-ee8/jetty-ee8-jaas/pom.xml | 163 ------------------ jetty-ee8/jetty-ee8-maven-plugin/pom.xml | 5 - jetty-ee8/pom.xml | 6 - jetty-ee9/jetty-ee9-bom/pom.xml | 5 - .../jetty-ee9-demo-embedded/pom.xml | 4 - .../src/main/config/modules/ee9-demo-jaas.mod | 2 +- jetty-ee9/jetty-ee9-home/pom.xml | 5 - jetty-ee9/jetty-ee9-maven-plugin/pom.xml | 5 - jetty-ee9/jetty-ee9-runner/pom.xml | 4 - jetty-ee9/pom.xml | 5 - 14 files changed, 2 insertions(+), 217 deletions(-) rename {jetty-ee8/jetty-ee8-jaas => jetty-core/jetty-server}/src/main/config/etc/jetty-jaas.xml (100%) rename jetty-ee8/jetty-ee8-jaas/src/main/config/modules/ee8-jaas.mod => jetty-core/jetty-server/src/main/config/modules/jaas.mod (87%) delete mode 100644 jetty-ee8/jetty-ee8-jaas/pom.xml diff --git a/jetty-ee8/jetty-ee8-jaas/src/main/config/etc/jetty-jaas.xml b/jetty-core/jetty-server/src/main/config/etc/jetty-jaas.xml similarity index 100% rename from jetty-ee8/jetty-ee8-jaas/src/main/config/etc/jetty-jaas.xml rename to jetty-core/jetty-server/src/main/config/etc/jetty-jaas.xml diff --git a/jetty-ee8/jetty-ee8-jaas/src/main/config/modules/ee8-jaas.mod b/jetty-core/jetty-server/src/main/config/modules/jaas.mod similarity index 87% rename from jetty-ee8/jetty-ee8-jaas/src/main/config/modules/ee8-jaas.mod rename to jetty-core/jetty-server/src/main/config/modules/jaas.mod index b72e98e789a8..c12d1fa9aee0 100644 --- a/jetty-ee8/jetty-ee8-jaas/src/main/config/modules/ee8-jaas.mod +++ b/jetty-core/jetty-server/src/main/config/modules/jaas.mod @@ -7,10 +7,7 @@ Enables JAAS for deployed web applications. ee8 [depend] -server - -[lib] -lib/jetty-ee8-jaas-${jetty.version}.jar +security [xml] etc/jetty-jaas.xml diff --git a/jetty-ee8/jetty-ee8-bom/pom.xml b/jetty-ee8/jetty-ee8-bom/pom.xml index 16d03ad0bcc6..43d44018415d 100644 --- a/jetty-ee8/jetty-ee8-bom/pom.xml +++ b/jetty-ee8/jetty-ee8-bom/pom.xml @@ -55,11 +55,6 @@ jetty-ee8-glassfish-jstl 12.0.0-SNAPSHOT
    - - org.eclipse.jetty.ee8 - jetty-ee8-jaas - 12.0.0-SNAPSHOT - org.eclipse.jetty.ee8 jetty-ee8-jndi diff --git a/jetty-ee8/jetty-ee8-home/pom.xml b/jetty-ee8/jetty-ee8-home/pom.xml index 839e87bc21e8..d5d0dc9a5495 100644 --- a/jetty-ee8/jetty-ee8-home/pom.xml +++ b/jetty-ee8/jetty-ee8-home/pom.xml @@ -419,11 +419,6 @@ - - org.eclipse.jetty.ee8 - jetty-ee8-jaas - true - org.eclipse.jetty.ee8 jetty-ee8-annotations diff --git a/jetty-ee8/jetty-ee8-jaas/pom.xml b/jetty-ee8/jetty-ee8-jaas/pom.xml deleted file mode 100644 index bb6719f7a7dd..000000000000 --- a/jetty-ee8/jetty-ee8-jaas/pom.xml +++ /dev/null @@ -1,163 +0,0 @@ - - - org.eclipse.jetty.ee8 - jetty-ee8 - 12.0.0-SNAPSHOT - - - 4.0.0 - jetty-ee8-jaas - EE8 :: JAAS - Jetty JAAS support - - - jetty-ee9-jaas - ${project.groupId}.jaas - 2.0.0.AM26 - 2.1.2 - 2.2.1 - org.eclipse.jetty.security.jaas.* - - - - - - - org.apache.maven.plugins - maven-source-plugin - - - org.apache.maven.plugins - maven-surefire-plugin - - false - false - --add-opens java.base/sun.security.x509=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED - - - - - - - - org.eclipse.jetty.ee8 - jetty-ee8-security - - - org.slf4j - slf4j-api - - - org.eclipse.jetty - jetty-slf4j-impl - test - - - org.eclipse.jetty.toolchain - jetty-test-helper - test - - - org.apache.mina - mina-core - ${apache.mina.version} - test - - - org.apache.directory.server - apacheds-test-framework - ${apacheds.version} - test - - - junit - junit - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.server - apacheds-server-integ - ${apacheds.version} - test - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.server - apacheds-core-integ - ${apacheds.version} - test - - - - org.apache.directory.shared - shared-ldap-schema - - - org.apache.directory.api - api-ldap-schema-data - - - - - org.apache.directory.api - api-ldap-schema-data - ${apache.directory.api.version} - test - - - org.apache.directory.api - api-ldap-model - ${apache.directory.api.version} - - - org.apache.mina - mina-core - - - - - org.apache.directory.api - api-util - ${apache.directory.api.version} - - - org.apache.directory.api - api-asn1-api - ${apache.directory.api.version} - - - - org.junit.vintage - junit-vintage-engine - ${junit.version} - test - - - - - - diff --git a/jetty-ee8/jetty-ee8-maven-plugin/pom.xml b/jetty-ee8/jetty-ee8-maven-plugin/pom.xml index 442fb24662f2..9f800606410d 100644 --- a/jetty-ee8/jetty-ee8-maven-plugin/pom.xml +++ b/jetty-ee8/jetty-ee8-maven-plugin/pom.xml @@ -188,11 +188,6 @@ jetty-ee8-quickstart true - - org.eclipse.jetty.ee8 - jetty-ee8-jaas - true - org.eclipse.jetty.ee8 jetty-ee8-plus diff --git a/jetty-ee8/pom.xml b/jetty-ee8/pom.xml index 304831cf0d48..ad3c8b45b48c 100644 --- a/jetty-ee8/pom.xml +++ b/jetty-ee8/pom.xml @@ -34,7 +34,6 @@ jetty-ee8-servlet jetty-ee8-servlets jetty-ee8-webapp - jetty-ee8-jaas jetty-ee8-plus jetty-ee8-jndi jetty-ee8-maven-plugin @@ -277,11 +276,6 @@ jetty-ee8-quickstart ${project.version} - - org.eclipse.jetty.ee8 - jetty-ee8-jaas - ${project.version} - org.eclipse.jetty.ee8 jetty-ee8-nested diff --git a/jetty-ee9/jetty-ee9-bom/pom.xml b/jetty-ee9/jetty-ee9-bom/pom.xml index cbf71db4131f..249583a43966 100644 --- a/jetty-ee9/jetty-ee9-bom/pom.xml +++ b/jetty-ee9/jetty-ee9-bom/pom.xml @@ -60,11 +60,6 @@ jetty-ee9-glassfish-jstl 12.0.0-SNAPSHOT - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - 12.0.0-SNAPSHOT - org.eclipse.jetty.ee9 jetty-ee9-jaspi diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/pom.xml b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/pom.xml index 360bdf2e3b32..035f374e8693 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/pom.xml +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/pom.xml @@ -90,10 +90,6 @@ org.eclipse.jetty.ee9 jetty-ee9-proxy - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - org.eclipse.jetty.ee9 jetty-ee9-plus diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod index 9492605a4a6f..4e73edcf731f 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod @@ -13,7 +13,7 @@ webapp [depends] demo-jaas ee9-deploy -ee9-jaas +jaas jdbc ee9-jsp ee9-annotations diff --git a/jetty-ee9/jetty-ee9-home/pom.xml b/jetty-ee9/jetty-ee9-home/pom.xml index 32480a36bfb3..97e5ed89f72c 100644 --- a/jetty-ee9/jetty-ee9-home/pom.xml +++ b/jetty-ee9/jetty-ee9-home/pom.xml @@ -453,11 +453,6 @@ jetty-ee9-cdi true - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - true - org.eclipse.jetty.ee9 jetty-ee9-annotations diff --git a/jetty-ee9/jetty-ee9-maven-plugin/pom.xml b/jetty-ee9/jetty-ee9-maven-plugin/pom.xml index e24d8a636bcb..b6b78a7e31af 100644 --- a/jetty-ee9/jetty-ee9-maven-plugin/pom.xml +++ b/jetty-ee9/jetty-ee9-maven-plugin/pom.xml @@ -194,11 +194,6 @@ jetty-ee9-quickstart true - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - true - org.eclipse.jetty.ee9 jetty-ee9-plus diff --git a/jetty-ee9/jetty-ee9-runner/pom.xml b/jetty-ee9/jetty-ee9-runner/pom.xml index 01235bc591df..6045e8bd1e86 100644 --- a/jetty-ee9/jetty-ee9-runner/pom.xml +++ b/jetty-ee9/jetty-ee9-runner/pom.xml @@ -128,10 +128,6 @@ org.eclipse.jetty.ee9 jetty-ee9-annotations - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - org.eclipse.jetty.ee9.websocket jetty-ee9-websocket-jetty-server diff --git a/jetty-ee9/pom.xml b/jetty-ee9/pom.xml index b0646ccb91a4..704fef32a8f8 100644 --- a/jetty-ee9/pom.xml +++ b/jetty-ee9/pom.xml @@ -103,11 +103,6 @@ jetty-ee9-nested ${project.version} - - org.eclipse.jetty.ee9 - jetty-ee9-jaas - ${project.version} - org.eclipse.jetty.ee9 jetty-ee9-jaspi From c4cc152db34f500b6e9d9ab350c6fe6aa0574619 Mon Sep 17 00:00:00 2001 From: gregw Date: Mon, 10 Apr 2023 13:51:13 +0200 Subject: [PATCH 039/129] Still fixing ee8 modules --- inceptionDates.csv | 4864 ----------------- .../src/main/config/modules/ee8-demo-jaas.mod | 2 +- 2 files changed, 1 insertion(+), 4865 deletions(-) delete mode 100644 inceptionDates.csv diff --git a/inceptionDates.csv b/inceptionDates.csv deleted file mode 100644 index 65dec64bdd92..000000000000 --- a/inceptionDates.csv +++ /dev/null @@ -1,4864 +0,0 @@ -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java, 2012-11-02 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java, 2012-11-02 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java, 2011-12-14 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-effective-web-xml-it/webapp-war/src/main/java/WebAppServletListener.java, 2022-11-21 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-effective-web-xml-it/resources/src/main/java/Placeholder.java, 2022-11-21 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/main/java/jettyissue/NormalClass.java, 2012-11-02 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyAnnotation.java, 2012-11-02 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyServletContainerInitializer.java, 2012-07-10 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java, 2011-03-29 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java, 2018-05-05 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java, 2012-07-27 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java, 2018-05-05 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java, 2009-03-24 -jetty-ee8/jetty-ee8-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java, 2012-11-02 -jetty-ee9/jetty-ee9-ant/src/test/java/org/eclipse/jetty/ee9/ant/AntBuild.java, 2012-11-15 -jetty-ee9/jetty-ee9-ant/src/test/java/org/eclipse/jetty/ee9/ant/JettyAntTaskTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/FileMatchingConfiguration.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/Attributes.java, 2012-07-09 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/Connectors.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/SystemProperties.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/ContextHandlers.java, 2012-06-27 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/Connector.java, 2011-09-12 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/Attribute.java, 2011-09-12 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/types/LoginServices.java, 2009-03-24 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/AntMetaInfConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/JettyRunTask.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/AntWebXmlConfiguration.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/JettyStopTask.java, 2012-12-07 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/AntWebInfConfiguration.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/ServerProxyImpl.java, 2012-08-21 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/utils/TaskLog.java, 2012-07-06 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/utils/ServerProxy.java, 2012-05-08 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/utils/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-ant/src/main/java/org/eclipse/jetty/ee9/ant/AntWebAppContext.java, 2012-12-07 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/acme/webapp/ClassInJarA.java, 2009-12-10 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/acme/webapp/TestAnnotation.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebInfConfigurationTest.java, 2017-11-15 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/OrderingTest.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/MetaInfConfigurationTest.java, 2017-04-13 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/TestMetaData.java, 2020-03-09 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppContextTest.java, 2010-04-22 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/ClassMatcherTest.java, 2015-06-18 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppDefaultServletTest.java, 2021-05-13 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/TempDirTest.java, 2021-04-30 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppClassLoaderUrlStreamTest.java, 2017-04-04 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/ConfigurationsTest.java, 2016-05-02 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/HugeResourceTest.java, 2019-07-18 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/ForcedServletTest.java, 2021-05-16 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebDescriptorTest.java, 2022-08-01 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/StandardDescriptorProcessorTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/URLStreamHandlerUtil.java, 2017-04-04 -jetty-ee9/jetty-ee9-webapp/src/test/java/org/eclipse/jetty/ee9/webapp/WebAppClassLoaderTest.java, 2009-12-10 -jetty-ee9/jetty-ee9-webapp/src/main/java/module-info.java, 2022-05-03 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/OverrideDescriptor.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JndiConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JspConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppContext.java, 2003-06-30 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/MetaData.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/RelativeOrdering.java, 2015-06-25 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/DescriptorProcessor.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/AbstractConfiguration.java, 2010-07-26 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/Descriptor.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/MetaInfConfiguration.java, 2009-05-19 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/Origin.java, 2011-03-25 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JettyWebXmlConfiguration.java, 2005-11-27 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebXmlConfiguration.java, 2005-11-27 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/Ordering.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/FragmentDescriptor.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/Configuration.java, 2006-02-19 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/DecoratingListener.java, 2019-08-08 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppClassLoader.java, 2005-11-27 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/ClassMatcher.java, 2010-04-13 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/DefaultsDescriptor.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/ServletsConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/FragmentConfiguration.java, 2009-05-19 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/DiscoveredAnnotation.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebInfConfiguration.java, 2006-02-23 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/package-info.java, 2011-03-25 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/IterativeDescriptorProcessor.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JmxConfiguration.java, 2010-07-26 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebAppConfiguration.java, 2010-07-26 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/Configurations.java, 2016-05-02 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaspiConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/StandardDescriptorProcessor.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/AbsoluteOrdering.java, 2015-06-25 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/WebDescriptor.java, 2010-07-16 -jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/CachingWebAppClassLoader.java, 2015-10-26 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/CrossOriginFilterTest.java, 2011-10-19 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/DoSFilterJMXTest.java, 2013-02-27 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/HeaderFilterTest.java, 2017-06-13 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AbstractFileContentServlet.java, 2014-11-13 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/GzipContentLengthTest.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletStreamTypeLengthWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AsyncTimeoutCompleteWrite.java, 2015-03-26 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletLengthStreamTypeWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/QoSFilterTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/NoOpOutputStream.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletTypeStreamLengthWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/PassThruInputStream.java, 2016-01-04 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/EventSourceServletTest.java, 2013-01-31 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletLengthTypeStreamWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletStreamLengthTypeWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/DoSFilterTest.java, 2009-05-26 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/GzipHandlerNoReCompressTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AsyncManipFilter.java, 2016-01-04 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/GzipDefaultServletDeferredContentTypeTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/HttpOutputWriteFileContentServlet.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/CloseableDoSFilterTest.java, 2009-05-26 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AsyncScheduledDispatchWrite.java, 2016-01-04 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/ThreadStarvationTest.java, 2015-10-07 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletTypeLengthStreamWrite.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/TestMinGzipSizeServlet.java, 2011-12-08 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/BlockingServletStreamLengthTypeWriteWithFlush.java, 2011-08-11 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/IncludeExcludeBasedFilterTest.java, 2017-06-13 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AsyncTimeoutDispatchWrite.java, 2016-01-04 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/GzipDefaultServletTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AbstractDoSFilterTest.java, 2009-05-26 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/GzipHandlerTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/TestStaticMimeTypeServlet.java, 2011-08-12 -jetty-ee9/jetty-ee9-servlets/src/test/java/org/eclipse/jetty/ee9/servlets/AbstractGzipTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-servlets/src/main/java/module-info.java, 2013-07-12 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/EventSourceServlet.java, 2013-01-31 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/HeaderFilter.java, 2017-06-13 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/QoSFilter.java, 2009-03-24 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/CGI.java, 2009-03-24 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/CrossOriginFilter.java, 2009-07-29 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/CloseableDoSFilter.java, 2009-05-26 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/IncludeExcludeBasedFilter.java, 2017-06-13 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/PushCacheFilter.java, 2014-08-08 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/DoSFilter.java, 2009-05-26 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/PushSessionCacheFilter.java, 2014-12-05 -jetty-ee9/jetty-ee9-servlets/src/main/java/org/eclipse/jetty/ee9/servlets/EventSource.java, 2013-01-31 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-mock-resources/src/main/java/org/example/MockUserTransaction.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-mock-resources/src/main/java/org/example/MockDataSource.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-mock-resources/src/main/java/org/example/MockTransport.java, 2012-08-09 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-simple-webapp/src/main/java/org/eclipse/jetty/ee9/demo/simple/HelloWorldServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-proxy-webapp/src/test/java/org/eclipse/jetty/ee9/demos/ProxyWebAppTest.java, 2020-09-28 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jsp-webapp/src/main/java/org/example/TagListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jsp-webapp/src/main/java/org/example/Date2Tag.java, 2010-04-20 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jsp-webapp/src/main/java/org/example/Counter.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jsp-webapp/src/main/java/org/example/DateTag.java, 2010-04-20 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-async-rest/jetty-ee9-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee9/demos/AbstractRestServlet.java, 2011-07-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-async-rest/jetty-ee9-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee9/demos/AsyncRestServlet.java, 2011-07-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-async-rest/jetty-ee9-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee9/demos/SerialRestServlet.java, 2011-07-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-async-rest/jetty-ee9-demo-async-rest-server/src/test/java/org/eclipse/jetty/ee9/demos/AsyncRestServer.java, 2011-07-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-web-fragment/src/main/java/org/example/fragment/FragmentServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-container-initializer/src/main/java/org/example/initializer/FooInitializer.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-container-initializer/src/main/java/org/example/initializer/Foo.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/RoleAnnotationTest.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/Bar.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/SecuredServlet.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/AsyncListenerServlet.java, 2013-05-06 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/AnnotationTest.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/AnnotatedListener.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/ClassLoaderServlet.java, 2019-03-26 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/TestListener.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-spec/jetty-ee9-demo-spec-webapp/src/main/java/org/example/test/MultiPartTest.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/test/java/org/eclipse/jetty/ee9/DispatchServletTest.java, 2009-04-21 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/test/java/org/eclipse/jetty/ee9/ChatServletTest.java, 2013-06-13 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/Dump.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/SecureModeServlet.java, 2009-08-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/HelloWorld.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/TestFilter.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/SessionDump.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/CookieDump.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/AddListServletRequestListener.java, 2012-07-12 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/RewriteServlet.java, 2009-10-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/WebSocketChatServlet.java, 2009-11-23 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/TestServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/LoginServlet.java, 2012-10-12 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/DispatchServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/ChatServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/RegTest.java, 2012-09-29 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/JakartaWebSocketChat.java, 2020-09-25 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jetty-webapp/src/main/java/org/example/TestListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jndi-webapp/src/main/java/org/example/JNDITest.java, 2012-11-02 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneServletContextTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJspTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneServletContextJmxStatsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneServletContextWithSessionTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandlerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/WebSocketServerTest.java, 2019-09-09 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/FileServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/FastFileServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/MinimalServletsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/RewriteServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ManyHandlersTest.java, 2019-08-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ManyConnectorsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/LikeJettyXmlTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneContextTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/SimplestServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/FileServerXmlTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/AbstractEmbeddedTest.java, 2019-02-11 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/SplitFileServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ServerUtil.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneWebAppTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotationsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ExampleServerXmlTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ManyContextsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ServerWithJMXTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/JarServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneHandlerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/OneConnectorTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ExampleServerTest.java, 2019-08-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ManyServletContextsTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ProxyServerTest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/test/java/org/eclipse/jetty/ee9/demos/ServerWithJNDITest.java, 2019-09-04 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/WebSocketServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/LikeJettyXml.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SplitFileServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebApp.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithJNDI.java, 2013-06-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/HelloWorld.java, 2009-07-27 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneServletContext.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneContext.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneHandler.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/HelloHandler.java, 2009-07-27 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ManyHandlers.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/AsyncEchoServlet.java, 2015-02-05 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/HelloServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithJMX.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/DumpServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/FileServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ServerWithAnnotations.java, 2013-06-07 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/Http2Server.java, 2013-02-22 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ExampleServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ProxyServer.java, 2012-07-20 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/FastFileServer.java, 2013-05-16 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ManyServletContexts.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SimplestServer.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/HelloSessionServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/MinimalServlets.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneServletContextWithSession.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/FileServerXml.java, 2009-08-05 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/JarServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneWebAppWithJsp.java, 2009-03-24 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ManyContexts.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneConnector.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/SecuredHelloHandler.java, 2009-09-28 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ExampleUtil.java, 2019-09-10 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ExampleServerXml.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/JettyDemos.java, 2019-06-18 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/OneServletContextJmxStats.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/ManyConnectors.java, 2009-03-30 -jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-embedded/src/main/java/org/eclipse/jetty/ee9/demos/RewriteServer.java, 2009-03-30 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee9/osgi/boot/jsp/FragmentActivator.java, 2009-03-24 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee9/osgi/boot/jsp/TLDServerClasspathContributor.java, 2022-12-22 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-webapp-resources/src/main/java/com/acme/HelloWorld.java, 2005-11-27 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestOSGiUtil.java, 2013-02-21 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWithJsp.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiClasspathResources.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWithWebSocket.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiAnnotationParser.java, 2020-07-07 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/SimpleJakartaWebSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWithAnnotations.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootHTTP2JDK9.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/SomeCustomBean.java, 2009-03-24 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/SimpleEchoSocket.java, 2012-06-27 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/java/org/eclipse/jetty/ee9/osgi/test/TestJettyOSGiBootWithJakartaWebSocket.java, 2012-10-06 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi/src/test/resources/module-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-osgi/test-jetty-ee9-osgi-server/src/main/java/com/acme/osgi/Activator.java, 2009-11-09 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationParser.java, 2011-07-07 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/annotations/AnnotationConfiguration.java, 2011-07-07 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/PackageAdminServiceTracker.java, 2009-11-09 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/EE9Activator.java, 2022-12-22 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiMetaInfConfiguration.java, 2012-05-14 -jetty-ee9/jetty-ee9-osgi/jetty-ee9-osgi-boot/src/main/java/org/eclipse/jetty/ee9/osgi/boot/OSGiWebappClassLoader.java, 2009-12-11 -jetty-ee9/jetty-ee9-runner/src/test/java/org/eclipse/jetty/ee9/maven/jettyrunner/it/IntegrationTestJettyRunner.java, 2021-04-27 -jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-runner/src/main/java/org/eclipse/jetty/ee9/runner/Runner.java, 2012-08-29 -jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModuleTest.java, 2019-07-01 -jetty-ee9/jetty-ee9-jaas/src/test/java/org/eclipse/jetty/ee9/jaas/TestLoginModule.java, 2018-05-01 -jetty-ee9/jetty-ee9-jaas/src/test/java/org.eclipse.jetty.security.jaas.JAASLdapLoginServiceTest.java, 2018-08-30 -jetty-ee9/jetty-ee9-jaas/src/test/java/org.eclipse.jetty.security.jaas.JAASLoginServiceTest.java, 2018-04-17 -jetty-ee9/jetty-ee9-jaas/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org.eclipse.jetty.security.jaas.JAASLoginService.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASUserPrincipal.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractLoginModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/AbstractDatabaseLoginModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/PropertyFileLoginModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/DataSourceLoginModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/JDBCLoginModule.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/spi/LdapLoginModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/PropertyUserStoreManager.java, 2020-11-11 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASRole.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/JAASPrincipal.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ServletRequestCallback.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/AbstractCallbackHandler.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/ObjectCallback.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/DefaultCallbackHandler.java, 2003-04-30 -jetty-ee9/jetty-ee9-jaas/src/main/java/org/eclipse/jetty/ee9/jaas/callback/RequestParameterCallback.java, 2004-06-23 -jetty-ee9/jetty-ee9-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/FooServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/TestQuickStart.java, 2017-04-12 -jetty-ee9/jetty-ee9-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/FooContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/FooFilter.java, 2009-03-24 -jetty-ee9/jetty-ee9-quickstart/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-quickstart/src/main/java/org/eclipse/jetty/ee9/quickstart/QuickStartGeneratorConfiguration.java, 2014-07-09 -jetty-ee9/jetty-ee9-quickstart/src/main/java/org/eclipse/jetty/ee9/quickstart/QuickStartDescriptorProcessor.java, 2014-03-17 -jetty-ee9/jetty-ee9-quickstart/src/main/java/org/eclipse/jetty/ee9/quickstart/PreconfigureQuickStartWar.java, 2014-03-17 -jetty-ee9/jetty-ee9-quickstart/src/main/java/org/eclipse/jetty/ee9/quickstart/QuickStartConfiguration.java, 2014-03-17 -jetty-ee9/jetty-ee9-quickstart/src/main/java/org/eclipse/jetty/ee9/quickstart/ExtraXmlDescriptorProcessor.java, 2014-03-17 -jetty-ee9/jetty-ee9-jndi/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-jndi/src/main/java/org/eclipse/jetty/ee9/jndi/factories/MailSessionReference.java, 2009-03-24 -jetty-ee9/jetty-ee9-jndi/src/main/java/org/eclipse/jetty/ee9/jndi/factories/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ConstraintTest.java, 2007-04-19 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/PropertyUserStoreTest.java, 2010-10-12 -jetty-ee9/jetty-ee9-security/src/test/java/org.eclipse.jetty.security.TestLoginService.java, 2015-11-26 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DataConstraintsTest.java, 2012-01-17 -jetty-ee9/jetty-ee9-security/src/test/java/org.eclipse.jetty.security.HashLoginServiceTest.java, 2019-05-07 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/DefaultIdentityServiceTest.java, 2021-08-25 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UnauthenticatedTest.java, 2021-08-20 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/UserStoreTest.java, 2017-04-20 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/SpecExampleConstraintTest.java, 2012-09-28 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/ClientCertAuthenticatorTest.java, 2021-02-10 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/AliasedConstraintTest.java, 2014-06-26 -jetty-ee9/jetty-ee9-security/src/test/java/org/eclipse/jetty/ee9/security/authentication/SpnegoAuthenticatorTest.java, 2017-08-01 -jetty-ee9/jetty-ee9-security/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultUserIdentity.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintSecurityHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserIdentity.java, 2010-12-17 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultIdentityService.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserPrincipal.java, 2020-11-17 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RolePrincipal.java, 2011-03-29 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserStore.java, 2017-04-20 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SecurityHandler.java, 2000-08-20 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/SpnegoUserPrincipal.java, 2010-12-17 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ServerAuthException.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/DefaultAuthenticatorFactory.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserDataConstraint.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/Authenticator.java, 2002-06-05 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/UserAuthentication.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/WrappedAuthConfiguration.java, 2021-08-18 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.LoginService.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintMapping.java, 2005-11-27 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/ConstraintAware.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.AbstractLoginService.java, 2015-11-26 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/LoggedOutAuthentication.java, 2019-03-20 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.EmptyLoginService.java, 2011-08-11 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.JDBCLoginService.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/PropertyUserStore.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.HashLoginService.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/IdentityService.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleRunAsToken.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RoleInfo.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org.eclipse.jetty.security.ConfigurableSpnegoLoginService.java, 2018-09-14 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/AbstractUserAuthentication.java, 2013-04-19 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ConfigurableSpnegoAuthenticator.java, 2018-09-14 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/BasicAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/AuthorizationService.java, 2018-09-14 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/ClientCertAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DigestAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallback.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SessionAuthentication.java, 2009-08-03 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/DeferredAuthentication.java, 2009-04-17 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/SslClientCertAuthenticator.java, 2021-02-10 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/FormAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginCallbackImpl.java, 2009-03-24 -jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/RunAsToken.java, 2009-03-24 -jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9/jstl/JspConfig.java, 2015-06-29 -jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9/jstl/JstlTest.java, 2015-06-29 -jetty-ee9/jetty-ee9-glassfish-jstl/src/test/java/org/eclipse/jetty/ee9/jstl/JspIncludeTest.java, 2015-06-29 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/acme/ClassOne.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestAnnotationParser.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestSecurityAnnotationConversions.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ClassA.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestRunAsAnnotation.java, 2020-04-06 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ServletC.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ServletE.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ListenerC.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/Sample.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestAnnotationConfiguration.java, 2010-07-16 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ClassB.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/InterfaceD.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/Multi.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/resources/TestResourceAnnotations.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/resources/ResourceA.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/resources/ResourceB.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestAnnotationDecorator.java, 2020-03-09 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestAnnotationIntrospector.java, 2020-03-09 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/ServletD.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestDiscoveredServletContainerInitializerHolder.java, 2021-02-19 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/TestServletAnnotations.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/test/java/org/eclipse/jetty/ee9/annotations/FilterC.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/main/java/module-info.java, 2012-07-10 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/AnnotationDecorator.java, 2010-07-16 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/ContainerInitializerAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebFilterAnnotation.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebServletAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/AbstractDiscoverableAnnotationHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebListenerAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/MultiPartConfigAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/ClassInheritanceHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebServletAnnotation.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/ResourceAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebListenerAnnotation.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/ServletSecurityAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/ResourcesAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/WebFilterAnnotationHandler.java, 2011-07-07 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/AnnotationParser.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/DeclareRolesAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/PostConstructAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/AnnotationIntrospector.java, 2010-07-16 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/AnnotationConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/RunAsAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-annotations/src/main/java/org/eclipse/jetty/ee9/annotations/PreDestroyAnnotationHandler.java, 2009-07-22 -jetty-ee9/jetty-ee9-plus/src/test/java/org/eclipse/jetty/ee9/plus/jndi/NamingEntryUtilTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/test/java/org/eclipse/jetty/ee9/plus/jndi/TestNamingEntryUtil.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/test/java/org/eclipse/jetty/ee9/plus/jndi/TestNamingEntries.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/test/java/org/eclipse/jetty/ee9/plus/webapp/PlusDescriptorProcessorTest.java, 2011-07-07 -jetty-ee9/jetty-ee9-plus/src/test/java/org/eclipse/jetty/ee9/plus/annotation/LifeCycleCallbackCollectionTest.java, 2019-07-01 -jetty-ee9/jetty-ee9-plus/src/main/java/module-info.java, 2018-11-22 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/EnvEntry.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/Link.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/NamingEntryUtil.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/NamingEntry.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/NamingDump.java, 2019-06-18 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/Resource.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/jndi/Transaction.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/DataSourceLoginService.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/security/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/webapp/EnvConfiguration.java, 2006-03-14 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/webapp/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/webapp/PlusConfiguration.java, 2009-03-24 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/webapp/PlusDecorator.java, 2010-07-16 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/webapp/PlusDescriptorProcessor.java, 2010-07-16 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/PostConstructCallback.java, 2006-12-29 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/RunAs.java, 2006-11-12 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/InjectionCollection.java, 2006-12-29 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/RunAsCollection.java, 2007-02-14 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/Injection.java, 2006-12-29 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/PreDestroyCallback.java, 2006-12-29 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/LifeCycleCallback.java, 2006-12-29 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-plus/src/main/java/org/eclipse/jetty/ee9/plus/annotation/LifeCycleCallbackCollection.java, 2006-12-29 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestJettyStopMojo.java, 2022-02-21 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestSelectiveJarResource.java, 2019-10-02 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/MockShutdownMonitor.java, 2022-02-21 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestJettyEmbedder.java, 2019-09-25 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestWebAppPropertyConverter.java, 2019-09-30 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/it/IntegrationTestGetContent.java, 2018-06-05 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/MockShutdownMonitorRunnable.java, 2022-02-21 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestQuickStartGenerator.java, 2019-09-30 -jetty-ee9/jetty-ee9-maven-plugin/src/test/java/org/eclipse/jetty/ee9/maven/plugin/TestForkedChild.java, 2019-10-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java, 2012-11-02 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java, 2012-11-02 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-effective-web-xml-it/webapp-war/src/main/java/WebAppServletListener.java, 2022-11-21 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-effective-web-xml-it/resources/src/main/java/Placeholder.java, 2022-11-21 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/main/java/jettyissue/NormalClass.java, 2012-11-02 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyAnnotation.java, 2012-11-02 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyServletContainerInitializer.java, 2012-07-10 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java, 2011-03-29 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java, 2018-05-05 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java, 2012-07-27 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java, 2018-05-05 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java, 2012-11-02 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/WarPluginInfo.java, 2012-11-19 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/QuickStartGenerator.java, 2019-09-17 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ScanTargetPattern.java, 2012-08-28 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractForker.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerSupport.java, 2012-08-28 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/Overlay.java, 2011-09-12 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/WebAppPropertyConverter.java, 2017-08-10 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyHomeForker.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyStartWarMojo.java, 2019-09-17 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/SelectiveJarResource.java, 2012-11-19 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/PluginLog.java, 2012-07-09 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/OverlayConfig.java, 2012-11-19 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyRunWarMojo.java, 2019-07-11 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerConnectorListener.java, 2017-10-05 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyRunMojo.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEffectiveWebXml.java, 2011-03-29 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ServerListener.java, 2017-08-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ScanPattern.java, 2012-07-09 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyStopMojo.java, 2012-08-28 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyEmbedder.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyForker.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyStartMojo.java, 2019-07-11 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/utils/MavenProjectHelper.java, 2019-05-30 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/OverlayManager.java, 2019-10-02 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/MavenQuickStartConfiguration.java, 2014-07-09 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/MavenWebInfConfiguration.java, 2012-08-28 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractUnassembledWebAppMojo.java, 2019-11-06 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/AbstractWebAppMojo.java, 2019-05-15 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/MavenServerConnector.java, 2012-07-09 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/MavenMetaInfConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/MavenWebAppContext.java, 2012-08-28 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/ConsoleReader.java, 2019-07-13 -jetty-ee9/jetty-ee9-maven-plugin/src/main/java/org/eclipse/jetty/ee9/maven/plugin/JettyForkedChild.java, 2019-05-15 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/DefaultServletRangesTest.java, 2012-08-27 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/GzipHandlerIsHandledTest.java, 2022-07-13 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/DispatcherForwardTest.java, 2014-05-09 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletWrapperTest.java, 2019-10-01 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ListenerHolderTest.java, 2020-03-09 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncServletLongPollTest.java, 2013-06-05 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncListenerTest.java, 2015-08-10 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextHandlerTest.java, 2011-05-11 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletHolderTest.java, 2015-12-14 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncContextDispatchWithQueryStrings.java, 2011-03-16 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletLifeCycleTest.java, 2019-09-13 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/InitServletTest.java, 2019-11-25 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/FormTest.java, 2019-07-23 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/EncodedURITest.java, 2016-09-08 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/SSLAsyncIOServletTest.java, 2014-04-16 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletHandlerTest.java, 2013-01-14 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/PostServletTest.java, 2016-04-26 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ErrorPageTest.java, 2013-03-11 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletUpgradeTest.java, 2021-01-28 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncServletTest.java, 2013-03-08 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/DispatcherTest.java, 2008-07-10 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/GzipHandlerCommitTest.java, 2020-05-01 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ComponentWrapTest.java, 2020-09-15 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContextResourcesTest.java, 2016-06-22 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/RegexServletTest.java, 2022-03-22 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ComplianceViolations2616Test.java, 2016-03-22 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletContainerInitializerHolderTest.java, 2021-02-19 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/IncludedServletTest.java, 2016-04-26 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/StaticFromJarServerTest.java, 2022-08-09 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CharacterEncodingTest.java, 2022-12-13 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CustomRequestLogTest.java, 2018-11-22 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ResponseHeadersTest.java, 2012-06-25 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/CacheControlHeaderTest.java, 2021-02-18 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/RequestURITest.java, 2014-03-19 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/RequestHeadersTest.java, 2013-03-19 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncContextListenersTest.java, 2013-08-21 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/InvokerTest.java, 2008-08-21 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/MultiPartServletTest.java, 2019-05-29 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/DefaultServletTest.java, 2009-04-21 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/GzipHandlerBreakEvenSizeTest.java, 2019-10-14 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncServletIOTest.java, 2013-05-24 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/FilterHolderTest.java, 2016-11-02 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/AsyncContextTest.java, 2012-02-14 -jetty-ee9/jetty-ee9-servlet/src/test/java/org/eclipse/jetty/ee9/servlet/ServletRequestLogTest.java, 2014-10-10 -jetty-ee9/jetty-ee9-servlet/src/main/java/module-info.java, 2012-09-13 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/FilterHolder.java, 2001-11-07 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/jmx/HolderMBean.java, 2003-02-15 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/jmx/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/jmx/FilterMappingMBean.java, 2009-06-11 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/jmx/ServletMappingMBean.java, 2009-06-11 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletMapping.java, 2005-11-27 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/Invoker.java, 2002-07-17 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/Source.java, 2016-07-08 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/FilterMapping.java, 2005-11-27 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/NoJspServlet.java, 2005-11-27 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ListenerHolder.java, 2013-12-12 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/listener/ELContextCleaner.java, 2011-07-29 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/listener/IntrospectorCleaner.java, 2009-03-24 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/listener/ContainerInitializer.java, 2019-05-28 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/listener/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletContainerInitializerHolder.java, 2021-02-19 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ErrorPageErrorHandler.java, 2006-09-07 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletTester.java, 2012-07-13 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/DecoratingListener.java, 2019-08-08 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/DefaultServlet.java, 2005-11-27 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/Holder.java, 2001-11-07 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java, 2006-12-29 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/BaseHolder.java, 2013-12-12 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/JspPropertyGroupServlet.java, 2013-02-25 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletContextHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHolder.java, 2000-06-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketPartialListener.java, 2015-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketBehavior.java, 2012-06-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketAdapter.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketContainer.java, 2019-02-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/OnWebSocketMessage.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/OnWebSocketConnect.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/WebSocket.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/OnWebSocketFrame.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/OnWebSocketError.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/annotations/OnWebSocketClose.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/ExtensionConfig.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WriteCallback.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/Frame.java, 2012-11-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketSessionListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/UpgradeRequest.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketFrameListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/RemoteEndpoint.java, 2012-11-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/CloseStatus.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketPingPongListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketListener.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/UpgradeResponse.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/BatchMode.java, 2012-07-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketPolicy.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/util/WSURI.java, 2013-06-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/util/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/util/WebSocketConstants.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/WebSocketConnectionListener.java, 2012-06-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/SuspendToken.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/StatusCode.java, 2012-06-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/InvalidWebSocketException.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/MessageTooLargeException.java, 2012-07-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/CloseException.java, 2012-06-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/BadPayloadException.java, 2012-07-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/WebSocketException.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/ProtocolException.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/UpgradeException.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/WebSocketTimeoutException.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/exceptions/PolicyViolationException.java, 2012-06-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee9/websocket/api/Session.java, 2012-11-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/test/java/examples/SecureWebSocketContainerExample.java, 2019-08-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/test/java/examples/SecureClientContainerExample.java, 2019-08-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/test/java/examples/EchoEndpoint.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/test/java/examples/OriginServerConfigurator.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/JakartaWebSocketClientContainerProvider.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/AnnotatedClientEndpointConfig.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/JakartaClientUpgradeRequest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/EmptyConfigurator.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/BasicClientEndpointConfig.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/JsrUpgradeListener.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/JakartaWebSocketClientContainer.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/internal/JakartaWebSocketClientFrameHandlerFactory.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/client/JakartaWebSocketShutdownContainer.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-servlet/src/main/java/module-info.java, 2013-07-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-servlet/src/main/java/org/eclipse/jetty/ee9/websocket/servlet/WebSocketUpgradeFilter.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketFrameHandlerTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/MessageInputStreamTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/EventQueue.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/MessageOutputStreamTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/EndPoints.java, 2020-03-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/LocalEndpointMetadataTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/OutgoingMessageCapture.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/DummyContainer.java, 2019-02-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/endpoints/adapters/ListenerEchoSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/endpoints/adapters/AdapterEchoSocket.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/invoke/NameParamIdentifier.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee9/websocket/common/invoke/InvokerUtilsTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketFrameHandlerFactory.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketRemoteEndpoint.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketFrameHandler.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketFrame.java, 2015-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/ExtensionConfigParser.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyWebSocketFrameHandlerMetadata.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/package-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/WebSocketSession.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/JettyExtensionConfig.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee9/websocket/common/SessionTracker.java, 2017-04-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/server/browser/JsrBrowserConfigurator.java, 2013-08-01 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/server/browser/JsrBrowserDebugTool.java, 2013-09-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/server/browser/JsrBrowserSocket.java, 2012-10-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/module-info.java, 2018-11-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/AnnotatedServerEndpointConfig.java, 2013-07-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/PathParamIdentifier.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JakartaServerUpgradeRequest.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JakartaWebSocketServerContainer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/PathParamServerEndpointConfig.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JsrHandshakeRequest.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/BasicServerEndpointConfig.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JsrHandshakeResponse.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JakartaWebSocketServerFrameHandlerFactory.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/internal/JakartaWebSocketCreator.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/config/JakartaWebSocketConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/config/ContainerDefaultConfigurator.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/server/config/JakartaWebSocketServletContainerInitializer.java, 2013-09-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageBinaryTest.java, 2020-02-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageBinaryStreamTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerBadSignaturesTest.java, 2020-02-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/AbstractJakartaWebSocketFrameHandlerTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ByteBufferWholeHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/LongMessageHandler.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/StringWholeHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ExtendedMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/BaseMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/StringPartialHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ReaderWholeHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ByteArrayWholeHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ComboMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ByteArrayPartialHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/ByteBufferPartialHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/handlers/InputStreamWholeHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnCloseTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnOpenTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/AbstractSessionTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageTextTest.java, 2020-02-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedTextStreamMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/InputStreamMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedBinaryMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedBinaryStreamMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/MessageWriterTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/ReaderMessageSinkTest.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/AbstractMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedTextMessageSinkTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnErrorTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/FruitDecoder.java, 2009-12-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/FruitTextEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/Fruit.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/BadDualDecoder.java, 2013-02-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/ExtDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/BadDualEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/coders/tests/FruitBinaryEncoder.java, 2012-07-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/sockets/TrackingSocket.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/Defaults.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/util/NameParamIdentifier.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/util/InvokerUtilsStaticParamsTest.java, 2020-02-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/util/ReflectUtilsTest.java, 2013-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/util/InvokerUtilsTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/DummyContainer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/DummyFrameHandlerFactory.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/endpoints/AbstractStringEndpoint.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/endpoints/DummyEndpoint.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/common/endpoints/EchoStringEndpoint.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/module-info.java, 2012-09-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/PathParamProvider.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketPongMessage.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketRemoteEndpoint.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketContainer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketAsyncRemote.java, 2013-02-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerFactory.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketBasicRemote.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/RegisteredMessageHandler.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/UpgradeRequest.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/EndpointConfigWrapper.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketSession.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/LongDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/ByteDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/DoubleDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/ByteArrayDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/ReaderDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/ByteBufferDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/AvailableDecoders.java, 2016-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/IntegerDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/ShortDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/StringDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/CharacterDecoder.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/RegisteredDecoder.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/InputStreamDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/FloatDecoder.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/BooleanDecoder.java, 2012-08-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/decoders/AbstractDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/ServerEndpointConfigWrapper.java, 2013-04-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandlerMetadata.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketSessionListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/AbstractDecodedMessageSink.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedBinaryMessageSink.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedTextStreamMessageSink.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedBinaryStreamMessageSink.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/messages/DecodedTextMessageSink.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/ClientEndpointConfigWrapper.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/UpgradeRequestAdapter.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketExtension.java, 2013-02-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketMessageMetadata.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/InitException.java, 2012-06-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/PutListenerMap.java, 2019-12-17 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/ConfiguredEndpoint.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/SendHandlerCallback.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketFrameHandler.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/SessionTracker.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/CharacterEncoder.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/ByteEncoder.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/ShortEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/RegisteredEncoder.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/FloatEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/ByteBufferEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/StringEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/AvailableEncoders.java, 2016-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/BooleanEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/EncodeFailedFuture.java, 2013-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/DoubleEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/ByteArrayEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/LongEncoder.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/IntegerEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/encoders/AbstractEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/common/JakartaWebSocketExtensionConfig.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee9/websocket/client/WebSocketClientBadUriTest.java, 2012-08-17 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee9/websocket/client/HttpClientInitTest.java, 2017-05-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee9/websocket/client/WebSocketClientInitTest.java, 2016-11-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/examples/ClientDemo.java, 2012-07-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java, 2013-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/JettyUpgradeListener.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/WebSocketClient.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/impl/JettyClientUpgradeRequest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/config/JettyWebSocketClientConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee9/websocket/client/ClientUpgradeRequest.java, 2012-06-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ParamsEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketFilterTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketStatsTest.java, 2019-02-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ConnectMessageEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/MaxOutgoingFramesTest.java, 2020-10-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketOverHTTP2Test.java, 2019-08-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/LargeDeflateTest.java, 2022-01-19 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/SingleOnMessageTest.java, 2020-12-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketServletTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/CloseInOnOpenTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/proxy/WebSocketProxyTest.java, 2020-11-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/proxy/WebSocketProxy.java, 2020-11-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/AnnoMaxMessageEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketRestartTest.java, 2021-01-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/SimpleStatusServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketExtensionConfigTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/EchoSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/SlowServerTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/PartialListenerTest.java, 2019-07-16 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/ServerCloseTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/CloseInOnCloseEndpointNewThread.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/FastFailEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/FastCloseEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/SlowServerEndpoint.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/FrameAnnotationTest.java, 2019-07-17 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/ServerCloseCreator.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/AbstractCloseEndpoint.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/ContainerEndpoint.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/FrameListenerTest.java, 2019-07-17 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/ServerConfigTest.java, 2019-05-16 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/server/CloseInOnCloseEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/SuspendResumeTest.java, 2019-03-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyOnCloseTest.java, 2020-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/GracefulCloseTest.java, 2020-06-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientCloseTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/InvalidUpgradeServlet.java, 2019-12-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientConnectTest.java, 2019-05-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/SlowClientTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/BadNetworkTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientSessionsTest.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/WebSocketClientTest.java, 2019-05-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ConnectFutureTest.java, 2020-07-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientWriteThread.java, 2012-09-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientConfigTest.java, 2019-05-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientOpenSessionTracker.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/client/ClientTimeoutTest.java, 2020-07-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketWebApp.java, 2020-11-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ConnectionHeaderTest.java, 2021-08-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/UpgradeRequestResponseTest.java, 2021-01-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/EchoCreator.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketNegotiationTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyWebSocketServletAttributeTest.java, 2019-01-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/GetAuthHeaderEndpoint.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyAuthedCreator.java, 2019-01-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyBinaryEchoSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyEchoSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyAuthedServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyAdvancedEchoServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyAdvancedEchoCreator.java, 2019-01-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/examples/MyEchoServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/CloseTrackingEndpoint.java, 2019-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ErrorCloseTest.java, 2020-02-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ConcurrentConnectTest.java, 2019-04-16 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/util/WSURITest.java, 2013-06-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/util/FutureWriteCallback.java, 2019-06-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/listeners/WebSocketListenerTest.java, 2020-04-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/listeners/AbstractAnnotatedListener.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/listeners/BinaryListeners.java, 2020-04-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/listeners/TextListeners.java, 2020-04-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/listeners/AbstractListener.java, 2012-08-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/PermessageDeflateBufferTest.java, 2021-03-17 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn/JettyAutobahnClient.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn/JettyAutobahnServer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/autobahn/JettyAutobahnSocket.java, 2012-06-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/JettyClientClassLoaderTest.java, 2021-02-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketServletExamplesTest.java, 2019-01-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/EventSocket.java, 2019-03-11 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/ProgrammaticWebSocketUpgradeTest.java, 2021-01-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/AnnotatedPartialListenerTest.java, 2021-06-11 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/extensions/ExtensionConfigTest.java, 2012-11-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebSocketStopTest.java, 2019-07-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee9/websocket/tests/WebAppTester.java, 2021-05-19 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/test/java/org/eclipse/jetty/ee9/websocket/server/browser/BrowserDebugTool.java, 2019-01-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/test/java/org/eclipse/jetty/ee9/websocket/server/browser/BrowserSocket.java, 2012-10-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/module-info.java, 2012-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyServerUpgradeRequest.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyWebSocketServlet.java, 2019-03-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/internal/JettyServerFrameHandlerFactory.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/internal/DelegatedServerUpgradeResponse.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/internal/DelegatedServerUpgradeRequest.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyServerUpgradeResponse.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyWebSocketCreator.java, 2019-03-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyWebSocketServletFactory.java, 2019-03-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/JettyWebSocketServerContainer.java, 2019-02-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/config/JettyWebSocketServletContainerInitializer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee9/websocket/server/config/JettyWebSocketConfiguration.java, 2016-05-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JakartaClientShutdownWithServerWebAppTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/CloseInOnOpenTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/JsrEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PongContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/LargeAnnotatedTest.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/ReaderEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/EndpointViaConfigTest.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/ServerDecoderTest.java, 2020-01-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java, 2020-03-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/MemoryUsageTest.java, 2014-02-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/DeploymentTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PingPongTest.java, 2017-05-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/BasicEchoSocketContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/BasicEchoEndpointContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PongSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/BasicEchoEndpointConfigContextListener.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PartialEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/StreamTest.java, 2014-03-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/DeploymentExceptionTest.java, 2016-08-18 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/JsrBatchModeTest.java, 2014-02-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/ContainerProviderServerTest.java, 2020-01-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/IdleTimeoutTest.java, 2017-05-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/TextStreamTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/LargeContainerTest.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/SessionTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/IdleTimeoutContextListener.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PrimitivesBinaryEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/AbstractJakartaWebSocketServerFrameHandlerTest.java, 2017-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/LargeEchoContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/GetHttpSessionSocket.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/GetHttpSessionConfigurator.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/StreamingEchoSocket.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/MyAuthedSocket.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/examples/MyAuthedConfigurator.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/PrimitivesTextEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/AnnotatedServerEndpointTest.java, 2013-12-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/StatelessTextMessageStringSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicEchoSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/binary/ByteBufferSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicErrorThrowableSessionSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicErrorThrowableSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidOpenIntSocket.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicErrorSessionSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicCloseReasonSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicCloseReasonSessionSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicOpenSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/TrackingSocket.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidErrorErrorSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/pong/PongMessageEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicCloseSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicOpenSessionSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicErrorSessionThrowableSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidCloseIntSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/BasicEchoSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/BasicEchoEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoReturnTextSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/LargeEchoDefaultSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoBasicTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/LargeEchoConfiguredSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoAsyncTextSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoReturnEndpoint.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidOpenCloseReasonSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicCloseSessionReasonSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicPongMessageSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/streaming/ReaderSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/streaming/ReaderParamSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/streaming/InputStreamSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/streaming/StringReturnReaderParamSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/partial/PartialTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/partial/PartialTextSessionSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/partial/PartialTrackingSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicTextMessageStringSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicOpenCloseSessionSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidOpenSessionIntSocket.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/BooleanTextParamSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/BooleanTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/IntTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/LongObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/IntegerObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/FloatTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/ByteTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/ShortObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/IntParamTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/BooleanObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/FloatObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/DoubleTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/LongTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/DoubleObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/CharacterObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/ShortTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/ByteObjectTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/primitives/CharTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/DateTextSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/ConfiguredEchoSocket.java, 2013-12-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/ByteBufferSocket.java, 2013-07-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicOpenCloseSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/BasicErrorSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/sockets/InvalidErrorIntSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/BinaryStreamTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/configs/EchoSocketConfigurator.java, 2013-08-01 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/AltFilterTest.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/WebSocketServerContainerExecutorTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/OnMessageReturnTest.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/BasicEchoSocketConfigContextListener.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/UriTemplateParameterTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/AddEndpointTest.java, 2020-06-13 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/JettyServerEndpointConfiguratorTest.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/SessionTrackingTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/ConfiguratorTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/WebAppClassLoaderTest.java, 2020-01-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/server/InputStreamEchoTest.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/SyntheticOnMessageTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/GracefulCloseTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/SessionAddMessageHandlerTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/DecoderReaderManySmallTest.java, 2017-04-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/DelayedStartClientTest.java, 2017-05-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/JsrClientTrackingSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/AnnotatedEchoTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/misbehaving/EndpointRuntimeOnOpen.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/misbehaving/MisbehavingClassTest.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/EndpointEchoTest.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/JsrClientEchoTrackingSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/WriteTimeoutTest.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/AbstractClientSessionTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/IntSocket.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseSessionReasonSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseSessionSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseReasonSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseEndpointConfigSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/samples/CloseReasonSessionSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/CookiesTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/AnnotatedClientEndpointTest.java, 2013-12-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/OnCloseTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/AnnotatedEchoClient.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/MessageReceivingTest.java, 2016-03-22 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/client/ConfiguratorTest.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/LongMessageHandler.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/ExtendedMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/AbstractHandler.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/BaseMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/AbstractAnnotatedHandler.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/BinaryHandlers.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/ComboMessageHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/MessageHandlerTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/handlers/TextHandlers.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/UpgradeRequestResponseTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JakartaClientShutdownWithServerEmbeddedTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesEncoderTest.java, 2017-04-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesDecoderTextStreamTest.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/Quotes.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesDecoderTest.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesDecoder.java, 2017-04-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/quotes/QuotesUtil.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/SingleMessageHandlerTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DecoderListTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/ValidDualDecoder.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/AvailableEncodersTest.java, 2016-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/FruitDecoder.java, 2009-12-04 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/FruitTextEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/LongDecoderTest.java, 2019-06-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/TimeEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DecoderTextStreamTest.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DateEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/EncoderTextTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/Quotes.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/ValidDualEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DateTimeEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/TimeDecoder.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/EncoderLifeCycleTest.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/CoderEventTracking.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DecoderTextTest.java, 2013-02-19 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/Fruit.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/BadDualDecoder.java, 2013-02-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/AvailableDecodersTest.java, 2016-05-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DateDecoder.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/FloatDecoderTest.java, 2019-06-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/ExtDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/QuotesEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/BadDualEncoder.java, 2012-08-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/QuotesDecoder.java, 2017-04-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/DateTimeDecoder.java, 2012-06-25 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/FruitBinaryEncoder.java, 2012-07-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/QuotesUtil.java, 2017-05-05 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/ShortDecoderTest.java, 2019-06-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/coders/IntegerDecoderTest.java, 2013-02-19 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/PathParamTest.java, 2019-08-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/RestartContextTest.java, 2019-06-06 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JakartaWebSocketRestartTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JakartaClientClassLoaderTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn/JakartaAutobahnClient.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn/JakartaAutobahnSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/autobahn/JakartaAutobahnServer.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JettySpecificConfigTest.java, 2019-08-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/IntegerClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/StringClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/IntegerTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/ShortTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/CharacterTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/DoubleTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/LongTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/ByteClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/FloatClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/BooleanClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/ShortClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/CharacterClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/ByteTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/FloatTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/BooleanTypeSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/LongClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/pathparam/DoubleClassSocket.java, 2022-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/ProgrammaticWebSocketUpgradeTest.java, 2022-01-27 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/ServerConfigTest.java, 2020-01-28 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/JakartaOnCloseTest.java, 2020-01-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/BasicEchoEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java, 2013-04-23 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongMessageEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/LargeEchoContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/CoreServer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/FunctionMethod.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/BadFrame.java, 2012-08-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/WSEndpointTracker.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/RawFrameBuilder.java, 2013-08-20 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/BiConsumerServiceServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/EchoSocket.java, 2021-01-21 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/WSServer.java, 2013-04-15 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/CompletableFutureMethodHandle.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/SessionMatchers.java, 2012-07-09 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/framehandlers/FrameHandlerTracker.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/framehandlers/WholeMessageEcho.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/framehandlers/StaticText.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/framehandlers/FrameEcho.java, 2013-07-12 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/Timeouts.java, 2012-05-08 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/UnitGenerator.java, 2017-05-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/LocalFuzzer.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/WSURI.java, 2013-06-10 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/LocalServer.java, 2012-06-29 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/NetworkFuzzer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/matchers/IsMessageHandlerTypeRegistered.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/matchers/IsMessageHandlerType.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/DummyEndpoint.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/Fuzzer.java, 2018-11-02 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/ParserCapture.java, 2011-08-26 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/UpgradeUtils.java, 2017-05-03 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/MessageType.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/Sha1Sum.java, 2015-12-07 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/EventSocket.java, 2019-03-11 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/WSEventTracker.java, 2009-03-24 -jetty-ee9/jetty-ee9-websocket/jetty-ee9-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee9/websocket/jakarta/tests/DataUtils.java, 2017-05-03 -jetty-ee9/jetty-ee9-jspc-maven-plugin/src/main/java/org/eclipse/jetty/ee9/jspc/plugin/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jspc-maven-plugin/src/main/java/org/eclipse/jetty/ee9/jspc/plugin/JspcMojo.java, 2012-08-29 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtEncoder.java, 2019-11-20 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/JwtDecoderTest.java, 2019-11-20 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentialsTest.java, 2021-08-16 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdProvider.java, 2019-09-11 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticationTest.java, 2019-08-29 -jetty-ee9/jetty-ee9-openid/src/test/java/org/eclipse/jetty/ee9/security/openid/OpenIdReamNameTest.java, 2021-11-10 -jetty-ee9/jetty-ee9-openid/src/main/java/module-info.java, 2013-07-12 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdConfiguration.java, 2019-08-29 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/JwtDecoder.java, 2019-11-20 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserPrincipal.java, 2011-03-29 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthenticatorFactory.java, 2019-08-29 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdAuthConfiguration.java, 2021-10-26 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdUserIdentity.java, 2010-12-17 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdLoginService.java, 2019-08-29 -jetty-ee9/jetty-ee9-openid/src/main/java/org/eclipse/jetty/ee9/security/openid/OpenIdCredentials.java, 2019-08-29 -jetty-ee9/jetty-ee9-cdi/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-cdi/src/main/java/org/eclipse/jetty/ee9/cdi/CdiDecoratingListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-cdi/src/main/java/org/eclipse/jetty/ee9/cdi/CdiConfiguration.java, 2020-12-10 -jetty-ee9/jetty-ee9-cdi/src/main/java/org/eclipse/jetty/ee9/cdi/CdiSpiDecorator.java, 2019-08-08 -jetty-ee9/jetty-ee9-cdi/src/main/java/org/eclipse/jetty/ee9/cdi/CdiServletContainerInitializer.java, 2019-08-08 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/BlockingTest.java, 2021-02-02 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpManyWaysToAsyncCommitTest.java, 2012-08-16 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpWriterTest.java, 2009-10-07 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/MockConnector.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ErrorHandlerTest.java, 2016-07-18 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AbstractHandlerContainerTest.java, 2022-05-25 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ResponseTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AbstractHttpTest.java, 2012-08-17 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpOutputTest.java, 2013-07-11 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AsyncContentProducerTest.java, 2020-03-20 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SessionHandlerTest.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/SuspendHandler.java, 2012-01-05 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ServletWriterTest.java, 2019-10-15 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/CookiesTest.java, 2017-07-19 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ContextHandlerTest.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/BlockingContentProducerTest.java, 2020-03-20 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ServerConnectorAsyncContextTest.java, 2011-11-17 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/DumpHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AsyncCompletionTest.java, 2019-08-26 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/LocalAsyncContextTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/MockConnectionMetaData.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpManyWaysToCommitTest.java, 2012-08-16 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/RequestTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/HttpServerTestFixture.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ScopedHandlerTest.java, 2009-05-12 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/ServletRequestWrapperTest.java, 2019-08-08 -jetty-ee9/jetty-ee9-nested/src/test/java/org/eclipse/jetty/ee9/nested/AsyncRequestReadTest.java, 2009-09-12 -jetty-ee9/jetty-ee9-nested/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResponseWriter.java, 2015-04-29 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/HttpContentRangeWriter.java, 2019-07-26 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/InputStreamRangeWriter.java, 2019-07-26 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/RangeWriter.java, 2011-08-11 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/ByteBufferRangeWriter.java, 2013-04-04 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/resource/SeekableByteChannelRangeWriter.java, 2019-07-26 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/jmx/ContextHandlerMBean.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/jmx/AbstractHandlerMBean.java, 2009-06-30 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/jmx/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/MultiPartFormInputStream.java, 2011-07-07 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/BufferedResponseHandler.java, 2016-07-28 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AbstractHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletRequestHttpWrapper.java, 2010-09-03 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AsyncContextEvent.java, 2013-04-22 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResourceService.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletResponseHttpWrapper.java, 2010-09-03 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/DebugHandler.java, 2009-07-28 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpWriter.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContentProducer.java, 2020-03-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannelListeners.java, 2019-08-27 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerContainer.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Cookies.java, 2017-07-19 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InetAccessHandler.java, 2016-09-01 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletAttributes.java, 2012-06-25 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerWrapper.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ResourceHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InetAccessSet.java, 2020-02-27 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AbstractHandlerContainer.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/FileBufferedResponseHandler.java, 2021-04-19 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/QuietServletException.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/BlockingContentProducer.java, 2020-03-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java, 2022-05-03 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Authentication.java, 2009-04-17 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ManagedAttributeListener.java, 2015-06-19 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ScopedHandler.java, 2009-05-12 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HotSwapHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletPathMapping.java, 2020-05-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AsyncDelayHandler.java, 2014-10-23 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ThreadLimitHandler.java, 2016-09-08 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpInput.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Utf8HttpWriter.java, 2012-08-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AsyncAttributes.java, 2020-05-12 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/InclusiveByteRange.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Handler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/MultiPartParser.java, 2018-03-08 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AsyncContentProducer.java, 2020-03-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/DebugListener.java, 2015-09-11 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ContextHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Iso88591HttpWriter.java, 2012-08-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Dispatcher.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannelState.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/PushBuilderImpl.java, 2015-03-11 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ErrorHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/IdleTimeoutHandler.java, 2013-11-08 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerCollection.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HandlerList.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/AsyncContextState.java, 2013-04-22 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/UserIdentity.java, 2009-03-24 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/EncodingHttpWriter.java, 2012-08-20 -jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SecuredRedirectHandler.java, 2014-09-30 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/EmptyServerHandler.java, 2012-09-05 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ReverseProxyTest.java, 2015-02-10 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ConnectHandlerTest.java, 2012-11-06 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ProxyServletTest.java, 2012-01-20 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ProxyServletLoadTest.java, 2015-03-05 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/BalancerServletTest.java, 2012-11-06 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/EchoHttpServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/AsyncMiddleManServletTest.java, 2015-01-15 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ClientAuthProxyTest.java, 2021-02-15 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/AbstractConnectHandlerTest.java, 2012-11-06 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ProxyServletFailureTest.java, 2014-04-30 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ConnectHandlerSSLTest.java, 2012-11-06 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ProxyServer.java, 2012-07-20 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/EmptyHttpServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ForwardProxyServerTest.java, 2016-03-10 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/CachingProxyServlet.java, 2018-09-04 -jetty-ee9/jetty-ee9-proxy/src/test/java/org/eclipse/jetty/ee9/proxy/ForwardProxyTLSServerTest.java, 2013-06-08 -jetty-ee9/jetty-ee9-proxy/src/main/java/module-info.java, 2013-07-12 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/AsyncMiddleManServlet.java, 2015-01-15 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/AfterContentTransformer.java, 2015-04-09 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/AsyncProxyServlet.java, 2014-04-01 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/BalancerServlet.java, 2012-11-06 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/AbstractProxyServlet.java, 2015-01-15 -jetty-ee9/jetty-ee9-proxy/src/main/java/org/eclipse/jetty/ee9/proxy/ProxyServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/DefaultAuthConfigFactoryTest.java, 2021-08-18 -jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/JaspiTest.java, 2014-12-12 -jetty-ee9/jetty-ee9-jaspi/src/test/java/org/eclipse/jetty/ee9/security/jaspi/HttpHeaderAuthModule.java, 2014-12-12 -jetty-ee9/jetty-ee9-jaspi/src/main/java/module-info.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiMessageInfo.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/modules/BaseAuthModule.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/modules/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/modules/BasicAuthenticationAuthModule.java, 2019-08-27 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/SimpleAuthConfig.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/ServletCallbackHandler.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticatorFactory.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/DefaultAuthConfigFactory.java, 2021-08-18 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/callback/CredentialValidationCallback.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/callback/package-info.java, 2012-11-02 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/provider/SimpleServerAuthContext.java, 2021-08-18 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/provider/SimpleAuthConfig.java, 2009-03-24 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/provider/JaspiAuthConfigProvider.java, 2021-08-18 -jetty-ee9/jetty-ee9-jaspi/src/main/java/org/eclipse/jetty/ee9/security/jaspi/JaspiAuthenticator.java, 2009-03-24 -jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9/jsp/TestJspFileNameToClass.java, 2017-01-19 -jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9/jsp/TestJettyJspServlet.java, 2016-10-26 -jetty-ee9/jetty-ee9-apache-jsp/src/test/java/org/eclipse/jetty/ee9/jsp/TestJettyTldPreScanned.java, 2017-10-10 -jetty-ee9/jetty-ee9-apache-jsp/src/main/java/module-info.java, 2012-07-10 -jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9/apache/jsp/JettyTldPreScanned.java, 2017-10-10 -jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9/apache/jsp/JettyJasperInitializer.java, 2014-03-14 -jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9/apache/jsp/JuliLog.java, 2014-03-14 -jetty-ee9/jetty-ee9-apache-jsp/src/main/java/org/eclipse/jetty/ee9/jsp/JettyJspServlet.java, 2014-11-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/WebSocketClientServlet.java, 2020-09-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/EchoEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/QuickStartTest.java, 2014-08-27 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/Quickstart.java, 2014-03-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/PreconfigureStandardTestWar.java, 2014-03-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/QuickStartStandardTestWar.java, 2012-05-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/QuickStartSpecWar.java, 2012-08-31 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/QuickStartJNDIWar.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/PreconfigureJNDIWar.java, 2013-07-10 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-quickstart/src/test/java/org/eclipse/jetty/ee9/quickstart/PreconfigureSpecWar.java, 2014-03-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-badinit-webapp/src/main/java/org/eclipse/jetty/ee10/test/BadServletInit.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java, 2019-06-05 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java, 2019-06-05 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java, 2012-11-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java, 2012-11-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/ErrorPage.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/AdminPage.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/HomePage.java, 2022-02-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/LogoutPage.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/LoginPage.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java, 2019-06-12 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/bad/StringSequence.java, 2011-08-11 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/StringSequence.java, 2011-08-11 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/EchoEndpoint.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/StringSequenceDecoder.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/InformationalResponseTest.java, 2022-06-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/HttpTrailersTest.java, 2017-04-03 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/VirtualThreadsTest.java, 2022-08-18 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/RequestReaderTest.java, 2021-05-19 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/PushCacheFilterTest.java, 2022-11-21 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/AsyncIOServletTest.java, 2013-08-12 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/BlockedIOTest.java, 2021-02-03 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/HttpClientContinueTest.java, 2012-10-10 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/ServerTimeoutsTest.java, 2016-08-31 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-client-transports/src/test/java/org/eclipse/jetty/ee9/test/client/transport/AbstractTest.java, 2022-08-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/WebSocketClientServlet.java, 2020-09-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee9/tests/webapp/websocket/EchoEndpoint.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.DatabaseLoginServiceTestServer.java, 2014-07-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.JdbcLoginServiceTest.java, 2010-05-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-loginservice/src/test/java/org.eclipse.jetty.loginservice.DataSourceLoginServiceTest.java, 2014-07-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/HazelcastClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/client/ClientOrphanedSessionTest.java, 2017-05-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/client/HazelcastSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/client/ClientSessionScavengingTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/HazelcastSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/HazelcastTestHelper.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee9/session/hazelcast/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/ClusteredSessionMigrationTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/JDBCSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/SessionTableSchemaTest.java, 2017-06-06 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/ReloadedSessionMissingClassTest.java, 2013-03-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/ClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee9/session/jdbc/WebAppObjectInSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/MongoTestHelper.java, 2017-01-13 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/ClusteredInvalidateSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/MongoSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee9/session/nosql/mongodb/AttributeNameTest.java, 2014-10-01 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-file/src/test/java/org/eclipse/jetty/ee9/session/file/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/IdleSessionTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/ReentrantRequestSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/ModifyMaxInactiveIntervalTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/DeleteUnloadableSessionTest.java, 2016-06-01 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/RemoveSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/SessionRenewTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/RequestScopedSessionSaveTest.java, 2022-01-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/CreationTest.java, 2017-01-13 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/RequestDispatchedSessionTest.java, 2019-10-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/NonClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/RedirectSessionTest.java, 2016-07-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/ClientCrossContextSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/SessionInvalidateCreateScavengeTest.java, 2012-05-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/SameContextForwardedSessionTest.java, 2015-04-23 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/DuplicateCookieTest.java, 2019-10-16 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/SessionInvalidationTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/ConcurrencyTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/test/java/org/eclipse/jetty/ee9/session/AsyncTest.java, 2018-12-18 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/AbstractSessionTestBase.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/AbstractClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/AbstractClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/TestHttpSessionListener.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/WebAppObjectInSessionServlet.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/AbstractClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/TestSessionDataStore.java, 2015-08-27 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/FooInvocationHandler.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/Foo.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/TestSessionDataStoreFactory.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/SessionTestSupport.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/AbstractWebAppObjectInSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-common/src/main/java/org/eclipse/jetty/ee9/session/TestFoo.java, 2011-03-29 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-memcached/src/test/java/org/eclipse/jetty/ee9/session/memcached/CachingSessionDataStoreTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-memcached/src/test/java/org/eclipse/jetty/ee9/session/memcached/MemcachedTestHelper.java, 2016-06-17 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/InfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/SerializedInfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/LoggingUtil.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/ClusteredSerializedSessionScavengingTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/ClusteredSessionScavengingTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/InfinispanTestSupport.java, 2015-04-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/InfinispanFileSessionDataStoreTest.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/ClusteredOrphanedSessionTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/remote/RemoteClusteredInvalidationSessionTest.java, 2015-04-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/remote/RemoteInfinispanTestSupport.java, 2015-04-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/remote/RemoteClusteredSessionScavengingTest.java, 2012-10-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee9/session/infinispan/remote/RemoteInfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee9/session/gcloud/InvalidationSessionTest.java, 2015-04-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee9/session/gcloud/GCloudSessionTestSupport.java, 2015-09-18 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee9/session/gcloud/GCloudSessionDataStoreTest.java, 2018-03-28 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee9/session/gcloud/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-sessions/jetty-ee9-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee9/session/gcloud/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jndi/src/test/java/org/eclipse/jetty/ee9/jndi/factories/TestMailSessionReference.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/rfcs/RFC2616BaseTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/rfcs/RFC2616NIOHttpTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/rfcs/RFC2616NIOHttpsTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DefaultHandlerTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/RecoverFailedSelectorTest.java, 2020-04-27 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/AllowedResourceAliasCheckerTest.java, 2021-12-07 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/GzipWithSendErrorTest.java, 2020-11-18 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/HttpInputIntegrationTest.java, 2015-02-25 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DeploymentErrorTest.java, 2018-01-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/AliasCheckerSymlinkTest.java, 2021-09-21 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DigestPostTest.java, 2010-03-16 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/FailedSelectorTest.java, 2019-08-30 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/AnnotatedAsyncListenerTest.java, 2019-06-07 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/HttpInputInterceptorTest.java, 2021-04-15 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/StringUtil.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpResponseTesterTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpTesting.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpSocketImpl.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpRequestTesterTest.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/rawhttp/HttpsSocketImpl.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/support/XmlBasedJettyServer.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/KeyStoreScannerTest.java, 2020-07-10 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/websocket/JettySimpleEchoSocket.java, 2012-06-27 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/websocket/JettyWebSocketTest.java, 2019-03-21 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/websocket/JakartaWebSocketTest.java, 2019-03-21 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/websocket/JakartaSimpleEchoSocket.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-integration/src/test/java/org/eclipse/jetty/ee9/test/DeploymentErrorInitializer.java, 2012-07-10 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-webapp-rfc2616/src/main/java/org/eclipse/jetty/tests/webapp/HttpMethodsServlet.java, 2009-07-08 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java, 2017-09-30 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java, 2017-09-30 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp-it/src/test/java/org/eclipse/jetty/ee9/test/jmx/JmxIT.java, 2015-01-16 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/MyContainerInitializer.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/Echoer.java, 2012-08-03 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/jmx/PingerMBean.java, 2012-07-23 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/jmx/EchoerMBean.java, 2012-08-03 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/CommonComponent.java, 2012-07-23 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/PingServlet.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-jmx/jetty-ee9-jmx-webapp/src/main/java/org/eclipse/jetty/ee9/test/jmx/Pinger.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/GreetingsServlet.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/EmbeddedWeldTest.java, 2020-09-07 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/MyFilter.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/Greetings.java, 2012-11-02 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/FriendlyGreetings.java, 2012-07-09 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/MyContextListener.java, 2009-03-24 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/websocket/JettyWebSocketCdiTest.java, 2021-03-31 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/websocket/JavaxWebSocketCdiTest.java, 2021-03-31 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-cdi/src/test/java/org/eclipse/jetty/ee9/cdi/tests/websocket/LogFactory.java, 2021-03-31 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-simple-session-webapp/src/main/java/org/eclipse/jetty/test/session/SessionTest.java, 2011-12-14 -jetty-ee9/jetty-ee9-tests/jetty-ee9-test-simple-session-webapp/src/main/java/org/eclipse/jetty/test/session/Chocolate.java, 2009-03-24 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java, 2020-04-08 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java, 2020-09-14 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/HandlerDocs.java, 2022-07-08 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java, 2020-04-13 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/ServerDocs.java, 2020-09-08 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/websocket/WebSocketServerDocs.java, 2021-09-15 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http3/HTTP3ServerDocs.java, 2020-04-13 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/SelectorManagerDocs.java, 2019-08-07 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java, 2019-07-31 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java, 2020-03-31 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java, 2020-04-06 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/websocket/WebSocketClientDocs.java, 2021-04-20 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http3/HTTP3ClientDocs.java, 2020-04-06 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/WebSocketDocs.java, 2021-04-20 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/ComponentDocs.java, 2020-04-20 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java, 2020-04-13 -documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/JMXDocs.java, 2020-05-03 -documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JettyIncludeExtension.java, 2021-01-25 -documentation/jetty-asciidoctor-extensions/src/main/java/org/eclipse/jetty/docs/JavadocIncludeExtension.java, 2022-01-12 -jetty-integrations/jetty-infinispan/jetty-infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java, 2019-04-18 -jetty-integrations/jetty-infinispan/jetty-infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java, 2009-06-11 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java, 2018-11-06 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/NullQueryManagerFactory.java, 2012-08-27 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManager.java, 2009-03-24 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java, 2021-09-21 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanKeyBuilder.java, 2009-03-24 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/QueryManagerFactory.java, 2009-03-24 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/BoundDelegatingInputStream.java, 2020-03-23 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionLegacyConverter.java, 2018-11-06 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java, 2018-11-06 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java, 2016-04-15 -jetty-integrations/jetty-infinispan/jetty-infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java, 2015-11-13 -jetty-integrations/jetty-infinispan/jetty-infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java, 2019-04-18 -jetty-integrations/jetty-infinispan/jetty-infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManagerFactory.java, 2019-04-18 -jetty-integrations/jetty-hazelcast/src/main/java/module-info.java, 2013-07-12 -jetty-integrations/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java, 2017-05-29 -jetty-integrations/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java, 2017-05-29 -jetty-integrations/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/SessionDataSerializer.java, 2018-11-06 -jetty-integrations/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreFactory.java, 2016-04-15 -jetty-integrations/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java, 2015-12-11 -jetty-integrations/jetty-memcached/jetty-memcached-sessions/src/main/java/module-info.java, 2013-07-12 -jetty-integrations/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.java, 2016-05-27 -jetty-integrations/jetty-memcached/jetty-memcached-sessions/src/main/java/org/eclipse/jetty/memcached/session/MemcachedSessionDataMapFactory.java, 2016-05-27 -jetty-integrations/jetty-nosql/src/main/java/module-info.java, 2013-07-12 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/NoSqlSessionDataStore.java, 2015-11-20 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java, 2015-11-20 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoUtils.java, 2018-03-28 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/package-info.java, 2012-11-02 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreFactory.java, 2016-04-15 -jetty-integrations/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/package-info.java, 2012-11-02 -jetty-core/jetty-quic/jetty-quic-client/src/test/java/org/eclipse/jetty/quic/client/End2EndClientTest.java, 2021-03-31 -jetty-core/jetty-quic/jetty-quic-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-client/src/main/java/org/eclipse/jetty/quic/client/ClientProtocolSession.java, 2021-09-11 -jetty-core/jetty-quic/jetty-quic-client/src/main/java/org/eclipse/jetty/quic/client/ClientQuicSession.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-client/src/main/java/org/eclipse/jetty/quic/client/ClientQuicConnection.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-client/src/main/java/org/eclipse/jetty/quic/client/QuicClientConnectorConfigurator.java, 2021-03-31 -jetty-core/jetty-quic/jetty-quic-server/src/test/java/org/eclipse/jetty/quic/server/ServerQuicConnectorTest.java, 2021-03-12 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/internal/SimpleTokenValidator.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/internal/SimpleTokenMinter.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/ServerQuicSession.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/ServerQuicConnection.java, 2021-03-23 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/QuicServerConnector.java, 2021-03-12 -jetty-core/jetty-quic/jetty-quic-server/src/main/java/org/eclipse/jetty/quic/server/ServerProtocolSession.java, 2021-09-11 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/StreamType.java, 2021-09-12 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicSessionContainer.java, 2021-10-12 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicConnection.java, 2021-03-12 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/CloseInfo.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/ProtocolSession.java, 2021-09-09 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicErrorCode.java, 2021-10-13 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicConfiguration.java, 2021-10-15 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicSession.java, 2021-03-16 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/package-info.java, 2021-03-31 -jetty-core/jetty-quic/jetty-quic-common/src/main/java/org/eclipse/jetty/quic/common/QuicStreamEndPoint.java, 2021-03-16 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/test/java/org/eclipse/jetty/quic/quiche/foreign/incubator/LowLevelQuicheTest.java, 2021-09-20 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/macos/sockaddr_macos.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/windows/sockaddr_windows.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/NativeHelper.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_path_stats.java, 2022-10-18 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_send_info.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheConnection.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/linux/sockaddr_linux.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/ForeignIncubatorQuicheBinding.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_stats.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_h.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/quiche_recv_info.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-foreign-incubator/src/main/java/org/eclipse/jetty/quic/quiche/foreign/incubator/sockaddr.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/test/java/org/eclipse/jetty/quic/quiche/jna/LowLevelQuicheTest.java, 2021-09-20 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/macos/netinet_macos.java, 2021-09-10 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/bool_pointer.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/ssize_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/windows/netinet_windows.java, 2021-09-10 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/size_t_pointer.java, 2021-03-15 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/SizedStructure.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/LibQuiche.java, 2021-03-15 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint16_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint32_t_pointer.java, 2011-09-12 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint64_t_pointer.java, 2011-09-12 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/timespec.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/linux/netinet_linux.java, 2021-09-10 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/size_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/char_pointer.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheConnection.java, 2021-03-15 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr_storage.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint8_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/JnaQuicheBinding.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint8_t_pointer.java, 2011-09-12 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint64_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/uint32_t.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-jna/src/main/java/org/eclipse/jetty/quic/quiche/jna/sockaddr.java, 2021-09-13 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/Quiche.java, 2009-03-24 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/QuicheBinding.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/QuicheConfig.java, 2021-03-15 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/QuicheConnection.java, 2021-11-08 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/SSLKeyPair.java, 2021-03-15 -jetty-core/jetty-quic/jetty-quic-quiche/jetty-quic-quiche-common/src/main/java/org/eclipse/jetty/quic/quiche/QuicheConnectionId.java, 2021-03-15 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutTest.java, 2018-01-10 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointOpenCloseTest.java, 2011-10-18 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/IdleTimeoutTest.java, 2013-01-11 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointInterestsTest.java, 2012-07-30 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ByteBufferAccumulatorTest.java, 2020-11-17 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ContentTest.java, 2022-12-01 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ArrayByteBufferPoolTest.java, 2021-05-28 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/NIOTest.java, 2011-11-28 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/AsyncContentTest.java, 2022-05-30 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ByteArrayEndPointTest.java, 2012-05-03 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/WriteFlusherTest.java, 2012-07-31 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ContentSourceTransformerTest.java, 2022-05-30 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/SocketChannelEndPointTest.java, 2011-10-18 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/SelectorManagerTest.java, 2012-10-05 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/CyclicTimeoutsTest.java, 2021-06-03 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/IOTest.java, 2005-11-27 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/SslConnectionTest.java, 2012-06-04 -jetty-core/jetty-io/src/test/java/org/eclipse/jetty/io/ContentSourceTest.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java, 2011-02-28 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/jmx/ConnectionStatisticsMBean.java, 2021-06-03 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficSocketChannelEndPoint.java, 2011-02-10 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/WriteFlusher.java, 2012-05-10 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/ContentSourceConsumer.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/ContentSourceString.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/ContentSourceByteBuffer.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/NonRetainableByteBuffer.java, 2009-03-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/ContentCopier.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/internal/ByteBufferChunk.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Connection.java, 2002-06-14 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteArrayEndPoint.java, 2005-11-27 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IdleTimeout.java, 2012-11-09 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/DatagramChannelEndPoint.java, 2021-12-01 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnection.java, 2012-07-27 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferAccumulator.java, 2020-11-05 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EndPoint.java, 2005-11-27 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SelectableChannelEndPoint.java, 2015-11-06 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/FillInterest.java, 2012-05-10 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/RuntimeIOException.java, 2009-03-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SelectorManager.java, 2006-11-05 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/NegotiatingClientConnectionFactory.java, 2009-03-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ManagedSelector.java, 2014-12-17 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Content.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/IncludeExcludeConnectionStatistics.java, 2020-08-14 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/NetworkTrafficListener.java, 2009-03-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/Retainable.java, 2022-07-25 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/OutputStreamContentSource.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/InputStreamContentSource.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/AsyncContent.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSinkSubscriber.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/PathContentSource.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ChunksContentSource.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceTransformer.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ByteBufferContentSource.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourcePublisher.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSinkOutputStream.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/content/ContentSourceInputStream.java, 2022-05-30 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/QuietException.java, 2012-08-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractRetainableByteBuffer.java, 2023-01-27 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/SocketChannelEndPoint.java, 2015-11-06 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeouts.java, 2021-05-16 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractEndPoint.java, 2012-05-02 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferCallbackAccumulator.java, 2021-08-18 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/package-info.java, 2012-11-02 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java, 2021-05-28 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java, 2016-09-14 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/CyclicTimeout.java, 2018-01-10 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnectionFactory.java, 2013-10-04 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferInputStream.java, 2022-07-15 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferPool.java, 2021-05-28 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferOutputStream.java, 2012-08-09 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java, 2019-01-17 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/WriterOutputStream.java, 2002-02-12 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/RetainableByteBuffer.java, 2018-11-02 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslConnection.java, 2012-05-11 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/ALPNProcessor.java, 2012-06-12 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslClientConnectionFactory.java, 2013-10-04 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/package-info.java, 2012-11-02 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ssl/SslHandshakeListener.java, 2016-05-24 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ByteBufferOutputStream2.java, 2020-11-05 -jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/EofException.java, 2009-03-24 -jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestJNDI.java, 2003-06-30 -jetty-core/jetty-jndi/src/test/java/org/eclipse/jetty/jndi/java/TestLocalJNDI.java, 2009-03-24 -jetty-core/jetty-jndi/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/InitialContextFactory.java, 2003-07-01 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/DataSourceCloser.java, 2010-12-21 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NameEnumeration.java, 2011-09-13 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaRootURLContext.java, 2003-06-30 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaURLContextFactory.java, 2003-06-30 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/javaNameParser.java, 2003-06-30 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/java/package-info.java, 2012-11-02 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java, 2003-06-30 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingContext.java, 2003-06-30 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/package-info.java, 2012-11-02 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/BindingEnumeration.java, 2011-09-13 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/localContextRoot.java, 2009-03-24 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/local/package-info.java, 2012-11-02 -jetty-core/jetty-jndi/src/main/java/org/eclipse/jetty/jndi/NamingUtil.java, 2009-03-24 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/AnnotatedTestConfiguration.java, 2012-08-10 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlParserTest.java, 2011-02-17 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/ConstructorArgTestClass.java, 2012-05-30 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/CatalogTest.java, 2022-08-09 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/ExampleConfiguration.java, 2009-03-24 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlAppendableTest.java, 2014-02-13 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java, 2006-05-22 -jetty-core/jetty-xml/src/test/java/org/eclipse/jetty/xml/DefaultTestConfiguration.java, 2012-08-10 -jetty-core/jetty-xml/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessor.java, 2011-02-17 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/EnvironmentBuilder.java, 2022-05-03 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java, 2000-08-09 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlParser.java, 2000-07-28 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/BaseClassCatalog.java, 2022-08-09 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlAppendable.java, 2014-02-13 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/ConfigurationProcessorFactory.java, 2009-03-24 -jetty-core/jetty-xml/src/main/java/org/eclipse/jetty/xml/package-info.java, 2012-11-02 -jetty-core/jetty-alpn/jetty-alpn-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnection.java, 2012-07-27 -jetty-core/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnectionFactory.java, 2013-10-04 -jetty-core/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9HTTP2Server.java, 2017-01-12 -jetty-core/jetty-alpn/jetty-alpn-java-server/src/test/java/org/eclipse/jetty/alpn/java/server/JDK9ALPNTest.java, 2017-01-13 -jetty-core/jetty-alpn/jetty-alpn-java-server/src/main/java/module-info.java, 2009-03-30 -jetty-core/jetty-alpn/jetty-alpn-java-server/src/main/java/org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor.java, 2010-01-26 -jetty-core/jetty-alpn/jetty-alpn-java-client/src/test/java/org/eclipse/jetty/alpn/java/client/JDK9HTTP2ClientTest.java, 2019-04-15 -jetty-core/jetty-alpn/jetty-alpn-java-client/src/main/java/module-info.java, 2009-03-30 -jetty-core/jetty-alpn/jetty-alpn-java-client/src/main/java/org/eclipse/jetty/alpn/java/client/JDK9ClientALPNProcessor.java, 2012-06-27 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-server/src/test/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptHTTP2ServerTest.java, 2019-03-05 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-server/src/main/java/org/eclipse/jetty/alpn/conscrypt/server/ConscryptServerALPNProcessor.java, 2017-09-21 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-client/src/test/java/org/eclipse/jetty/alpn/java/client/ConscryptHTTP2ClientTest.java, 2019-04-15 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-alpn/jetty-alpn-conscrypt-client/src/main/java/org/eclipse/jetty/alpn/conscrypt/client/ConscryptClientALPNProcessor.java, 2017-09-21 -jetty-core/jetty-alpn/jetty-alpn-server/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnection.java, 2014-03-18 -jetty-core/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java, 2014-03-18 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/FileSessionDataStoreTest.java, 2013-03-28 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/HouseKeeperTest.java, 2020-08-05 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandlerTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DefaultSessionCacheTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionConsumer.java, 2010-01-26 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionDataStore.java, 2015-08-27 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/NullSessionCacheTest.java, 2018-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SessionListenerTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/AbstractSessionManagerTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/FileTestHelper.java, 2010-01-26 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/AbstractSessionCacheTest.java, 2019-09-11 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionManager.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DirtyAttributeTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/JdbcTestHelper.java, 2010-01-26 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/FileSessionsTest.java, 2017-03-22 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableRequest.java, 2022-05-03 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/AbstractSessionDataStoreTest.java, 2018-03-28 -jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/DefaultSessionIdManagerTest.java, 2022-05-03 -jetty-core/jetty-session/src/test/resources/ProxyableFactory.java, 2009-03-24 -jetty-core/jetty-session/src/test/resources/Proxyable.java, 2012-11-02 -jetty-core/jetty-session/src/test/resources/Foo.java, 2009-03-24 -jetty-core/jetty-session/src/test/resources/ProxyableInvocationHandler.java, 2010-01-26 -jetty-core/jetty-session/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/JDBCSessionDataStore.java, 2015-08-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionDataMapFactory.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/DefaultSessionCacheFactory.java, 2016-04-15 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/DefaultSessionCache.java, 2015-08-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionDataStoreFactory.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionDataStoreFactory.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/NullSessionCache.java, 2016-05-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/FileSessionDataStoreFactory.java, 2016-04-15 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionConfig.java, 2022-05-03 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionManager.java, 2022-05-03 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/NullSessionCacheFactory.java, 2016-04-15 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/UnwriteableSessionDataException.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionDataStore.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionManager.java, 2022-05-03 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionDataMap.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/DatabaseAdaptor.java, 2015-10-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/DefaultSessionIdManager.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionCache.java, 2015-08-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/HouseKeeper.java, 2015-10-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionCacheFactory.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionCacheFactory.java, 2016-04-15 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionInactivityTimer.java, 2022-05-03 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/CachingSessionDataStoreFactory.java, 2010-01-26 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/package-info.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionContext.java, 2015-09-04 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionCache.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/NullSessionDataStore.java, 2015-08-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/JDBCSessionDataStoreFactory.java, 2016-04-15 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/FileSessionDataStore.java, 2015-09-11 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/CachingSessionDataStore.java, 2016-04-25 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/NullSessionDataStoreFactory.java, 2010-01-26 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/AbstractSessionDataStore.java, 2015-08-27 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/ManagedSession.java, 2011-07-07 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionIdManager.java, 2009-03-24 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/UnreadableSessionDataException.java, 2012-07-09 -jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionData.java, 2015-08-27 -jetty-core/jetty-ee/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-ee/src/main/java/org/eclipse/jetty/ee/Deployable.java, 2022-06-30 -jetty-core/jetty-keystore/src/test/java/org/eclipse/jetty/test/keystore/KeystoreGeneratorTest.java, 2022-12-20 -jetty-core/jetty-keystore/src/main/java/org/eclipse/jetty/keystore/KeystoreGenerator.java, 2021-01-06 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/EmptyServerHandler.java, 2012-09-05 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientIdleTimeoutTest.java, 2015-02-09 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientTest.java, 2015-02-05 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientConnectTimeoutTest.java, 2015-02-09 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientLoadTest.java, 2012-09-17 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/ForwardProxyWithDynamicTransportTest.java, 2019-08-13 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/ConnectionStatisticsTest.java, 2016-09-14 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/TrailersTest.java, 2022-09-16 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/RoundRobinConnectionPoolTest.java, 2018-03-21 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientStreamTest.java, 2012-09-08 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpInterimResponseTest.java, 2022-09-26 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientTransportDynamicTest.java, 2019-01-17 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientTimeoutTest.java, 2012-10-24 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/VirtualThreadsTest.java, 2022-08-17 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpChannelAssociationTest.java, 2015-12-18 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/HttpClientDemandTest.java, 2019-09-19 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/AsyncRequestContentTest.java, 2015-09-25 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/ServerTimeoutsTest.java, 2009-03-24 -jetty-core/jetty-tests/jetty-test-client-transports/src/test/java/org/eclipse/jetty/test/client/transport/AbstractTest.java, 2022-08-17 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/Slf4jEffort.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/StdErrAppenderTest.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/JMXTest.java, 2020-05-03 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/JettyLoggerTest.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/CapturedStream.java, 2011-10-27 -jetty-core/jetty-slf4j-impl/src/test/java/org/eclipse/jetty/logging/JettyLoggerConfigurationTest.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/Timestamp.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyLoggingServiceProvider.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/StdErrAppender.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyLogger.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyLoggerConfiguration.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/StacklessLogging.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyLoggerFactory.java, 2020-02-24 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyLevel.java, 2020-05-08 -jetty-core/jetty-slf4j-impl/src/main/java/org/eclipse/jetty/logging/JettyAppender.java, 2009-03-24 -jetty-core/jetty-demos/jetty-demo-handler/src/main/java/org/eclipse/jetty/demo/HelloHandler.java, 2012-09-05 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BarebonesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BarebonesAddToStartdTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EmptyCreateStartdTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EmptyAddToStartTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BarebonesAlreadyEnabledTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/TransientIniTemplateTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BarebonesAddUnknownTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasehomeWithfilesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/PropertyOverrideTest.java, 2021-11-17 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/OrderedTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/DatabaseTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AlternatesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/LoopTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/Files0Test.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EmptyAddToStartCreateStartdTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AgentPropertiesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/ParameterizedTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/VersionedModulesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicPropertiesTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BarebonesAddToStartTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/DynamicDependTest.java, 2021-11-15 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/JarVersionTest.java, 2010-01-26 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/BaseHomeTest.java, 2013-08-17 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenMetadataTest.java, 2020-09-18 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializerTest.java, 2014-11-13 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/UtilsTest.java, 2019-05-07 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/CommandLineBuilderTest.java, 2012-01-30 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleGraphWriterTest.java, 2013-08-21 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PathMatchersAbsoluteTest.java, 2014-04-29 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/VersionTest.java, 2009-07-23 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/StartMatchers.java, 2014-11-20 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/FileArgTest.java, 2014-06-03 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PropertyPassingTest.java, 2013-06-12 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java, 2013-08-21 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/FSTest.java, 2010-01-26 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PropertyDump.java, 2012-06-28 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/TestEnv.java, 2010-01-26 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/util/CorrectMavenCentralRefs.java, 2014-11-14 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/util/RebuildTestResources.java, 2014-11-03 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java, 2011-12-30 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PathFinderTest.java, 2014-03-26 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PropsTest.java, 2013-12-26 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModuleTest.java, 2013-08-21 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/config/ConfigSourcesTest.java, 2014-04-10 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java, 2014-04-09 -jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/PathMatchersSearchRootTest.java, 2014-04-29 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java, 2014-11-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/FileArg.java, 2012-06-27 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Utils.java, 2014-11-13 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartIni.java, 2013-08-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Version.java, 2002-08-27 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java, 2013-08-21 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Classpath.java, 2002-08-23 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/CommandLineBuilder.java, 2012-01-30 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/PathFinder.java, 2014-03-26 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/FS.java, 2013-08-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/JarVersion.java, 2009-07-23 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/BaseHomeFileInitializer.java, 2009-03-24 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/UriFileInitializer.java, 2014-11-13 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/TestFileInitializer.java, 2009-03-24 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenMetadata.java, 2020-09-18 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/LocalFileInitializer.java, 2016-10-20 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/fileinits/MavenLocalRepoFileInitializer.java, 2014-11-13 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/ModuleGraphWriter.java, 2013-08-30 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/NaturalSort.java, 2013-08-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/PathMatchers.java, 2014-03-26 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/RawArgs.java, 2014-06-04 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/TextFile.java, 2013-08-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartLog.java, 2013-08-22 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/builders/StartDirBuilder.java, 2014-11-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/builders/StartIniBuilder.java, 2014-11-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Licensing.java, 2014-11-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java, 2013-08-21 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/package-info.java, 2012-11-02 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/PropsException.java, 2012-06-12 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java, 2002-08-23 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/CommandLineConfigSource.java, 2014-04-10 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/ConfigSources.java, 2014-04-10 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/DirConfigSource.java, 2014-04-09 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/ConfigSource.java, 2011-08-26 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/JettyHomeConfigSource.java, 2009-03-24 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/config/JettyBaseConfigSource.java, 2009-03-24 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java, 2013-08-22 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/FileInitializer.java, 2009-03-24 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/UsageException.java, 2012-06-12 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseHome.java, 2013-08-17 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java, 2022-05-03 -jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Props.java, 2013-12-26 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java, 2012-09-13 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientFailureTest.java, 2015-02-15 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/EmptyServerHandler.java, 2012-09-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientChunkedContentTest.java, 2015-04-23 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpRequestAbortTest.java, 2012-09-13 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/LivelockTest.java, 2017-10-28 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpCookieTest.java, 2012-09-06 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/jmx/HttpClientJMXTest.java, 2017-12-12 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyTest.java, 2012-11-06 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/InsufficientThreadsDetectionTest.java, 2017-10-02 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ValidatingConnectionPoolTest.java, 2015-09-01 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientRedirectTest.java, 2012-09-04 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientIdleTimeoutTest.java, 2019-12-17 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ServerConnectionCloseTest.java, 2015-09-21 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java, 2012-07-18 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientExplicitConnectionTest.java, 2012-09-17 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java, 2016-03-07 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpConnectionLifecycleTest.java, 2012-09-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java, 2014-07-21 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolMaxUsageTest.java, 2022-08-13 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTPTest.java, 2014-04-07 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/http/HttpSenderOverHTTPTest.java, 2014-04-07 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAuthenticationTest.java, 2012-09-10 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HostnameVerificationTest.java, 2013-01-17 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ExternalSiteTest.java, 2012-10-30 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolHelper.java, 2011-02-16 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientUploadDuringServerShutdownTest.java, 2015-03-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java, 2015-09-23 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ContentResponseTest.java, 2014-05-14 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpAuthenticationStoreTest.java, 2016-03-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseConcurrentAbortTest.java, 2012-09-13 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCustomProxyTest.java, 2013-10-04 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/InputStreamContentTest.java, 2020-02-19 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartRequestContentTest.java, 2015-10-27 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/SPNEGOAuthenticationTest.java, 2018-09-14 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/TypedContentProviderTest.java, 2014-05-14 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/AsyncRequestContentTest.java, 2020-02-19 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java, 2017-10-16 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/TLSServerConnectionCloseTest.java, 2015-09-21 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/NetworkTrafficListenerTest.java, 2020-04-07 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientProxyProtocolTest.java, 2019-12-17 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java, 2014-09-16 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/AbstractHttpClientServerTest.java, 2012-09-04 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientSynchronizationTest.java, 2012-10-25 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientAsyncContentTest.java, 2014-04-19 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ProxyConfigurationTest.java, 2013-10-17 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientCorrelationDataTest.java, 2019-07-26 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/NeedWantClientAuthTest.java, 2017-04-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslBytesTest.java, 2011-11-24 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java, 2017-01-10 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientURITest.java, 2013-05-05 -jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/DuplexHttpDestinationTest.java, 2020-12-10 -jetty-core/jetty-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Socks4Proxy.java, 2013-10-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/RequestListeners.java, 2023-02-13 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContinueProtocolHandler.java, 2012-10-10 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ValidatingConnectionPool.java, 2015-09-01 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/BufferingResponseListener.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/PathRequestContent.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/UpgradeProtocolHandler.java, 2019-12-09 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandlers.java, 2015-03-31 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/jmx/HttpClientMBean.java, 2012-08-03 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyConfiguration.java, 2013-10-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpContentResponse.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/TunnelRequest.java, 2009-03-24 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpAuthenticationStore.java, 2012-09-10 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/NotifyingRequestListeners.java, 2023-02-13 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/RedirectProtocolHandler.java, 2012-09-09 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/WWWAuthenticationProtocolHandler.java, 2013-03-27 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectionPool.java, 2015-10-30 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Connection.java, 2009-06-11 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponseException.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractHttpClientTransport.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/InputStreamResponseListener.java, 2012-09-17 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequestException.java, 2011-02-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/BytesRequestContent.java, 2020-02-19 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Origin.java, 2009-06-11 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/FormRequestContent.java, 2014-05-14 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Authentication.java, 2012-06-25 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java, 2013-10-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Destination.java, 2023-01-11 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/LeakTrackingConnectionPool.java, 2014-01-07 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ByteBufferRequestContent.java, 2020-02-19 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java, 2012-09-10 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/StringRequestContent.java, 2012-05-08 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationStore.java, 2009-06-11 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/FutureResponseListener.java, 2012-03-14 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentResponse.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/MultiPartRequestContent.java, 2015-10-27 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRedirector.java, 2013-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Request.java, 2012-07-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/BasicAuthentication.java, 2012-09-10 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/MultiplexConnectionPool.java, 2015-10-30 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Result.java, 2012-09-08 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyProtocolClientConnectionFactory.java, 2019-12-17 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProcessingProtocolHandler.java, 2022-09-26 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/SendFailure.java, 2011-02-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/ProtocolHttpUpgrader.java, 2019-12-09 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpReceiverOverHTTP.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpSenderOverHTTP.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpConnectionOverHTTP.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpChannelOverHTTP.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/ResponseListeners.java, 2012-09-10 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpReceiver.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpExchange.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpClientConnectionFactory.java, 2012-07-27 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpClientTransportOverHTTP.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpResponse.java, 2009-06-11 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpDestination.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpClientTransportDynamic.java, 2019-01-17 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpRequest.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/IConnection.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpConversation.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpSender.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpChannel.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/HttpConnection.java, 2012-09-04 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/OutputStreamRequestContent.java, 2020-02-19 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProtocolHandler.java, 2011-02-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ProxyAuthenticationProtocolHandler.java, 2013-03-27 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/EarlyHintsProtocolHandler.java, 2022-09-26 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/RoundRobinConnectionPool.java, 2017-10-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/DigestAuthentication.java, 2012-09-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexConnectionPool.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ConnectionPool.java, 2013-07-12 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java, 2012-09-18 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java, 2012-09-18 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/Response.java, 2012-07-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/SPNEGOAuthentication.java, 2018-09-14 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/InputStreamRequestContent.java, 2020-02-19 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AsyncRequestContent.java, 2020-02-19 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpUpgrader.java, 2011-02-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClientTransport.java, 2011-02-16 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractAuthentication.java, 2016-03-05 -jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/RandomConnectionPool.java, 2012-07-23 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerTest.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java, 2009-03-24 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/test/XmlConfiguredJetty.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/JmxServiceConnection.java, 2015-07-23 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCyclePathCollector.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/DeploymentManagerLifeCycleRouteTest.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/AppLifeCycleTest.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ContextProviderRuntimeUpdatesTest.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/providers/ContextProviderStartupTest.java, 2009-12-04 -jetty-core/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/graph/GraphTest.java, 2009-12-08 -jetty-core/jetty-deploy/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/package-info.java, 2012-11-02 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/jmx/DeploymentManagerMBean.java, 2011-01-06 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStopper.java, 2009-03-24 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/OrderedGroupBinding.java, 2011-05-20 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardDeployer.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/package-info.java, 2012-11-02 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/DebugBinding.java, 2009-03-24 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/package-info.java, 2012-11-02 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java, 2009-12-31 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/package-info.java, 2012-11-02 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java, 2009-12-30 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java, 2009-03-24 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Graph.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Edge.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Route.java, 2009-12-08 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/Node.java, 2009-12-04 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/GraphOutputDot.java, 2009-12-07 -jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/graph/package-info.java, 2012-11-02 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/Baz.java, 2020-01-14 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorTest.java, 2009-01-13 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/Bar.java, 2020-01-14 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertorTest.java, 2013-07-26 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactoryTest.java, 2009-01-13 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/Color.java, 2012-11-02 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/Foo.java, 2020-01-14 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/AsyncJSONTest.java, 2020-05-20 -jetty-core/jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java, 2007-04-11 -jetty-core/jetty-util-ajax/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSON.java, 2007-01-27 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONEnumConvertor.java, 2007-12-21 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONCollectionConvertor.java, 2009-03-24 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONDateConvertor.java, 2007-12-21 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONObjectConvertor.java, 2007-12-03 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/package-info.java, 2012-11-02 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/AsyncJSON.java, 2020-05-20 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertorFactory.java, 2009-08-11 -jetty-core/jetty-util-ajax/src/main/java/org/eclipse/jetty/util/ajax/JSONPojoConvertor.java, 2009-01-13 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/GoAwayTest.java, 2021-10-07 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HttpClientTransportOverHTTP3Test.java, 2021-10-19 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ClientServerTest.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/UnexpectedFrameTest.java, 2021-09-28 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/ExternalServerTest.java, 2021-09-29 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/AbstractClientServerTest.java, 2021-09-21 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/StreamIdleTimeoutTest.java, 2021-10-01 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/DataDemandTest.java, 2021-09-21 -jetty-core/jetty-http3/jetty-http3-tests/src/test/java/org/eclipse/jetty/http3/tests/HandlerClientServerTest.java, 2021-10-12 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/TestEncoderHandler.java, 2021-02-18 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/InstructionGeneratorTest.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/PreEncodedFieldTest.java, 2021-05-31 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/DecoderInstructionParserTest.java, 2021-02-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EvictionTest.java, 2021-03-09 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/TestDecoderHandler.java, 2021-02-18 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/DecoderParserDebugHandler.java, 2021-03-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java, 2021-03-09 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncoderParserDebugHandler.java, 2021-03-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java, 2021-03-03 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java, 2022-08-11 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/HuffmanTest.java, 2014-06-02 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerParserTest.java, 2021-02-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/BlockedStreamsTest.java, 2022-08-11 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncoderInstructionParserTest.java, 2021-02-11 -jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/NBitIntegerTest.java, 2014-06-02 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackException.java, 2012-06-25 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackFieldPreEncoder.java, 2014-08-06 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/Http3Fields.java, 2021-05-04 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/AuthorityHttpField.java, 2014-06-09 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/StaticTableHttpField.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/metadata/MetaDataBuilder.java, 2014-06-09 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/QpackContext.java, 2014-06-08 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/parser/DecoderInstructionParser.java, 2021-02-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/parser/EncodedFieldSection.java, 2021-02-18 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/parser/EncoderInstructionParser.java, 2021-02-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/table/StaticTable.java, 2021-02-05 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/table/DynamicTable.java, 2021-02-05 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/table/Entry.java, 2021-02-05 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SetCapacityInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/InsertCountIncrementInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/StreamCancellationInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/IndexedNameEntryInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/LiteralNameEntryInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/AbstractInstruction.java, 2012-08-03 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SectionAcknowledgmentInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/DuplicateInstruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/StreamInfo.java, 2021-03-04 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/NBitIntegerEncoder.java, 2014-06-02 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/HuffmanEncoder.java, 2014-06-02 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/EncodingException.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/NBitIntegerParser.java, 2021-02-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/NBitStringParser.java, 2021-02-11 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/util/HuffmanDecoder.java, 2021-03-10 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/EncodableEntry.java, 2021-02-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/Instruction.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnectionFactory.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HTTP3StreamServer.java, 2021-11-29 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java, 2021-09-21 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HttpStreamOverHTTP3.java, 2022-05-03 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3Session.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/HTTP3SessionServer.java, 2011-09-12 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/RawHTTP3ServerConnectionFactory.java, 2011-09-12 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/AbstractHTTP3ServerConnectionFactory.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnector.java, 2021-10-15 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/internal/HttpReceiverOverHTTP3.java, 2021-10-19 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/internal/HttpConnectionOverHTTP3.java, 2021-10-15 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/internal/HttpChannelOverHTTP3.java, 2021-10-12 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/internal/HttpSenderOverHTTP3.java, 2015-02-05 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/internal/SessionClientListener.java, 2021-10-19 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/HttpClientTransportOverHTTP3.java, 2021-10-15 -jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/ClientConnectionFactoryOverHTTP3.java, 2021-10-15 -jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/HeadersGenerateParseTest.java, 2021-09-14 -jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/DataGenerateParseTest.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/SettingsGenerateParseTest.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/GoAwayGenerateParseTest.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/VarLenIntTest.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/SettingsFrame.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/HeadersFrame.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/Frame.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/GoAwayFrame.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/DataFrame.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/frames/FrameType.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3ErrorCode.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlStreamConnection.java, 2017-04-01 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/VarLenInt.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/InstructionHandler.java, 2017-04-01 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/MessageFlusher.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/ControlParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/UnknownBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/PushPromiseBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/GoAwayBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/ParserListener.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/MessageParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/HeadersBodyParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/SettingsBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/DataBodyParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/BodyParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/CancelPushBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/HeaderParser.java, 2021-09-09 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/parser/MaxPushIdBodyParser.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/EncoderStreamConnection.java, 2017-04-01 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/ControlGenerator.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/CancelPushGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/HeadersGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/DataGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/SettingsGenerator.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/MaxPushIdGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/MessageGenerator.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/GoAwayGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/FrameGenerator.java, 2021-02-13 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/generator/PushPromiseGenerator.java, 2012-05-08 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3StreamConnection.java, 2021-09-21 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Stream.java, 2009-03-24 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/DecoderStreamConnection.java, 2017-04-01 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/ControlFlusher.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/InstructionStreamConnection.java, 2017-04-01 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/InstructionFlusher.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/api/Stream.java, 2012-11-02 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/api/Session.java, 2012-11-02 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Session.java, 2013-07-12 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/UnidirectionalStreamConnection.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/HTTP3Configuration.java, 2021-10-13 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/HTTP3Client.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientHTTP3Session.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3StreamConnection.java, 2021-09-21 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/HTTP3ClientConnectionFactory.java, 2021-09-11 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/HTTP3SessionClient.java, 2021-09-12 -jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/HTTP3StreamClient.java, 2021-11-29 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiServerConstants.java, 2010-06-23 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyBootstrapActivator.java, 2010-06-23 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/ContextFactory.java, 2009-03-24 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/AbstractContextProvider.java, 2022-12-22 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleProvider.java, 2009-03-24 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/LibExtClassLoaderHelper.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultFileLocatorHelper.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelperFactory.java, 2012-05-14 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerClasspathContributor.java, 2009-03-24 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelperFactory.java, 2012-05-14 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/FakeURLClassLoader.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/ServerConnectorListener.java, 2017-10-05 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleFileLocatorHelper.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/DefaultBundleClassLoaderHelper.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/Util.java, 2013-05-24 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/BundleClassLoaderHelper.java, 2009-11-02 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/OSGiClassLoader.java, 2012-05-16 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/util/EventSender.java, 2012-06-06 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleWebAppProvider.java, 2012-05-14 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiUndeployer.java, 2009-03-24 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiDeployer.java, 2012-06-06 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiApp.java, 2022-12-22 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/OSGiWebappConstants.java, 2009-11-09 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/BundleContextProvider.java, 2012-05-14 -jetty-core/jetty-osgi/src/main/java/org/eclipse/jetty/osgi/JettyServerFactory.java, 2022-12-22 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java, 2013-09-03 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ResponseContentParser.java, 2013-09-03 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ServerParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/Parser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ContentParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ClientParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/BeginRequestContentParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/StreamContentParser.java, 2013-09-02 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/EndRequestContentParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/ParamsContentParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/parser/HeaderParser.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java, 2013-09-08 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java, 2013-09-03 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpReceiverOverFCGI.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpSenderOverFCGI.java, 2013-09-06 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpConnectionOverFCGI.java, 2013-09-06 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpChannelOverFCGI.java, 2013-09-08 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/HttpClientTransportOverFCGI.java, 2013-09-06 -jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/FCGI.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-proxy/src/test/java/org/eclipse/jetty/fcgi/proxy/FastCGIProxyHandlerTest.java, 2014-05-06 -jetty-core/jetty-fcgi/jetty-fcgi-proxy/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-fcgi/jetty-fcgi-proxy/src/main/java/org/eclipse/jetty/fcgi/proxy/FastCGIProxyHandler.java, 2022-10-18 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/ExternalFastCGIServerTest.java, 2013-10-18 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java, 2013-09-06 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java, 2013-09-06 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java, 2022-05-03 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java, 2013-08-31 -jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/ServerFCGIConnectionFactory.java, 2013-08-31 -jetty-core/jetty-unixdomain-server/src/test/java/org/eclipse/jetty/unixdomain/server/UnixDomainTest.java, 2021-08-05 -jetty-core/jetty-unixdomain-server/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-unixdomain-server/src/main/java/org/eclipse/jetty/unixdomain/server/UnixDomainServerConnector.java, 2021-08-05 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketMappings.java, 2018-12-22 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/ServerUpgradeResponseImpl.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/ServerUpgradeRequestImpl.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/WebSocketHttpFieldsWrapper.java, 2022-05-03 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Negotiation.java, 2019-11-14 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HandshakerSelector.java, 2019-08-14 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/HttpFieldsWrapper.java, 2022-05-03 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Negotiation.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/WebSocketNegotiation.java, 2023-01-31 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC6455Handshaker.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/CreatorNegotiator.java, 2020-12-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/RFC8441Handshaker.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/internal/AbstractHandshaker.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/FrameHandlerFactory.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketServerComponents.java, 2020-05-12 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketNegotiator.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/ServerUpgradeResponse.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketUpgradeHandler.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/Handshaker.java, 2013-08-31 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/ServerUpgradeRequest.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-server/src/main/java/org/eclipse/jetty/websocket/core/server/WebSocketCreator.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/internal/HttpUpgraderOverHTTP.java, 2019-08-14 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/internal/HttpClientProvider.java, 2017-05-18 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/internal/XmlHttpClientProvider.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/internal/HttpUpgraderOverHTTP2.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/WebSocketCoreClient.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/UpgradeListener.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-client/src/main/java/org/eclipse/jetty/websocket/core/client/CoreClientUpgradeRequest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserReservedBitTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserBadCloseStatusCodesTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServer.java, 2019-02-28 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/DemandTest.java, 2021-11-09 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/FrameBufferTest.java, 2019-11-29 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/FlushTest.java, 2020-01-29 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/internal/MockEndpoint.java, 2019-02-21 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/internal/FrameFlusherTest.java, 2019-02-21 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/UpgradeWithLeftOverHttpBytesTest.java, 2020-08-31 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/CloseStatusTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/RawFrameBuilder.java, 2013-08-20 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxyTest.java, 2019-01-31 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/proxy/WebSocketProxy.java, 2019-02-13 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/server/WebSocketServerTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketFrameTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/AutoFragmentTest.java, 2019-10-22 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketUpgradeHandlerTest.java, 2020-12-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/client/WebSocketClientServerTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParsePayloadLengthTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/DemandingIncomingFramesCapture.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/TestFrameHandler.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketServerComponentsTest.java, 2021-03-26 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketNegotiationTest.java, 2019-03-21 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/Timeouts.java, 2012-05-08 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/GeneratorFrameFlagsTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/EchoFrameHandler.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketOpenTest.java, 2019-01-24 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/IncomingFramesCapture.java, 2012-06-18 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/GeneratorParserRoundTripTest.java, 2012-06-21 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/TestWebSocketNegotiator.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserTest.java, 2012-06-18 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserCapture.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/util/MessageReaderTest.java, 2020-02-17 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/util/PartialStringMessageSinkTest.java, 2020-02-20 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/util/MessageWriterTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/util/StringMessageSinkTest.java, 2020-02-20 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/GeneratorTest.java, 2012-07-18 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketTester.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/OpCodeTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketEchoTest.java, 2021-08-30 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/SynchronousFrameHandler.java, 2019-01-29 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/OutgoingFramesCapture.java, 2012-07-23 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/WebSocketCloseTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnClient.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/CoreAutobahnServer.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnTests.java, 2020-09-21 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/autobahn/AutobahnFrameHandler.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/AcceptHashTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserGoodCloseStatusCodesTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/MessageHandlerTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/TestAsyncFrameHandler.java, 2019-06-11 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/ParserBadOpCodesTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/TestMessageHandler.java, 2019-06-26 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketServer.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/chat/ChatWebSocketClient.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/OutgoingNetworkBytesCapture.java, 2012-10-04 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/ValidationExtensionTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionConfigTest.java, 2012-11-06 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionStackTest.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/PermessageDeflateDemandTest.java, 2022-01-19 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/FragmentExtensionTest.java, 2012-07-23 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflateExtensionTest.java, 2012-07-23 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/PerMessageDeflaterBufferSizeTest.java, 2019-11-19 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/IdentityExtensionTest.java, 2012-07-23 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/AbstractExtensionTest.java, 2012-07-10 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/extensions/ExtensionTool.java, 2013-12-09 -jetty-core/jetty-websocket/jetty-websocket-core-tests/src/test/java/org/eclipse/jetty/websocket/core/CapturedHexPayloads.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/module-info.java, 2018-11-22 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/OutgoingFrames.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/FrameHandler.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/DemandChain.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameSequence.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketConnection.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/Parser.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCoreSession.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/DemandingFlusher.java, 2022-01-19 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketSessionState.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/NullAppendable.java, 2012-06-25 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/TransformingFlusher.java, 2019-11-19 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/ExtensionStack.java, 2012-11-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/Generator.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/WebSocketCore.java, 2012-06-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameFlusher.java, 2013-11-21 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/PerMessageDeflateExtension.java, 2019-11-19 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentExtension.java, 2012-11-05 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/ValidationExtension.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/MessageHandler.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameEntry.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/PartialByteArrayMessageSink.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/DispatchedMessageSink.java, 2017-05-09 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/PartialStringMessageSink.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/MessageInputStream.java, 2012-08-07 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/InputStreamMessageSink.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/MessageSink.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/StringMessageSink.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/ByteBufferMessageSink.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/AbstractMessageSink.java, 2012-08-27 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/ReaderMessageSink.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/MessageReader.java, 2012-07-05 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/MessageOutputStream.java, 2012-07-05 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/ByteArrayMessageSink.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/PartialByteBufferMessageSink.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/messages/MessageWriter.java, 2012-07-05 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/util/ReflectUtils.java, 2013-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/util/TextUtils.java, 2013-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/util/InvokerUtils.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/util/FrameValidation.java, 2021-02-08 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/IdentityExtension.java, 2011-05-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/Negotiated.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FrameCaptureExtension.java, 2014-05-16 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/internal/FragmentingFlusher.java, 2019-11-26 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/ExtensionConfig.java, 2009-03-24 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/WebSocketComponents.java, 2019-01-22 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/OpCode.java, 2012-06-18 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/Frame.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/CoreSession.java, 2019-12-30 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/CloseStatus.java, 2018-11-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/Configuration.java, 2019-12-30 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/IncomingFrames.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/DuplicateAnnotationException.java, 2016-02-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/InvalidWebSocketException.java, 2012-06-27 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/MessageTooLargeException.java, 2012-07-06 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/CloseException.java, 2012-06-20 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/BadPayloadException.java, 2012-07-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketException.java, 2012-06-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/ProtocolException.java, 2012-06-29 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/InvalidSignatureException.java, 2012-09-26 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/UpgradeException.java, 2012-06-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketWriteTimeoutException.java, 2019-04-23 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/exception/WebSocketTimeoutException.java, 2012-06-12 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/Extension.java, 2012-11-05 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/WebSocketExtensionRegistry.java, 2012-05-08 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/AbstractExtension.java, 2011-05-02 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/Behavior.java, 2012-06-20 -jetty-core/jetty-websocket/jetty-websocket-core-common/src/main/java/org/eclipse/jetty/websocket/core/WebSocketConstants.java, 2018-11-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/UptimeTest.java, 2012-11-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/IntrospectionUtilTest.java, 2019-05-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingTest.java, 2022-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/SharedBlockingCallbackTest.java, 2012-10-25 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/AttributeNormalizerToCanonicalUriTest.java, 2018-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceFactoryTest.java, 2022-11-11 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/MemoryResourceTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/UrlResourceFactoryTest.java, 2022-11-14 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/PathResourceTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/AlternateFileSystemResourceTest.java, 2023-01-13 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceAliasTest.java, 2013-06-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/MountedPathResourceTest.java, 2014-06-25 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/ResourceTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/AttributeNormalizerTest.java, 2016-01-13 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/CombinedResourceTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/resource/FileSystemResourceTest.java, 2014-06-25 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/LoaderTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/test10/ExampleClass.java, 2012-11-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8LineParserTest.java, 2012-08-15 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/UrlEncodedUtf8Test.java, 2014-04-10 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiReleaseJarFileTest.java, 2017-09-20 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/DateCacheTest.java, 2005-11-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ExceptionUtilTest.java, 2022-07-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/IteratingCallbackTest.java, 2013-11-21 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/RolloverFileOutputStreamTest.java, 2017-02-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/security/PasswordTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/security/CredentialTest.java, 2015-11-26 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/FieldsTest.java, 2022-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/HostPortTest.java, 2016-08-31 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/StringUtilTest.java, 2005-11-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/LeakDetectorTest.java, 2014-01-07 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/LazyListTest.java, 2005-11-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/Utf8AppendableTest.java, 2017-10-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/QuotedStringTokenizerTest.java, 2005-11-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/URIUtilNormalizePathTest.java, 2017-04-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TypeUtilTest.java, 2012-11-11 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/SearchPatternTest.java, 2012-11-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/RegexSetTest.java, 2015-07-17 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/CharsetStringBuilderTest.java, 2022-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java, 2015-09-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/RateStatisticTest.java, 2018-06-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/statistic/SampleStatisticTest.java, 2010-02-15 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ScannerTest.java, 2011-04-01 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/QueuedThreadPoolTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AutoLockTest.java, 2015-02-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ReservedThreadExecutorTest.java, 2017-06-21 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SchedulerTest.java, 2012-08-31 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ExecutorThreadPoolTest.java, 2012-08-31 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedInvokerTest.java, 2022-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AdaptiveExecutionStrategyTest.java, 2018-04-25 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SweeperTest.java, 2015-03-20 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadFactoryTest.java, 2019-10-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/SerializedExecutorTest.java, 2019-03-20 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/AbstractThreadPoolTest.java, 2018-08-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScopeTest.java, 2015-03-10 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecutionStrategyTest.java, 2017-04-01 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsumeTest.java, 2015-02-18 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ArrayUtilTest.java, 2019-05-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/URLEncodedTest.java, 2005-11-27 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/IndexTest.java, 2020-11-23 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/JavaVersionTest.java, 2018-01-04 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ProcessorUtilsTest.java, 2012-11-02 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TestIntrospectionUtil.java, 2006-12-29 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ConcurrentPoolTest.java, 2020-06-10 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/DumpableTest.java, 2010-01-26 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleTest.java, 2012-09-21 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/LifeCycleListenerNestedTest.java, 2015-02-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/ContainerLifeCycleListenerTest.java, 2015-02-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/component/ClassLoaderDumpTest.java, 2017-03-23 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/BlockingArrayQueueTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/FileIDTest.java, 2022-07-29 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/IncludeExcludeTest.java, 2015-07-17 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/MultiMapTest.java, 2011-08-05 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TopologicalSortTest.java, 2015-06-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/InetAddressSetTest.java, 2016-09-01 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/BufferUtilTest.java, 2009-03-24 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/AtomicBiIntegerTest.java, 2018-03-07 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/AttributesTest.java, 2022-05-03 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/TrieTest.java, 2012-12-07 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/IncludeExcludeSetTest.java, 2016-09-01 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java, 2011-10-19 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509Test.java, 2017-05-15 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/X509CertificateAdapter.java, 2017-05-15 -jetty-core/jetty-util/src/test/java/org/eclipse/jetty/util/FutureCallbackTest.java, 2012-05-09 -jetty-core/jetty-util/src/main/java/module-info.java, 2018-11-22 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/compression/DeflaterPool.java, 2019-04-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/compression/CompressionPool.java, 2019-06-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/compression/InflaterPool.java, 2019-04-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/LazyList.java, 2001-09-17 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/SearchPattern.java, 2018-03-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ServiceLoaderSpliterator.java, 2020-03-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Promise.java, 2012-05-08 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/FutureCallback.java, 2012-05-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayUtil.java, 2012-08-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Jetty.java, 2009-06-11 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceFactoryInternals.java, 2022-08-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceFactory.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResourceFactory.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/MountedPathResourceFactory.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/GraalIssue5720PathResource.java, 2023-01-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/CombinedResource.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resource.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/FileSystemPool.java, 2022-07-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/URLResourceFactory.java, 2022-11-14 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceUriPatternPredicate.java, 2022-08-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/AttributeNormalizer.java, 2016-01-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/Resources.java, 2022-10-19 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/ResourceCollators.java, 2019-04-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/GraalIssue5720PathResourceFactory.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/MountedPathResource.java, 2022-07-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathResource.java, 2014-06-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/MemoryResource.java, 2022-08-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/resource/PathCollators.java, 2019-04-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java, 2002-06-05 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/HostMap.java, 2010-06-16 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiMap.java, 1999-10-11 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/FuturePromise.java, 2012-05-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/NanoTime.java, 2022-09-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TreeTrie.java, 2013-01-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/BufferUtil.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Uptime.java, 2014-09-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Atomics.java, 2012-06-08 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConcurrentPool.java, 2023-01-30 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/AbstractTrie.java, 2013-03-28 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartOutputStream.java, 2005-11-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/DecoratedObjectFactory.java, 2014-11-11 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/StringUtil.java, 1995-12-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Loader.java, 2002-03-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/UnixCrypt.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/CertificateUtils.java, 2011-03-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/CertificateValidator.java, 2011-02-08 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Password.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/Constraint.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/CredentialProvider.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/SharedBlockingCallback.java, 2012-10-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java, 2006-10-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IncludeExclude.java, 2015-07-17 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/LeakDetector.java, 2014-01-07 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Attachable.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ByteArrayOutputStream2.java, 2001-08-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingNestedCallback.java, 2013-05-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/AttributesMap.java, 2005-11-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Index.java, 2020-11-23 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ClassLoadingObjectInputStream.java, 2013-03-28 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/AtomicBiInteger.java, 2018-03-07 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressSet.java, 2016-09-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ByteArrayISO8859Writer.java, 2001-08-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IteratingCallback.java, 2013-05-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Fields.java, 2012-05-05 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/StaticException.java, 2022-06-13 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/CountingCallback.java, 2015-02-05 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/HostPort.java, 2016-08-31 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/BlockingArrayQueue.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/AsciiLowerCaseSet.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/LockedPool.java, 2023-01-30 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiPartWriter.java, 2005-11-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IntrospectionUtil.java, 2006-12-29 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/CounterStatistic.java, 2010-02-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java, 2020-12-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateStatistic.java, 2018-06-19 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/package-info.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/SampleStatistic.java, 2010-02-15 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Attributes.java, 2000-06-14 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UrlEncoded.java, 1995-12-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/AutoLock.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutionStrategy.java, 2014-07-30 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPool.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ScheduledExecutorScheduler.java, 2013-01-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ShutdownThread.java, 2009-12-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadPoolBudget.java, 2017-09-28 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/QueuedThreadPool.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Scheduler.java, 2012-08-31 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ExecutorThreadPool.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ReservedThreadExecutor.java, 2017-06-21 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedInvoker.java, 2022-05-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/MonitoredQueuedThreadPool.java, 2018-03-07 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Invocable.java, 2016-06-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/TryExecutor.java, 2018-02-08 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/Sweeper.java, 2015-03-20 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/ThreadClassLoaderScope.java, 2012-06-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/EatWhatYouKill.java, 2017-04-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ExecuteProduceConsume.java, 2015-02-18 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceConsume.java, 2012-06-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/AdaptiveExecutionStrategy.java, 2021-06-16 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/strategy/ProduceExecuteConsume.java, 2015-02-18 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/TimerScheduler.java, 2012-08-31 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/PrivilegedThreadFactory.java, 2021-02-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/thread/SerializedExecutor.java, 2019-03-20 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IO.java, 1995-12-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/QuotedStringTokenizer.java, 1999-09-29 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MemoryUtils.java, 2013-03-07 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8LineParser.java, 2012-08-15 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8StringBuilder.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/UriPatternPredicate.java, 2022-08-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Callback.java, 2012-05-08 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/VirtualThreads.java, 2022-08-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MultiReleaseJarFile.java, 2017-09-19 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/HaltLifeCycleListener.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/LifeCycle.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileDestroyable.java, 2011-01-06 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Dumpable.java, 2010-12-21 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/AbstractLifeCycle.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/FileNoticeLifeCycleListener.java, 2013-03-14 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Graceful.java, 2012-08-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java, 2010-12-21 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Destroyable.java, 2010-12-21 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/DumpableCollection.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/ClassLoaderDump.java, 2012-09-21 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Container.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/StopLifeCycle.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/AttributeContainerMap.java, 2019-06-18 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/TopologicalSort.java, 2015-06-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/DateCache.java, 1999-03-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/IncludeExcludeSet.java, 2015-07-17 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTernaryTrie.java, 2013-01-14 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/SocketAddressResolver.java, 2013-02-14 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8Appendable.java, 2011-05-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/EmptyTrie.java, 2020-11-23 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/annotation/ManagedOperation.java, 2009-07-22 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/annotation/ManagedAttribute.java, 2012-07-20 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/annotation/Name.java, 2009-07-22 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/annotation/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/annotation/ManagedObject.java, 2012-07-23 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/MathUtils.java, 2011-09-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/CharsetStringBuilder.java, 2022-05-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ManifestUtils.java, 2012-06-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ConstantThrowable.java, 2011-09-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/FileID.java, 2022-07-29 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/InetAddressPattern.java, 2016-09-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ClassVisibilityChecker.java, 2019-04-29 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/DeprecationWarning.java, 2015-12-01 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java, 2017-01-12 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ExceptionUtil.java, 2022-07-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/preventers/AppContextLeakPreventer.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/preventers/DriverManagerLeakPreventer.java, 2009-03-24 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/preventers/AWTLeakPreventer.java, 2012-08-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/preventers/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/preventers/AbstractLeakPreventer.java, 2012-08-09 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ProcessorUtils.java, 2012-06-25 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/RolloverFileOutputStream.java, 2002-01-17 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/RegexSet.java, 2015-07-17 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Blocker.java, 2022-05-03 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Decorator.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SniX509ExtendedKeyManager.java, 2015-04-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/AliasedX509ExtendedKeyManager.java, 2011-02-16 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/X509.java, 2015-08-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/KeyStoreScanner.java, 2020-07-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/package-info.java, 2012-11-02 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java, 2011-02-16 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslSelectionDump.java, 2016-11-22 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/URIUtil.java, 2005-11-27 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ArrayTrie.java, 2012-12-07 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Pool.java, 2020-06-10 -jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/Utf8StringBuffer.java, 2006-03-09 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRuleTest.java, 2015-07-22 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/PatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewritePatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RegexRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CompactPathRuleTest.java, 2022-12-20 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteHandlerTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRuleTest.java, 2014-12-04 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainerTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRuleTest.java, 2009-07-08 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRuleTest.java, 2015-07-22 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/CookiePatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRuleTest.java, 2009-03-24 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/AbstractRuleTest.java, 2022-05-03 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRuleTest.java, 2021-02-16 -jetty-core/jetty-rewrite/src/test/java/org/eclipse/jetty/rewrite/handler/InvalidURIRuleTest.java, 2022-05-03 -jetty-core/jetty-rewrite/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingPatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/VirtualHostRuleContainer.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteHandler.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/PatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForwardedSchemeHeaderRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ForceRequestHeaderValueRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RegexRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/InvalidURIRule.java, 2022-05-03 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewritePatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CookiePatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/Rule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/ResponsePatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/package-info.java, 2012-11-02 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderRegexRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectPatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RewriteRegexRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RuleContainer.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/CompactPathRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/TerminatingRegexRule.java, 2011-12-14 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/HeaderPatternRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/handler/RedirectRegexRule.java, 2009-03-24 -jetty-core/jetty-rewrite/src/main/java/org/eclipse/jetty/rewrite/RewriteCustomizer.java, 2012-06-25 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/PojoTest.java, 2016-03-10 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerTest.java, 2016-03-10 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanUtilTest.java, 2016-03-10 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ConnectorServerTest.java, 2009-06-11 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/ObjectMBeanTest.java, 2009-03-24 -jetty-core/jetty-jmx/src/test/java/org/eclipse/jetty/jmx/MBeanContainerLifeCycleTest.java, 2016-03-10 -jetty-core/jetty-jmx/src/test/java/com/acme/Derived.java, 2005-11-27 -jetty-core/jetty-jmx/src/test/java/com/acme/DerivedManaged.java, 2016-03-10 -jetty-core/jetty-jmx/src/test/java/com/acme/jmx/ManagedMBean.java, 2012-07-23 -jetty-core/jetty-jmx/src/test/java/com/acme/jmx/DerivedMBean.java, 2012-07-23 -jetty-core/jetty-jmx/src/test/java/com/acme/Managed.java, 2012-08-03 -jetty-core/jetty-jmx/src/test/java/com/acme/SuperManaged.java, 2009-03-24 -jetty-core/jetty-jmx/src/test/java/com/acme/DerivedExtended.java, 2012-07-23 -jetty-core/jetty-jmx/src/test/java/com/acme/Base.java, 2000-09-13 -jetty-core/jetty-jmx/src/test/java/com/acme/Signature.java, 2005-11-27 -jetty-core/jetty-jmx/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java, 2009-03-24 -jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MetaData.java, 2018-09-20 -jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ConnectorServer.java, 2009-12-10 -jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/package-info.java, 2012-11-02 -jetty-core/jetty-jmx/src/main/java/org/eclipse/jetty/jmx/ObjectMBean.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectionOpenCloseTest.java, 2012-09-19 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConfigurationAuthorityOverrideTest.java, 2022-01-06 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/RequestLogTest.java, 2021-12-28 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HostHeaderCustomizerTest.java, 2013-06-10 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpCookieTest.java, 2019-05-16 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/LocalConnectorTest.java, 2012-05-23 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/InsufficientThreadsDetectionTest.java, 2016-10-20 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MockConnector.java, 2013-07-05 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyConnectionTest.java, 2014-11-13 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyProtocolTest.java, 2016-11-25 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/SlowClientWithPipelinedRequestTest.java, 2012-02-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/AbstractHttpTest.java, 2012-08-17 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorCloseTestBase.java, 2011-07-06 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MockHttpStream.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorAcceptTest.java, 2021-05-20 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTest.java, 2014-07-15 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpConnectionTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/CookieCacheTest.java, 2022-05-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/OptionalSslConnectionTest.java, 2019-01-31 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ConnectorTimeoutTest.java, 2010-07-13 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/jmh/HandlerBenchmark.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MultiPartByteRangesTest.java, 2022-08-05 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/NotAcceptingTest.java, 2017-08-12 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpChannelTest.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/StopTest.java, 2013-10-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyCustomizerTest.java, 2020-05-07 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorTimeoutTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ExtendedServerTest.java, 2013-11-07 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HalfCloseTest.java, 2013-11-04 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ShutdownMonitorTest.java, 2013-03-18 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/DelayedServerTest.java, 2019-11-13 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/CustomRequestLogTest.java, 2018-11-06 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorHttpServerTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/MockConnectionMetaData.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ThreadStarvationTest.java, 2015-07-01 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ServerConnectorCloseTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/HandlerTest.java, 2016-02-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DefaultHandlerTest.java, 2018-06-21 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerGetResourceTest.java, 2013-08-23 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ThreadLimitHandlerTest.java, 2016-09-08 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/BufferedResponseHandlerTest.java, 2016-07-28 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/HelloHandler.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/gzip/GzipHandlerTest.java, 2011-06-20 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/TryPathsHandlerTest.java, 2022-10-18 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DelayedHandlerTest.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ShutdownHandlerTest.java, 2011-09-30 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/FileBufferedResponseHandlerTest.java, 2021-04-19 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ResourceHandlerByteRangesTest.java, 2022-08-05 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerCodeTest.java, 2022-01-27 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/AllowAllVerifier.java, 2012-11-02 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/AllowSymLinkAliasCheckerTest.java, 2016-07-07 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/MultiPartFormDataHandlerTest.java, 2022-08-04 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/InetAccessHandlerTest.java, 2019-04-18 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/NcsaRequestLogTest.java, 2014-10-31 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/SecuredRedirectHandlerTest.java, 2014-09-30 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ResourceHandlerTest.java, 2011-09-28 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DumpHandler.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/PathMappingsHandlerTest.java, 2022-10-25 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerDeepTest.java, 2022-10-20 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/EchoHandler.java, 2022-05-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/StatisticsHandlerTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/DebugHandlerTest.java, 2015-09-30 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/MovedContextHandlerTest.java, 2022-11-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/handler/ContextHandlerCollectionTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/LargeHeaderTest.java, 2020-06-03 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/RequestTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ResourceListingTest.java, 2022-09-27 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/LatencyRecordingHandlerTest.java, 2023-01-19 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/GracefulHandlerTest.java, 2023-01-23 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ErrorHandlerTest.java, 2016-07-18 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java, 2010-07-13 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestBase.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ForwardedRequestCustomizerTest.java, 2016-08-11 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/CustomResourcesMonitorTest.java, 2018-08-23 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/HttpChannelEventTest.java, 2017-09-08 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/DetectorConnectionTest.java, 2020-01-23 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/PartialRFC2616Test.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslUploadTest.java, 2009-09-12 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/ServerConnectorSslServerTest.java, 2010-07-14 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLSelectChannelConnectorLoadTest.java, 2010-10-01 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SlowClientsTest.java, 2017-03-06 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/ServerConnectorSslTimeoutTest.java, 2010-07-14 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslContextFactoryReloadTest.java, 2016-09-30 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLCloseTest.java, 2011-09-27 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLEngineTest.java, 2009-03-24 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SniSslConnectionFactoryTest.java, 2015-04-02 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SslConnectionFactoryTest.java, 2015-04-02 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SSLReadEOFAfterResponseTest.java, 2018-11-20 -jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/LowResourcesMonitorTest.java, 2013-02-18 -jetty-core/jetty-server/src/main/java/module-info.java, 2012-09-13 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HostHeaderCustomizer.java, 2013-06-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Context.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java, 2010-03-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractNetworkConnector.java, 2012-07-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnectionFactory.java, 2012-09-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractHandlerMBean.java, 2009-06-30 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/package-info.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/AbstractConnectorMBean.java, 2012-09-21 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/jmx/ServerMBean.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLogWriter.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AcceptRateLimit.java, 2018-06-19 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceService.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/ResponseHttpFields.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/MultiPartParser.java, 2018-03-08 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/HttpChannelState.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/internal/HttpConnection.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelListeners.java, 2019-08-27 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HandlerContainer.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionMetaData.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AllowedResourceAliasChecker.java, 2021-09-21 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/DetectorConnectionFactory.java, 2020-01-23 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConfiguration.java, 2012-09-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnectionFactory.java, 2014-03-18 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/SocketCustomizationListener.java, 2015-04-30 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ServerConnector.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpCookieUtils.java, 2023-02-07 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyConnectionFactory.java, 2014-11-13 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkTrafficServerConnector.java, 2011-02-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Components.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/SymlinkAllowedResourceAliasChecker.java, 2021-09-21 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AbstractConnector.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionFactory.java, 2012-08-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ConnectionLimit.java, 2017-09-05 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/FormFields.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Slf4jRequestLogWriter.java, 2018-11-19 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/SslConnectionFactory.java, 2012-09-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/TunnelSupport.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/package-info.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/LowResourceMonitor.java, 2013-02-18 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/CustomRequestLog.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HomeBaseWarning.java, 2014-10-29 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Handler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ForwardedRequestCustomizer.java, 2012-09-10 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceListing.java, 2022-08-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DelayedHandler.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/GracefulHandler.java, 2023-01-23 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ReHandlingErrorHandler.java, 2022-10-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/ContextHandlerMBean.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/AbstractHandlerMBean.java, 2009-06-30 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/jmx/package-info.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/BufferedResponseHandler.java, 2016-07-28 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DebugHandler.java, 2009-07-28 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ConnectHandler.java, 2012-07-20 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/HeaderWrappingRequest.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipFactory.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/package-info.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipResponseAndCallback.java, 2013-12-06 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/gzip/GzipRequest.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/PathMappingsHandler.java, 2022-10-25 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessHandler.java, 2016-09-01 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ResourceHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ShutdownHandler.java, 2011-09-30 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/InetAccessSet.java, 2020-02-27 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractLatencyRecordingHandler.java, 2023-01-19 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/AbstractHandlerContainer.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/FileBufferedResponseHandler.java, 2021-04-19 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ManagedAttributeListener.java, 2015-06-19 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextRequest.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/TryPathsHandler.java, 2022-10-18 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/HotSwapHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/MovedContextHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ThreadLimitHandler.java, 2016-09-08 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/DefaultHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ProxiedRequestHandler.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandlerCollection.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/package-info.java, 2012-11-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextResponse.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java, 2022-05-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/IdleTimeoutHandler.java, 2013-11-08 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/StatisticsHandler.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/handler/SecuredRedirectHandler.java, 2014-09-30 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Connector.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ClassLoaderDump.java, 2012-09-21 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/RequestLog.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/NetworkConnector.java, 2012-08-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpConnectionFactory.java, 2012-08-03 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AliasCheck.java, 2022-08-11 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Response.java, 2009-03-24 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncRequestLogWriter.java, 2013-03-18 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ProxyCustomizer.java, 2020-05-07 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ShutdownMonitor.java, 2012-12-04 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java, 1995-12-01 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/NegotiatingServerConnection.java, 2012-07-27 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/LocalConnector.java, 2012-05-14 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/OptionalSslConnectionFactory.java, 2019-01-31 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Session.java, 2023-02-02 -jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/HttpStream.java, 2022-05-03 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/LoggingUtil.java, 2010-01-26 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/SPIServerTest.java, 2017-11-15 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/TestSPIServer.java, 2011-12-22 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/PrintTask.java, 2009-03-24 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/SpiConstants.java, 2016-05-04 -jetty-core/jetty-http-spi/src/test/java/org/eclipse/jetty/http/spi/util/Pool.java, 2011-09-12 -jetty-core/jetty-http-spi/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpsExchange.java, 2011-12-12 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyExchange.java, 2009-03-24 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServerProvider.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpContext.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpServer.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/HttpSpiContextHandler.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchange.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/JettyHttpExchangeDelegate.java, 2011-10-07 -jetty-core/jetty-http-spi/src/main/java/org/eclipse/jetty/http/spi/DelegatingThreadPool.java, 2013-07-26 -jetty-core/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ReverseProxyTest.java, 2022-08-19 -jetty-core/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/InterimResponseProxyTest.java, 2022-09-26 -jetty-core/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/ForwardProxyWithDynamicTransportTest.java, 2019-08-13 -jetty-core/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/AbstractProxyTest.java, 2022-08-19 -jetty-core/jetty-proxy/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-proxy/src/main/java/org/eclipse/jetty/proxy/ProxyHandler.java, 2022-08-19 -jetty-core/jetty-http-tools/src/test/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchersTest.java, 2018-09-04 -jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsHeaderValue.java, 2018-09-04 -jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderValue.java, 2018-09-04 -jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsMatchers.java, 2018-09-04 -jetty-core/jetty-http-tools/src/main/java/org/eclipse/jetty/http/tools/matchers/HttpFieldsContainsHeaderKey.java, 2018-09-04 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackContextTest.java, 2014-06-08 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackDecoderTest.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HuffmanTest.java, 2014-06-02 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackTest.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackEncoderTest.java, 2014-06-08 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/HpackPerfTest.java, 2014-07-16 -jetty-core/jetty-http2/jetty-http2-hpack/src/test/java/org/eclipse/jetty/http2/hpack/NBitIntegerTest.java, 2014-06-02 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/internal/AuthorityHttpField.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/internal/StaticTableHttpField.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/internal/MetaDataBuilder.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/internal/Huffman.java, 2014-06-02 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/internal/NBitInteger.java, 2014-06-02 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackDecoder.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackEncoder.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackFieldPreEncoder.java, 2014-08-06 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackContext.java, 2014-06-08 -jetty-core/jetty-http2/jetty-http2-hpack/src/main/java/org/eclipse/jetty/http2/hpack/HpackException.java, 2012-06-25 -jetty-core/jetty-http2/jetty-http2-client/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/internal/HTTP2ClientSession.java, 2014-06-11 -jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java, 2014-06-11 -jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java, 2014-08-01 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MultiplexedConnectionPoolTest.java, 2020-12-11 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BufferingFlowControlStrategyTest.java, 2015-02-06 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTunnelTest.java, 2019-08-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ReverseProxyTest.java, 2022-10-07 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java, 2016-12-08 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GoAwayTest.java, 2020-11-10 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorKnowledgeHTTP2OverTLSTest.java, 2016-03-18 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BlockedWritesWithSmallThreadPoolTest.java, 2021-08-26 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java, 2012-03-22 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ProxyProtocolTest.java, 2015-08-11 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConnectTimeoutTest.java, 2015-02-09 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SmallThreadPoolLoadTest.java, 2016-05-10 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxConcurrentStreamsTest.java, 2015-12-11 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PushedResourcesTest.java, 2017-03-05 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/TrailersTest.java, 2016-12-08 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java, 2014-06-24 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/IdleTimeoutTest.java, 2014-06-18 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ConcurrentStreamCreationTest.java, 2020-04-23 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/GracefulShutdownTest.java, 2022-11-07 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java, 2014-06-12 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java, 2014-08-05 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java, 2014-08-20 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PingTest.java, 2014-06-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PriorityTest.java, 2015-09-14 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncIOTest.java, 2015-04-15 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AsyncServletTest.java, 2016-08-12 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/MaxPushedStreamsTest.java, 2018-07-18 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCloseTest.java, 2015-02-06 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java, 2015-09-29 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java, 2014-06-11 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServer.java, 2015-02-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RequestTrailersTest.java, 2019-06-12 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlWindowsTest.java, 2018-05-18 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ContentLengthTest.java, 2020-04-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java, 2015-02-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java, 2015-09-20 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SessionFailureTest.java, 2015-02-13 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/H2SpecServer.java, 2009-03-30 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/ResponseTrailerTest.java, 2019-07-11 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java, 2019-08-23 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/SimpleFlowControlStrategyTest.java, 2015-02-06 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStalledTest.java, 2015-12-23 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BadURITest.java, 2022-12-20 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java, 2016-02-29 -jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractTest.java, 2014-06-12 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/module-info.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java, 2022-05-03 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/ServerHTTP2StreamEndPoint.java, 2019-08-13 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HTTP2ServerConnection.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HTTP2ServerSession.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java, 2014-06-12 -jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/RawHTTP2ServerConnectionFactory.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HTTPSessionListenerPromise.java, 2019-01-17 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpChannelOverHTTP2.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpSenderOverHTTP2.java, 2015-02-05 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/ClientHTTP2StreamEndPoint.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpConnectionOverHTTP2.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpReceiverOverHTTP2.java, 2015-02-05 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/HttpClientTransportOverHTTP2.java, 2013-07-12 -jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/ClientConnectionFactoryOverHTTP2.java, 2019-01-17 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java, 2018-07-03 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java, 2018-07-03 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java, 2014-06-16 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java, 2014-06-06 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersTooLargeParseTest.java, 2022-01-19 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java, 2019-08-17 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DisconnectFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/SettingsFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/HeadersFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/PingFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/WindowUpdateFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/Frame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/ContinuationFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/FailureFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/GoAwayFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/PushPromiseFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/StreamFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/FrameType.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/UnknownFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/PriorityFrame.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/ResetFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/PrefaceFrame.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/CloseState.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/FlowControlStrategy.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Session.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/Flags.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java, 2014-08-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/UnknownBodyParser.java, 2012-06-20 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/WindowUpdateBodyParser.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/ServerParser.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/PushPromiseBodyParser.java, 2014-06-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/PriorityBodyParser.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/GoAwayBodyParser.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/Parser.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/PrefaceParser.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeadersBodyParser.java, 2014-06-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/ResetBodyParser.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/SettingsBodyParser.java, 2014-06-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockFragments.java, 2015-07-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/DataBodyParser.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderBlockParser.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/ContinuationBodyParser.java, 2012-08-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/PingBodyParser.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/BodyParser.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/parser/HeaderParser.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/ResetGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/PingGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/Generator.java, 2014-06-05 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeaderGenerator.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/PriorityGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/HeadersGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/DataGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/SettingsGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/NoOpGenerator.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/WindowUpdateGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/GoAwayGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/PrefaceGenerator.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/FrameGenerator.java, 2014-06-10 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/generator/PushPromiseGenerator.java, 2014-06-16 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/AbstractFlowControlStrategy.java, 2012-08-27 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Connection.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/BufferingFlowControlStrategy.java, 2015-02-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/SimpleFlowControlStrategy.java, 2015-02-06 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/RateControl.java, 2009-03-24 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java, 2012-05-08 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2StreamEndPoint.java, 2019-08-13 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/WindowRateControl.java, 2019-08-17 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/server/ServerSessionListener.java, 2012-07-09 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java, 2011-03-31 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Session.java, 2014-06-09 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Cipher.java, 2014-12-04 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Stream.java, 2011-08-11 -jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/HTTP2Channel.java, 2019-08-13 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterTest.java, 2017-05-12 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedCSVTest.java, 2016-03-30 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/DateParserTest.java, 2010-01-26 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/EtagUtilsTest.java, 2022-09-21 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorClientTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/SyntaxTest.java, 2017-03-16 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java, 2012-09-18 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartCaptureTest.java, 2018-03-21 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpTesterTest.java, 2016-05-30 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldsTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/CookieCutterLenientTest.java, 2017-05-12 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpParserTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpCookieStoreTest.java, 2023-02-07 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java, 2016-03-30 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerHTTPTest.java, 2014-01-28 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpFieldTest.java, 2014-06-17 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartFormDataTest.java, 2022-08-04 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpURITest.java, 2011-08-25 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpStatusCodeTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpGeneratorServerTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/MimeTypesTest.java, 2011-08-12 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/ByteRangeTest.java, 2009-07-08 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/HttpSchemeTest.java, 2019-05-16 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/MultiPartTest.java, 2022-08-04 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecTest.java, 2013-04-09 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecMatchListTest.java, 2015-12-14 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecOrderTest.java, 2015-12-14 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/RegexPathSpecTest.java, 2009-03-24 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java, 2015-12-14 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/WebSocketUriMappingTest.java, 2020-04-16 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpecBadSpecsTest.java, 2013-04-09 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathSpecAssert.java, 2013-02-19 -jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/ServletPathSpecTest.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/module-info.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookie.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java, 2013-10-17 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpField.java, 2012-12-07 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/BadMessageException.java, 2012-05-08 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCache.java, 2017-07-19 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartByteRanges.java, 2022-08-05 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CompressedContentFormat.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MetaData.java, 2014-06-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java, 1999-09-29 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/ComplianceViolation.java, 2012-05-08 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Trailers.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpParser.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Syntax.java, 2017-03-16 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeader.java, 1995-12-01 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http11FieldPreEncoder.java, 2012-11-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/DateParser.java, 2013-10-17 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http1FieldPreEncoder.java, 2014-08-06 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/EtagUtils.java, 2022-09-21 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java, 2016-03-30 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/UriCompliance.java, 2021-03-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ResourceHttpContentFactory.java, 2015-09-17 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/HttpContent.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/FileMappingHttpContentFactory.java, 2022-10-11 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/PreCompressedHttpContent.java, 2015-09-17 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java, 2022-10-17 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/VirtualHttpContentFactory.java, 2022-12-13 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/CachingHttpContentFactory.java, 2022-05-03 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/PreCompressedHttpContentFactory.java, 2022-10-13 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ResourceHttpContent.java, 2014-11-06 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPart.java, 2022-08-04 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTokens.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HostPortHttpField.java, 2014-06-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MimeTypes.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/Http10FieldPreEncoder.java, 2012-11-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/package-info.java, 2012-11-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpScheme.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFieldPreEncoder.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java, 2016-03-30 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpHeaderValue.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpMethod.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCompliance.java, 2012-11-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCutter.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java, 2014-08-06 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpVersion.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/ByteRange.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpCookieStore.java, 2023-02-07 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/CookieCompliance.java, 2012-11-02 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java, 2016-10-05 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpStatus.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecSet.java, 2015-12-14 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/AbstractPathSpec.java, 2009-12-04 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedResource.java, 2022-06-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/UriTemplatePathSpec.java, 2009-03-24 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpec.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MatchedPath.java, 2022-06-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathSpecGroup.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/RegexPathSpec.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java, 2013-04-09 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/MappedResource.java, 2011-09-12 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/MultiPartFormData.java, 2022-08-04 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java, 2016-03-30 -jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpTester.java, 2012-07-13 -jetty-ee10/jetty-ee10-glassfish-jstl/src/test/java/org/eclipse/jetty/ee10/jstl/JspConfig.java, 2015-06-29 -jetty-ee10/jetty-ee10-glassfish-jstl/src/test/java/org/eclipse/jetty/ee10/jstl/JstlTest.java, 2015-06-29 -jetty-ee10/jetty-ee10-glassfish-jstl/src/test/java/org/eclipse/jetty/ee10/jstl/JspIncludeTest.java, 2015-06-29 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestJettyStopMojo.java, 2022-02-21 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestSelectiveJarResource.java, 2019-10-02 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/MockShutdownMonitor.java, 2022-02-21 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestJettyEmbedder.java, 2019-09-25 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestWebAppPropertyConverter.java, 2019-09-30 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/it/IntegrationTestGetContent.java, 2018-06-05 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/MockShutdownMonitorRunnable.java, 2022-02-21 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestQuickStartGenerator.java, 2019-09-30 -jetty-ee10/jetty-ee10-maven-plugin/src/test/java/org/eclipse/jetty/ee10/maven/plugin/TestForkedChild.java, 2019-10-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/common/src/main/java/mca/common/CommonService.java, 2012-11-02 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-impl/src/main/java/mca/module/ModuleImpl.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/module/module-api/src/main/java/mca/module/ModuleApi.java, 2012-11-02 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-multi-module-single-war-it/webapp-war/src/main/java/mca/webapp/WebAppServletListener.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-war-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-cdi-start-forked/src/main/java/test/Greeter.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-war-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_war_exploded_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_distro_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/HelloServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/Counter.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_mojo_it/PingServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/HelloServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/Counter.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-forked-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_start_forked/PingServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-effective-web-xml-it/webapp-war/src/main/java/WebAppServletListener.java, 2022-11-21 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-effective-web-xml-it/resources/src/main/java/Placeholder.java, 2022-11-21 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyWebApp/src/main/java/jettyissue/NormalClass.java, 2012-11-02 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyAnnotation.java, 2012-11-02 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-run-mojo-jar-scan-it/MyLibrary/src/main/java/jettyissue/MyServletContainerInitializer.java, 2012-07-10 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingResponse.java, 2011-03-29 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/FieldVerifier.java, 2018-05-05 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingServiceAsync.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-shared/src/main/java/org/olamy/GreetingService.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-server/src/main/java/org/olamy/GreetingServiceImpl.java, 2012-07-27 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-start-gwt-it/beer-client/src/main/java/org/olamy/App.java, 2018-05-05 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/web/src/main/java/test/ClassLoadingTestingServletContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/it/jetty-maven-plugin-provided-module-dep/api/src/main/java/test/Api.java, 2012-11-02 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/WarPluginInfo.java, 2012-11-19 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/QuickStartGenerator.java, 2019-09-17 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ScanTargetPattern.java, 2012-08-28 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/AbstractForker.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ServerSupport.java, 2012-08-28 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/Overlay.java, 2011-09-12 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/WebAppPropertyConverter.java, 2017-08-10 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyHomeForker.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyStartWarMojo.java, 2019-09-17 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/SelectiveJarResource.java, 2012-11-19 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/PluginLog.java, 2012-07-09 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/OverlayConfig.java, 2012-11-19 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyRunWarMojo.java, 2019-07-11 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ServerConnectorListener.java, 2017-10-05 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyRunMojo.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyEffectiveWebXml.java, 2011-03-29 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ServerListener.java, 2017-08-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ScanPattern.java, 2012-07-09 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyStopMojo.java, 2012-08-28 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyEmbedder.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyForker.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyStartMojo.java, 2019-07-11 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/utils/MavenProjectHelper.java, 2019-05-30 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/OverlayManager.java, 2019-10-02 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/MavenQuickStartConfiguration.java, 2014-07-09 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/MavenWebInfConfiguration.java, 2012-08-28 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/AbstractUnassembledWebAppMojo.java, 2019-11-06 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/AbstractWebAppMojo.java, 2019-05-15 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/MavenServerConnector.java, 2012-07-09 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/MavenMetaInfConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/MavenWebAppContext.java, 2012-08-28 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/ConsoleReader.java, 2019-07-13 -jetty-ee10/jetty-ee10-maven-plugin/src/main/java/org/eclipse/jetty/ee10/maven/plugin/JettyForkedChild.java, 2019-05-15 -jetty-ee10/jetty-ee10-cdi/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-cdi/src/main/java/org/eclipse/jetty/ee10/cdi/CdiDecoratingListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-cdi/src/main/java/org/eclipse/jetty/ee10/cdi/CdiConfiguration.java, 2020-12-10 -jetty-ee10/jetty-ee10-cdi/src/main/java/org/eclipse/jetty/ee10/cdi/CdiSpiDecorator.java, 2019-08-08 -jetty-ee10/jetty-ee10-cdi/src/main/java/org/eclipse/jetty/ee10/cdi/CdiServletContainerInitializer.java, 2019-08-08 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-server/src/main/java/com/acme/osgi/Activator.java, 2009-11-09 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationParser.java, 2011-07-07 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/annotations/AnnotationConfiguration.java, 2011-07-07 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/PackageAdminServiceTracker.java, 2009-11-09 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/EE10Activator.java, 2022-12-22 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiMetaInfConfiguration.java, 2012-05-14 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot/src/main/java/org/eclipse/jetty/ee10/osgi/boot/OSGiWebappClassLoader.java, 2009-12-11 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi-webapp-resources/src/main/java/com/acme/HelloWorld.java, 2005-11-27 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java, 2013-02-21 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWithJsp.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiClasspathResources.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWithWebSocket.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiAnnotationParser.java, 2020-07-07 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/SimpleJakartaWebSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWithAnnotations.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootHTTP2JDK9.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/SomeCustomBean.java, 2009-03-24 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootHTTP2Conscrypt.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/SimpleEchoSocket.java, 2012-06-27 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestJettyOSGiBootWithJakartaWebSocket.java, 2012-10-06 -jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/resources/module-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/FragmentActivator.java, 2009-03-24 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-jsp/src/main/java/org/eclipse/jetty/ee10/osgi/boot/jsp/TLDServerClasspathContributor.java, 2022-12-22 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee10/osgi/boot/warurl/internal/WarURLConnection.java, 2009-11-09 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee10/osgi/boot/warurl/internal/WarBundleManifestGenerator.java, 2009-11-09 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee10/osgi/boot/warurl/WarUrlStreamHandler.java, 2009-11-09 -jetty-ee10/jetty-ee10-osgi/jetty-ee10-osgi-boot-warurl/src/main/java/org/eclipse/jetty/ee10/osgi/boot/warurl/WarUrlActivator.java, 2009-11-09 -jetty-ee10/jetty-ee10-runner/src/test/java/org/eclipse/jetty/ee10/maven/jettyrunner/it/IntegrationTestJettyRunner.java, 2021-04-27 -jetty-ee10/jetty-ee10-runner/src/main/java/org/eclipse/jetty/ee10/runner/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-runner/src/main/java/org/eclipse/jetty/ee10/runner/Runner.java, 2012-08-29 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-container-initializer/src/main/java/org/example/initializer/FooInitializer.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-container-initializer/src/main/java/org/example/initializer/Foo.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/RoleAnnotationTest.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/Bar.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/SecuredServlet.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/AsyncListenerServlet.java, 2013-05-06 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/AnnotationTest.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/AnnotatedListener.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/ClassLoaderServlet.java, 2019-03-26 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/TestListener.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-spec-webapp/src/main/java/org/example/test/MultiPartTest.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-spec/jetty-ee10-demo-web-fragment/src/main/java/org/example/fragment/FragmentServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-async-rest/jetty-ee10-demo-async-rest-server/src/main/java/org/eclipse/jetty/ee10/demos/AsyncRestServer.java, 2011-07-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-async-rest/jetty-ee10-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee10/demos/AbstractRestServlet.java, 2011-07-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-async-rest/jetty-ee10-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee10/demos/AsyncRestServlet.java, 2011-07-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-async-rest/jetty-ee10-demo-async-rest-jar/src/main/java/org/eclipse/jetty/ee10/demos/SerialRestServlet.java, 2011-07-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/src/main/java/org/example/TagListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/src/main/java/org/example/Date2Tag.java, 2010-04-20 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/src/main/java/org/example/Counter.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jsp-webapp/src/main/java/org/example/DateTag.java, 2010-04-20 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneServletContextTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneWebAppWithJspTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneServletContextJmxStatsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneServletContextWithSessionTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/SecuredHelloHandlerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/WebSocketServerTest.java, 2019-09-09 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/FileServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/FastFileServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/MinimalServletsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/RewriteServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ManyHandlersTest.java, 2019-08-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ManyConnectorsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/LikeJettyXmlTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneContextTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/SimplestServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/FileServerXmlTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/AbstractEmbeddedTest.java, 2019-02-11 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/SplitFileServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ServerUtil.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneWebAppTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ServerWithAnnotationsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ExampleServerXmlTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ManyContextsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ServerWithJMXTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/JarServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneHandlerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/OneConnectorTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ExampleServerTest.java, 2019-08-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ManyServletContextsTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ProxyServerTest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/test/java/org/eclipse/jetty/ee10/demos/ServerWithJNDITest.java, 2019-09-04 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/WebSocketServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/LikeJettyXml.java, 2022-05-03 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/SplitFileServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneWebApp.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ServerWithJNDI.java, 2013-06-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/HelloWorld.java, 2009-07-27 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneServletContext.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneContext.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneHandler.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/HelloHandler.java, 2022-05-03 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ManyHandlers.java, 2022-05-03 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/AsyncEchoServlet.java, 2015-02-05 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/HelloServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ServerWithJMX.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/DumpServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/FileServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ServerWithAnnotations.java, 2013-06-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/Http2Server.java, 2013-02-22 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ExampleServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ProxyServer.java, 2012-07-20 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/FastFileServer.java, 2013-05-16 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ManyServletContexts.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/SimplestServer.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/HelloSessionServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/MinimalServlets.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneServletContextWithSession.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/FileServerXml.java, 2009-08-05 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/JarServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneWebAppWithJsp.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ManyContexts.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneConnector.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/SecuredHelloHandler.java, 2009-09-28 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ExampleUtil.java, 2019-09-10 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ExampleServerXml.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/JettyDemos.java, 2019-06-18 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/OneServletContextJmxStats.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/ManyConnectors.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-embedded/src/main/java/org/eclipse/jetty/ee10/demos/RewriteServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-proxy-webapp/src/test/java/org/eclipse/jetty/ee10/demos/ProxyWebAppTest.java, 2020-09-28 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jndi-webapp/src/main/java/org/example/JNDITest.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-simple-webapp/src/main/java/org/eclipse/jetty/ee10/demo/simple/HelloWorldServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/test/java/org/eclipse/jetty/ee10/DispatchServletTest.java, 2009-04-21 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/test/java/org/eclipse/jetty/ee10/ChatServletTest.java, 2013-06-13 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/test/java/org/eclipse/jetty/ee10/TestServer.java, 2009-03-30 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/Dump.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/SecureModeServlet.java, 2009-08-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/HelloWorld.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/TestFilter.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/SessionDump.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/CookieDump.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/AddListServletRequestListener.java, 2012-07-12 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/RewriteServlet.java, 2009-10-07 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/WebSocketChatServlet.java, 2009-11-23 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/TestServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/LoginServlet.java, 2012-10-12 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/DispatchServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/ChatServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/RegTest.java, 2012-09-29 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/JakartaWebSocketChat.java, 2020-09-25 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jetty-webapp/src/main/java/org/example/TestListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-mock-resources/src/main/java/org/example/MockUserTransaction.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-mock-resources/src/main/java/org/example/MockDataSource.java, 2012-11-02 -jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-mock-resources/src/main/java/org/example/MockTransport.java, 2012-08-09 -jetty-ee10/jetty-ee10-jspc-maven-plugin/src/main/java/org/eclipse/jetty/ee10/jspc/plugin/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jspc-maven-plugin/src/main/java/org/eclipse/jetty/ee10/jspc/plugin/JspcMojo.java, 2012-08-29 -jetty-ee10/jetty-ee10-ant/src/test/java/org/eclipse/jetty/ee10/ant/AntBuild.java, 2012-11-15 -jetty-ee10/jetty-ee10-ant/src/test/java/org/eclipse/jetty/ee10/ant/JettyAntTaskTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/FileMatchingConfiguration.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/Attributes.java, 2012-07-09 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/Connectors.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/SystemProperties.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/ContextHandlers.java, 2012-06-27 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/Connector.java, 2011-09-12 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/Attribute.java, 2011-09-12 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/types/LoginServices.java, 2009-03-24 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/AntMetaInfConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/JettyRunTask.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/AntWebXmlConfiguration.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/JettyStopTask.java, 2012-12-07 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/AntWebInfConfiguration.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/ServerProxyImpl.java, 2012-08-21 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/utils/TaskLog.java, 2012-07-06 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/utils/ServerProxy.java, 2012-05-08 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/utils/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-ant/src/main/java/org/eclipse/jetty/ee10/ant/AntWebAppContext.java, 2012-12-07 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/EmptyServerHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ReverseProxyTest.java, 2015-02-10 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ConnectHandlerTest.java, 2012-11-06 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ProxyServletTest.java, 2012-01-20 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ProxyServletLoadTest.java, 2015-03-05 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/BalancerServletTest.java, 2012-11-06 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/EchoHttpServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/AsyncMiddleManServletTest.java, 2015-01-15 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ClientAuthProxyTest.java, 2021-02-15 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/AbstractConnectHandlerTest.java, 2012-11-06 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ProxyServletFailureTest.java, 2014-04-30 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ConnectHandlerSSLTest.java, 2012-11-06 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ProxyServer.java, 2012-07-20 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/EmptyHttpServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ForwardProxyServerTest.java, 2016-03-10 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/CachingProxyServlet.java, 2018-09-04 -jetty-ee10/jetty-ee10-proxy/src/test/java/org/eclipse/jetty/ee10/proxy/ForwardProxyTLSServerTest.java, 2013-06-08 -jetty-ee10/jetty-ee10-proxy/src/main/java/module-info.java, 2013-07-12 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/AsyncMiddleManServlet.java, 2015-01-15 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/AfterContentTransformer.java, 2015-04-09 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/AsyncProxyServlet.java, 2014-04-01 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/BalancerServlet.java, 2012-11-06 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/AbstractProxyServlet.java, 2015-01-15 -jetty-ee10/jetty-ee10-proxy/src/main/java/org/eclipse/jetty/ee10/proxy/ProxyServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/acme/webapp/ClassInJarA.java, 2009-12-10 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/acme/webapp/TestAnnotation.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebInfConfigurationTest.java, 2017-11-15 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebAppDefaultServletCacheTest.java, 2022-12-22 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/OrderingTest.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/MetaInfConfigurationTest.java, 2017-04-13 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/TestMetaData.java, 2020-03-09 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebAppContextTest.java, 2010-04-22 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/ClassMatcherTest.java, 2015-06-18 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebAppDefaultServletTest.java, 2021-05-13 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/TempDirTest.java, 2021-04-30 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebAppClassLoaderUrlStreamTest.java, 2017-04-04 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/ConfigurationsTest.java, 2016-05-02 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/HugeResourceTest.java, 2019-07-18 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/ForcedServletTest.java, 2021-05-16 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebDescriptorTest.java, 2022-08-01 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/StandardDescriptorProcessorTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/URLStreamHandlerUtil.java, 2017-04-04 -jetty-ee10/jetty-ee10-webapp/src/test/java/org/eclipse/jetty/ee10/webapp/WebAppClassLoaderTest.java, 2009-12-10 -jetty-ee10/jetty-ee10-webapp/src/main/java/module-info.java, 2022-05-03 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/OverrideDescriptor.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JndiConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JspConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppContext.java, 2003-06-30 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/MetaData.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/RelativeOrdering.java, 2015-06-25 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/DescriptorProcessor.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/AbstractConfiguration.java, 2010-07-26 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/Descriptor.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/MetaInfConfiguration.java, 2009-05-19 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/Origin.java, 2011-03-25 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JettyWebXmlConfiguration.java, 2005-11-27 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebXmlConfiguration.java, 2005-11-27 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/Ordering.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/FragmentDescriptor.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/Configuration.java, 2006-02-19 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/DecoratingListener.java, 2019-08-08 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppClassLoader.java, 2005-11-27 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/ClassMatcher.java, 2010-04-13 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/DefaultsDescriptor.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/ServletsConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaasConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/FragmentConfiguration.java, 2009-05-19 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/DiscoveredAnnotation.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebInfConfiguration.java, 2006-02-23 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/package-info.java, 2011-03-25 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/IterativeDescriptorProcessor.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JmxConfiguration.java, 2010-07-26 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebAppConfiguration.java, 2010-07-26 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/Configurations.java, 2016-05-02 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/JaspiConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/StandardDescriptorProcessor.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/AbsoluteOrdering.java, 2015-06-25 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/WebDescriptor.java, 2010-07-16 -jetty-ee10/jetty-ee10-webapp/src/main/java/org/eclipse/jetty/ee10/webapp/CachingWebAppClassLoader.java, 2015-10-26 -jetty-ee10/jetty-ee10-jaas/src/test/java/org/eclipse/jetty/ee10/jaas/TestServlet.java, 2022-05-03 -jetty-ee10/jetty-ee10-jaas/src/test/java/org/eclipse/jetty/ee10/jaas/spi/PropertyFileLoginModuleTest.java, 2022-05-03 -jetty-ee10/jetty-ee10-jaas/src/test/java/org/eclipse/jetty/ee10/jaas/TestLoginModule.java, 2018-05-01 -jetty-ee10/jetty-ee10-jaas/src/test/java/org/eclipse/jetty/ee10/jaas/JAASLdapLoginServiceTest.java, 2022-05-03 -jetty-ee10/jetty-ee10-jaas/src/test/java/org/eclipse/jetty/ee10/jaas/JAASLoginServiceTest.java, 2018-04-17 -jetty-ee10/jetty-ee10-jaas/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/JAASLoginService.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/JAASUserPrincipal.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/AbstractLoginModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/AbstractDatabaseLoginModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/PropertyFileLoginModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/DataSourceLoginModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/JDBCLoginModule.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/spi/LdapLoginModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/PropertyUserStoreManager.java, 2020-11-11 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/JAASRole.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/JAASPrincipal.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/ServletRequestCallback.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/AbstractCallbackHandler.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/ObjectCallback.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/DefaultCallbackHandler.java, 2003-04-30 -jetty-ee10/jetty-ee10-jaas/src/main/java/org/eclipse/jetty/ee10/jaas/callback/RequestParameterCallback.java, 2004-06-23 -jetty-ee10/jetty-ee10-apache-jsp/src/test/java/org/eclipse/jetty/ee10/jsp/TestJspFileNameToClass.java, 2017-01-19 -jetty-ee10/jetty-ee10-apache-jsp/src/test/java/org/eclipse/jetty/ee10/jsp/TestJettyJspServlet.java, 2016-10-26 -jetty-ee10/jetty-ee10-apache-jsp/src/test/java/org/eclipse/jetty/ee10/jsp/TestJettyTldPreScanned.java, 2017-10-10 -jetty-ee10/jetty-ee10-apache-jsp/src/main/java/module-info.java, 2012-07-10 -jetty-ee10/jetty-ee10-apache-jsp/src/main/java/org/eclipse/jetty/ee10/apache/jsp/JettyTldPreScanned.java, 2017-10-10 -jetty-ee10/jetty-ee10-apache-jsp/src/main/java/org/eclipse/jetty/ee10/apache/jsp/JettyJasperInitializer.java, 2014-03-14 -jetty-ee10/jetty-ee10-apache-jsp/src/main/java/org/eclipse/jetty/ee10/apache/jsp/JuliLog.java, 2014-03-14 -jetty-ee10/jetty-ee10-apache-jsp/src/main/java/org/eclipse/jetty/ee10/jsp/JettyJspServlet.java, 2014-11-26 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/CrossOriginFilterTest.java, 2011-10-19 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/DoSFilterJMXTest.java, 2013-02-27 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/HeaderFilterTest.java, 2017-06-13 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AbstractFileContentServlet.java, 2014-11-13 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipContentLengthTest.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletStreamTypeLengthWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AsyncTimeoutCompleteWrite.java, 2015-03-26 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletLengthStreamTypeWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/QoSFilterTest.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/NoOpOutputStream.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletTypeStreamLengthWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/PassThruInputStream.java, 2016-01-04 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/EventSourceServletTest.java, 2013-01-31 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletLengthTypeStreamWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletStreamLengthTypeWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/DoSFilterTest.java, 2009-05-26 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipHandlerNoReCompressTest.java, 2020-04-14 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AsyncManipFilter.java, 2016-01-04 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipDefaultServletDeferredContentTypeTest.java, 2020-04-14 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/HttpOutputWriteFileContentServlet.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/CloseableDoSFilterTest.java, 2009-05-26 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AsyncScheduledDispatchWrite.java, 2016-01-04 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/ThreadStarvationTest.java, 2015-10-07 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletTypeLengthStreamWrite.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/TestMinGzipSizeServlet.java, 2011-12-08 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/BlockingServletStreamLengthTypeWriteWithFlush.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/IncludeExcludeBasedFilterTest.java, 2017-06-13 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AsyncTimeoutDispatchWrite.java, 2016-01-04 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AbstractDoSFilterTest.java, 2009-05-26 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/GzipHandlerTest.java, 2020-04-14 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/TestStaticMimeTypeServlet.java, 2011-08-12 -jetty-ee10/jetty-ee10-servlets/src/test/java/org/eclipse/jetty/ee10/servlets/AbstractGzipTest.java, 2020-04-14 -jetty-ee10/jetty-ee10-servlets/src/main/java/module-info.java, 2013-07-12 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/EventSourceServlet.java, 2013-01-31 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/HeaderFilter.java, 2017-06-13 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/QoSFilter.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/CGI.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/CrossOriginFilter.java, 2009-07-29 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/CloseableDoSFilter.java, 2009-05-26 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/IncludeExcludeBasedFilter.java, 2017-06-13 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/PushCacheFilter.java, 2014-08-08 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/DoSFilter.java, 2009-05-26 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/PushSessionCacheFilter.java, 2014-12-05 -jetty-ee10/jetty-ee10-servlets/src/main/java/org/eclipse/jetty/ee10/servlets/EventSource.java, 2013-01-31 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-servlet/src/main/java/module-info.java, 2013-07-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-servlet/src/main/java/org/eclipse/jetty/ee10/websocket/servlet/WebSocketUpgradeFilter.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee10/websocket/client/WebSocketClientBadUriTest.java, 2012-08-17 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee10/websocket/client/HttpClientInitTest.java, 2017-05-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/org/eclipse/jetty/ee10/websocket/client/WebSocketClientInitTest.java, 2016-11-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/examples/ClientDemo.java, 2012-07-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/examples/SimpleEchoClient.java, 2013-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/test/java/examples/SimpleEchoSocket.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/JettyUpgradeListener.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/WebSocketClient.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/impl/DelegatedJettyClientUpgradeResponse.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/impl/DelegatedJettyClientUpgradeRequest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/impl/JettyClientUpgradeRequest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/config/JettyWebSocketClientConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-client/src/main/java/org/eclipse/jetty/ee10/websocket/client/ClientUpgradeRequest.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JakartaClientShutdownWithServerWebAppTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/CloseInOnOpenTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/JsrEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PongContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/LargeAnnotatedTest.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/ReaderEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/EndpointViaConfigTest.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/ServerDecoderTest.java, 2020-01-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/MemoryUsageTest.java, 2014-02-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/DeploymentTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PingPongTest.java, 2017-05-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/BasicEchoSocketContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/BasicEchoEndpointContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PongSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/BasicEchoEndpointConfigContextListener.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PartialEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/StreamTest.java, 2014-03-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/DeploymentExceptionTest.java, 2016-08-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/JsrBatchModeTest.java, 2014-02-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/ContainerProviderServerTest.java, 2020-01-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/IdleTimeoutTest.java, 2017-05-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/TextStreamTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/LargeContainerTest.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/SessionTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/IdleTimeoutContextListener.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PrimitivesBinaryEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/AbstractJakartaWebSocketServerFrameHandlerTest.java, 2017-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/LargeEchoContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/GetHttpSessionSocket.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/WebSocketServerExamplesTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/GetHttpSessionConfigurator.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/StreamingEchoSocket.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/MyAuthedSocket.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/examples/MyAuthedConfigurator.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/PrimitivesTextEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/AnnotatedServerEndpointTest.java, 2013-12-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/StatelessTextMessageStringSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicEchoSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/binary/ByteBufferSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicErrorThrowableSessionSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicErrorThrowableSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidOpenIntSocket.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicErrorSessionSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicCloseReasonSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicBinaryMessageByteBufferSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicCloseReasonSessionSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicOpenSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/TrackingSocket.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidErrorErrorSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/pong/PongMessageEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicCloseSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicOpenSessionSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicErrorSessionThrowableSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidCloseIntSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/BasicEchoSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/BasicEchoEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoReturnTextSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoStatelessBasicTextSocket.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/LargeEchoDefaultSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoBasicTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/LargeEchoConfiguredSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoAsyncTextSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoReturnEndpoint.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/echo/EchoStatelessAsyncTextSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidOpenCloseReasonSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicCloseSessionReasonSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicPongMessageSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/streaming/ReaderSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/streaming/ReaderParamSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/streaming/InputStreamSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/streaming/StringReturnReaderParamSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/partial/PartialTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/partial/PartialTextSessionSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/partial/PartialTrackingSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicTextMessageStringSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicOpenCloseSessionSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidOpenSessionIntSocket.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/BooleanTextParamSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/BooleanTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/IntTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/LongObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/IntegerObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/FloatTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/ByteTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/ShortObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/IntParamTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/BooleanObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/FloatObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/DoubleTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/BooleanObjectTextParamSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/IntegerObjectParamTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/LongTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/DoubleObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/CharacterObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/ShortTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/ByteObjectTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/primitives/CharTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/DateTextSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/ConfiguredEchoSocket.java, 2013-12-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/idletimeout/OnOpenIdleTimeoutSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/idletimeout/OnOpenIdleTimeoutEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/ByteBufferSocket.java, 2013-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicOpenCloseSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/IdleTimeoutOnOpenEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/BasicErrorSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/sockets/InvalidErrorIntSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/BinaryStreamTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/configs/EchoSocketConfigurator.java, 2013-08-01 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/AltFilterTest.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/WebSocketServerContainerExecutorTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/OnMessageReturnTest.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/BasicEchoSocketConfigContextListener.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/UriTemplateParameterTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/AddEndpointTest.java, 2020-06-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/JettyServerEndpointConfiguratorTest.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/SessionTrackingTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/ConfiguratorTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/WebAppClassLoaderTest.java, 2020-01-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/server/InputStreamEchoTest.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/SyntheticOnMessageTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/GracefulCloseTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/SessionAddMessageHandlerTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/DecoderReaderManySmallTest.java, 2017-04-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/DelayedStartClientTest.java, 2017-05-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/JsrClientTrackingSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/AnnotatedEchoTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/misbehaving/EndpointRuntimeOnOpen.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/misbehaving/MisbehavingClassTest.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/misbehaving/AnnotatedRuntimeOnOpen.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/EndpointEchoTest.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/JsrClientEchoTrackingSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/WriteTimeoutTest.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/AbstractClientSessionTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/IntSocket.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseSessionReasonSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseSessionSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseReasonSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseEndpointConfigSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/samples/CloseReasonSessionSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/CookiesTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/AnnotatedClientEndpointTest.java, 2013-12-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/OnCloseTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/AnnotatedEchoClient.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/MessageReceivingTest.java, 2016-03-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/client/ConfiguratorTest.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/LongMessageHandler.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/ExtendedMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/AbstractHandler.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/BaseMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/AbstractAnnotatedHandler.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/BinaryHandlers.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/ComboMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/MessageHandlerTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/handlers/TextHandlers.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/UpgradeRequestResponseTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JakartaClientShutdownWithServerEmbeddedTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesEncoderTest.java, 2017-04-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesDecoderTextStreamTest.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/Quotes.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesDecoderTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesDecoder.java, 2017-04-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/quotes/QuotesUtil.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/SingleMessageHandlerTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DecoderListTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/ValidDualDecoder.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/AvailableEncodersTest.java, 2016-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/FruitDecoder.java, 2009-12-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/FruitTextEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/LongDecoderTest.java, 2019-06-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/TimeEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DecoderTextStreamTest.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DateEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/EncoderTextTest.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/Quotes.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/ValidDualEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DateTimeEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/TimeDecoder.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/EncoderLifeCycleTest.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/CoderEventTracking.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DecoderTextTest.java, 2013-02-19 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/Fruit.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/BadDualDecoder.java, 2013-02-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/AvailableDecodersTest.java, 2016-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DateDecoder.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/FloatDecoderTest.java, 2019-06-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/ExtDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/QuotesEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/BadDualEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/QuotesDecoder.java, 2017-04-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/DateTimeDecoder.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/FruitBinaryEncoder.java, 2012-07-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/QuotesUtil.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/ShortDecoderTest.java, 2019-06-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/coders/IntegerDecoderTest.java, 2013-02-19 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/PathParamTest.java, 2019-08-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/RestartContextTest.java, 2019-06-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JakartaWebSocketRestartTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JakartaClientClassLoaderTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/autobahn/JakartaAutobahnClient.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/autobahn/JakartaAutobahnSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/autobahn/JakartaAutobahnServer.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JettySpecificConfigTest.java, 2019-08-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/IntegerClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/StringClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/IntegerTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/ShortTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/CharacterTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/DoubleTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/LongTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/ByteClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/FloatClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/BooleanClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/ShortClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/CharacterClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/ByteTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/FloatTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/BooleanTypeSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/LongClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/pathparam/DoubleClassSocket.java, 2022-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/ProgrammaticWebSocketUpgradeTest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/ServerConfigTest.java, 2020-01-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/JakartaOnCloseTest.java, 2020-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/BasicEchoEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/LargeEchoDefaultSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenSocket.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/BasicEchoEndpointConfigContextListener.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutContextListener.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/PongMessageEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/LargeEchoContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/IdleTimeoutOnOpenEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/test/java/com/acme/websocket/OnOpenIdleTimeoutEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/CoreServer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/FunctionMethod.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/BadFrame.java, 2012-08-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/WSEndpointTracker.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/RawFrameBuilder.java, 2013-08-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/BiConsumerServiceServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/EchoSocket.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/WSServer.java, 2013-04-15 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/CompletableFutureMethodHandle.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/SessionMatchers.java, 2012-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/framehandlers/FrameHandlerTracker.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/framehandlers/WholeMessageEcho.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/framehandlers/StaticText.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/framehandlers/FrameEcho.java, 2013-07-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/Timeouts.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/UnitGenerator.java, 2017-05-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/LocalFuzzer.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/WSURI.java, 2013-06-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/LocalServer.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/NetworkFuzzer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/matchers/IsMessageHandlerTypeRegistered.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/matchers/IsMessageHandlerType.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/DummyEndpoint.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/Fuzzer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/ParserCapture.java, 2011-08-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/UpgradeUtils.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/MessageType.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/Sha1Sum.java, 2015-12-07 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/EventSocket.java, 2019-03-11 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/WSEventTracker.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-tests/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/tests/DataUtils.java, 2017-05-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketFrameHandlerTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/MessageInputStreamTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/EventQueue.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/MessageOutputStreamTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/EndPoints.java, 2020-03-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/LocalEndpointMetadataTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/OutgoingMessageCapture.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/DummyContainer.java, 2019-02-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/endpoints/adapters/ListenerEchoSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/endpoints/adapters/AdapterEchoSocket.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/endpoints/adapters/AnnotatedEchoSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/invoke/NameParamIdentifier.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/test/java/org/eclipse/jetty/ee10/websocket/common/invoke/InvokerUtilsTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketFrameHandlerFactory.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketRemoteEndpoint.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketFrameHandler.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketFrame.java, 2015-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/ExtensionConfigParser.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyWebSocketFrameHandlerMetadata.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/WebSocketSession.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/JettyExtensionConfig.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-common/src/main/java/org/eclipse/jetty/ee10/websocket/common/SessionTracker.java, 2017-04-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageBinaryTest.java, 2020-02-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageBinaryStreamTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageTextStreamTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerBadSignaturesTest.java, 2020-02-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/AbstractJakartaWebSocketFrameHandlerTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ByteBufferWholeHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/LongMessageHandler.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/StringWholeHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ExtendedMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/BaseMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/StringPartialHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ReaderWholeHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ByteArrayWholeHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ComboMessageHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ByteArrayPartialHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/ByteBufferPartialHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/handlers/InputStreamWholeHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnCloseTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnOpenTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/AbstractSessionTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnMessageTextTest.java, 2020-02-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedTextStreamMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/InputStreamMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedBinaryMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedBinaryStreamMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/MessageWriterTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/ReaderMessageSinkTest.java, 2017-05-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/AbstractMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedTextMessageSinkTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerOnErrorTest.java, 2020-03-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/FruitDecoder.java, 2009-12-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/FruitTextEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/Fruit.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/BadDualDecoder.java, 2013-02-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/ExtDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/BadDualEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/coders/tests/FruitBinaryEncoder.java, 2012-07-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/sockets/TrackingSocket.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/Defaults.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/util/NameParamIdentifier.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/util/InvokerUtilsStaticParamsTest.java, 2020-02-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/util/ReflectUtilsTest.java, 2013-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/util/InvokerUtilsTest.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/DummyContainer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/DummyFrameHandlerFactory.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/endpoints/AbstractStringEndpoint.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/endpoints/DummyEndpoint.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/common/endpoints/EchoStringEndpoint.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/module-info.java, 2012-09-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/PathParamProvider.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketPongMessage.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketRemoteEndpoint.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketContainer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketAsyncRemote.java, 2013-02-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerFactory.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketBasicRemote.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/RegisteredMessageHandler.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/UpgradeRequest.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/EndpointConfigWrapper.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketSession.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/LongDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/ByteDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/DoubleDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/ByteArrayDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/ReaderDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/ByteBufferDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/AvailableDecoders.java, 2016-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/IntegerDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/ShortDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/StringDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/CharacterDecoder.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/RegisteredDecoder.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/InputStreamDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/FloatDecoder.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/BooleanDecoder.java, 2012-08-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/decoders/AbstractDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/ServerEndpointConfigWrapper.java, 2013-04-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandlerMetadata.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketSessionListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/AbstractDecodedMessageSink.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedBinaryMessageSink.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedTextStreamMessageSink.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedBinaryStreamMessageSink.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/messages/DecodedTextMessageSink.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/ClientEndpointConfigWrapper.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/UpgradeRequestAdapter.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketExtension.java, 2013-02-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketMessageMetadata.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/InitException.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/PutListenerMap.java, 2019-12-17 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/ConfiguredEndpoint.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/SendHandlerCallback.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketFrameHandler.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/SessionTracker.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/CharacterEncoder.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/ByteEncoder.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/ShortEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/RegisteredEncoder.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/FloatEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/ByteBufferEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/StringEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/AvailableEncoders.java, 2016-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/BooleanEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/EncodeFailedFuture.java, 2013-07-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/DoubleEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/ByteArrayEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/LongEncoder.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/IntegerEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/encoders/AbstractEncoder.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-common/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/common/JakartaWebSocketExtensionConfig.java, 2012-06-25 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ParamsEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketFilterTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/WebSocketStatsTest.java, 2019-02-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ConnectMessageEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/MaxOutgoingFramesTest.java, 2020-10-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/WebSocketOverHTTP2Test.java, 2019-08-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/LargeDeflateTest.java, 2022-01-19 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/SingleOnMessageTest.java, 2020-12-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketServletTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/CloseInOnOpenTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/proxy/WebSocketProxyTest.java, 2020-11-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/proxy/WebSocketProxy.java, 2020-11-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/SimpleEchoTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/AnnoMaxMessageEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketRestartTest.java, 2021-01-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/SimpleStatusServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketExtensionConfigTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/EchoSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/SlowServerTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/PartialListenerTest.java, 2019-07-16 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/ServerCloseTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/CloseInOnCloseEndpointNewThread.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/FastFailEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/FastCloseEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/SlowServerEndpoint.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/FrameAnnotationTest.java, 2019-07-17 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/ServerCloseCreator.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/AbstractCloseEndpoint.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/ContainerEndpoint.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/FrameListenerTest.java, 2019-07-17 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/ServerConfigTest.java, 2019-05-16 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/server/CloseInOnCloseEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/SuspendResumeTest.java, 2019-03-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyOnCloseTest.java, 2020-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/GracefulCloseTest.java, 2020-06-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientCloseTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/InvalidUpgradeServlet.java, 2019-12-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientConnectTest.java, 2019-05-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/SlowClientTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/BadNetworkTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientSessionsTest.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/WebSocketClientTest.java, 2019-05-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ConnectFutureTest.java, 2020-07-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientWriteThread.java, 2012-09-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientConfigTest.java, 2019-05-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientOpenSessionTracker.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/client/ClientTimeoutTest.java, 2020-07-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketWebApp.java, 2020-11-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ConnectionHeaderTest.java, 2021-08-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/UpgradeRequestResponseTest.java, 2021-01-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/EchoCreator.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketNegotiationTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyWebSocketServletAttributeTest.java, 2019-01-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/GetAuthHeaderEndpoint.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyAuthedCreator.java, 2019-01-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyBinaryEchoSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyEchoSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyAuthedServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyAdvancedEchoServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyAdvancedEchoCreator.java, 2019-01-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/examples/MyEchoServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/CloseTrackingEndpoint.java, 2019-01-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ErrorCloseTest.java, 2020-02-18 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ConcurrentConnectTest.java, 2019-04-16 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/util/WSURITest.java, 2013-06-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/util/FutureWriteCallback.java, 2019-06-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/listeners/WebSocketListenerTest.java, 2020-04-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/listeners/AbstractAnnotatedListener.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/listeners/BinaryListeners.java, 2020-04-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/listeners/TextListeners.java, 2020-04-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/listeners/AbstractListener.java, 2012-08-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/PermessageDeflateBufferTest.java, 2021-03-17 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/autobahn/JettyAutobahnClient.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/autobahn/JettyAutobahnServer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/autobahn/JettyAutobahnSocket.java, 2012-06-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/JettyClientClassLoaderTest.java, 2021-02-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/WebSocketServletExamplesTest.java, 2019-01-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/EventSocket.java, 2019-03-11 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/ProgrammaticWebSocketUpgradeTest.java, 2021-01-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/AnnotatedPartialListenerTest.java, 2021-06-11 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/extensions/ExtensionConfigTest.java, 2012-11-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/WebSocketStopTest.java, 2019-07-03 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-tests/src/test/java/org/eclipse/jetty/ee10/websocket/tests/WebAppTester.java, 2021-05-19 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/module-info.java, 2009-03-30 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketPartialListener.java, 2015-05-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketBehavior.java, 2012-06-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketAdapter.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketContainer.java, 2019-02-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/OnWebSocketMessage.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/OnWebSocketConnect.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/WebSocket.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/OnWebSocketFrame.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/OnWebSocketError.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/annotations/OnWebSocketClose.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/ExtensionConfig.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WriteCallback.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/Frame.java, 2012-11-05 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketSessionListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/UpgradeRequest.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketFrameListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/RemoteEndpoint.java, 2012-11-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/CloseStatus.java, 2012-05-08 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketPingPongListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketListener.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/UpgradeResponse.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/BatchMode.java, 2012-07-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketPolicy.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/util/WSURI.java, 2013-06-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/util/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/util/WebSocketConstants.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/WebSocketConnectionListener.java, 2012-06-26 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/SuspendToken.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/StatusCode.java, 2012-06-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/InvalidWebSocketException.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/MessageTooLargeException.java, 2012-07-06 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/CloseException.java, 2012-06-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/BadPayloadException.java, 2012-07-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/WebSocketException.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/ProtocolException.java, 2012-06-29 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/UpgradeException.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/WebSocketTimeoutException.java, 2012-06-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/exceptions/PolicyViolationException.java, 2012-06-20 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-api/src/main/java/org/eclipse/jetty/ee10/websocket/api/Session.java, 2012-11-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/test/java/examples/SecureWebSocketContainerExample.java, 2019-08-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/test/java/examples/SecureClientContainerExample.java, 2019-08-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/test/java/examples/EchoEndpoint.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/test/java/examples/OriginServerConfigurator.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/JakartaWebSocketClientContainerProvider.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/AnnotatedClientEndpointConfig.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/JakartaClientUpgradeRequest.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/EmptyConfigurator.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/BasicClientEndpointConfig.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/JsrUpgradeListener.java, 2021-01-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/JakartaWebSocketClientContainer.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/internal/JakartaWebSocketClientFrameHandlerFactory.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-client/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/client/JakartaWebSocketShutdownContainer.java, 2022-01-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/test/java/org/eclipse/jetty/ee10/websocket/server/browser/BrowserDebugTool.java, 2019-01-14 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/test/java/org/eclipse/jetty/ee10/websocket/server/browser/BrowserSocket.java, 2012-10-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/module-info.java, 2012-07-10 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyServerUpgradeRequest.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyWebSocketServlet.java, 2019-03-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/internal/UpgradeHttpServletRequest.java, 2022-05-09 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/internal/JettyServerFrameHandlerFactory.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/internal/DelegatedServerUpgradeResponse.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/internal/DelegatedServerUpgradeRequest.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyServerUpgradeResponse.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyWebSocketCreator.java, 2019-03-13 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyWebSocketServletFactory.java, 2019-03-28 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/JettyWebSocketServerContainer.java, 2019-02-21 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/config/JettyWebSocketServletContainerInitializer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jetty-server/src/main/java/org/eclipse/jetty/ee10/websocket/server/config/JettyWebSocketConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/server/browser/JsrBrowserConfigurator.java, 2013-08-01 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/server/browser/JsrBrowserDebugTool.java, 2013-09-12 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/test/java/org/eclipse/jetty/ee10/websocket/jakarta/server/browser/JsrBrowserSocket.java, 2012-10-04 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/module-info.java, 2018-11-22 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/AnnotatedServerEndpointConfig.java, 2013-07-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/PathParamIdentifier.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JakartaServerUpgradeRequest.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JakartaWebSocketServerContainer.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/PathParamServerEndpointConfig.java, 2012-08-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JsrHandshakeRequest.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/BasicServerEndpointConfig.java, 2012-06-27 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JsrHandshakeResponse.java, 2009-03-24 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JakartaWebSocketServerFrameHandlerFactory.java, 2018-11-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/internal/JakartaWebSocketCreator.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/config/JakartaWebSocketConfiguration.java, 2016-05-02 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/config/ContainerDefaultConfigurator.java, 2013-04-23 -jetty-ee10/jetty-ee10-websocket/jetty-ee10-websocket-jakarta-server/src/main/java/org/eclipse/jetty/ee10/websocket/jakarta/server/config/JakartaWebSocketServletContainerInitializer.java, 2013-09-23 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-loginservice/src/test/java/org/eclipse/jetty/ee10/loginservice/DatabaseLoginServiceTestServer.java, 2014-07-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-loginservice/src/test/java/org/eclipse/jetty/ee10/loginservice/JdbcLoginServiceTest.java, 2010-05-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-loginservice/src/test/java/org/eclipse/jetty/ee10/loginservice/DataSourceLoginServiceTest.java, 2014-07-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/GreetingsServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/EmbeddedWeldTest.java, 2020-09-07 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/MyFilter.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/Greetings.java, 2012-11-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/FriendlyGreetings.java, 2012-07-09 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/MyContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/websocket/JettyWebSocketCdiTest.java, 2021-03-31 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/websocket/JavaxWebSocketCdiTest.java, 2021-03-31 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/websocket/LogFactory.java, 2021-03-31 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/ErrorPage.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/AdminPage.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/HomePage.java, 2022-02-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/LogoutPage.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-openid-webapp/src/main/java/org/eclipse/jetty/test/openid/LoginPage.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-felix-webapp/src/main/java/org/eclipse/jetty/demo/InfoServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-felix-webapp/src/main/java/org/eclipse/jetty/demo/AppListener.java, 2019-06-12 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/QuickStartTest.java, 2014-08-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/Quickstart.java, 2014-03-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/PreconfigureStandardTestWar.java, 2014-03-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/QuickStartStandardTestWar.java, 2012-05-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/QuickStartSpecWar.java, 2012-08-31 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/QuickStartJNDIWar.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/PreconfigureJNDIWar.java, 2013-07-10 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/PreconfigureSpecWar.java, 2014-03-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-memcached/src/test/java/org/eclipse/jetty/ee10/session/memcached/CachingSessionDataStoreTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-memcached/src/test/java/org/eclipse/jetty/ee10/session/memcached/MemcachedTestHelper.java, 2016-06-17 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/MongoTestHelper.java, 2017-01-13 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/ClusteredInvalidateSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/MongoSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-mongodb/src/test/java/org/eclipse/jetty/ee10/session/nosql/mongodb/AttributeNameTest.java, 2014-10-01 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-file/src/test/java/org/eclipse/jetty/ee10/session/file/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee10/session/gcloud/InvalidationSessionTest.java, 2015-04-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee10/session/gcloud/GCloudSessionTestSupport.java, 2015-09-18 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee10/session/gcloud/GCloudSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee10/session/gcloud/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-gcloud/src/test/java/org/eclipse/jetty/ee10/session/gcloud/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/IdleSessionTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/ReentrantRequestSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/ModifyMaxInactiveIntervalTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/DeleteUnloadableSessionTest.java, 2016-06-01 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/RemoveSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/SessionRenewTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/RequestScopedSessionSaveTest.java, 2022-01-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/CreationTest.java, 2017-01-13 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/RequestDispatchedSessionTest.java, 2019-10-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/NonClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/RedirectSessionTest.java, 2016-07-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/ClientCrossContextSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/SessionInvalidateCreateScavengeTest.java, 2012-05-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/SameContextForwardedSessionTest.java, 2015-04-23 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/DuplicateCookieTest.java, 2019-10-16 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/SessionInvalidationTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/ConcurrencyTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/test/java/org/eclipse/jetty/ee10/session/AsyncTest.java, 2018-12-18 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/AbstractSessionTestBase.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/AbstractClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/AbstractClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/TestHttpSessionListener.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/WebAppObjectInSessionServlet.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/AbstractClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/TestSessionDataStore.java, 2015-08-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/FooInvocationHandler.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/Foo.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/TestSessionDataStoreFactory.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/SessionTestSupport.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/AbstractWebAppObjectInSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-common/src/main/java/org/eclipse/jetty/ee10/session/TestFoo.java, 2011-03-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/HazelcastClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/client/ClientOrphanedSessionTest.java, 2017-05-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/client/HazelcastSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/client/ClientSessionScavengingTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/HazelcastSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/HazelcastTestHelper.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-hazelcast/src/test/java/org/eclipse/jetty/ee10/session/hazelcast/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/InfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/SerializedInfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/LoggingUtil.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/ClusteredSerializedSessionScavengingTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/ClusteredSessionScavengingTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/InfinispanTestSupport.java, 2015-04-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/InfinispanFileSessionDataStoreTest.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/ClusteredOrphanedSessionTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/remote/RemoteClusteredInvalidationSessionTest.java, 2015-04-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/remote/RemoteInfinispanTestSupport.java, 2015-04-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/remote/RemoteClusteredSessionScavengingTest.java, 2012-10-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-infinispan/src/test/java/org/eclipse/jetty/ee10/session/infinispan/remote/RemoteInfinispanSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/ClusteredSessionMigrationTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/JDBCSessionDataStoreTest.java, 2018-03-28 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/ClusteredSessionScavengingTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/SessionTableSchemaTest.java, 2017-06-06 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/ReloadedSessionMissingClassTest.java, 2013-03-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/ClusteredInvalidationSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/ClusteredOrphanedSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-sessions/jetty-ee10-test-sessions-jdbc/src/test/java/org/eclipse/jetty/ee10/session/jdbc/WebAppObjectInSessionTest.java, 2010-01-26 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/bad/StringSequence.java, 2011-08-11 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/bad/BadOnOpenServerEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-bad-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/bad/BadOnCloseServerEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ManifestServerID.java, 2019-06-05 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/OldGreetings.java, 2019-06-05 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/GreetingsServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerIDFilter.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/Greetings.java, 2012-11-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/FriendlyGreetings.java, 2012-07-09 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/MyContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/InfoServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi-common-webapp/src/main/java/org/eclipse/jetty/test/ServerID.java, 2012-11-02 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jndi/src/test/java/org/eclipse/jetty/ee10/jndi/factories/TestMailSessionReference.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-http2-webapp/src/test/java/org/eclipse/jetty/test/webapp/HTTP2FromWebAppIT.java, 2017-09-30 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP2Servlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-http2-webapp/src/main/java/org/eclipse/jetty/test/webapp/HTTP1Servlet.java, 2017-09-30 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/InformationalResponseTest.java, 2022-06-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/HttpTrailersTest.java, 2017-04-03 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/VirtualThreadsTest.java, 2022-08-18 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/RequestReaderTest.java, 2021-05-19 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/PushCacheFilterTest.java, 2022-11-21 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/AsyncIOServletTest.java, 2013-08-12 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/BlockedIOTest.java, 2021-02-03 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/HttpClientContinueTest.java, 2012-10-10 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/ServerTimeoutsTest.java, 2016-08-31 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-client-transports/src/test/java/org/eclipse/jetty/ee10/test/client/transport/AbstractTest.java, 2015-02-05 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-badinit-webapp/src/main/java/org/eclipse/jetty/ee10/test/BadServletInit.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-simple-session-webapp/src/main/java/org/eclipse/jetty/test/session/SessionTest.java, 2011-12-14 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-simple-session-webapp/src/main/java/org/eclipse/jetty/test/session/Chocolate.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/StringSequence.java, 2011-08-11 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/EchoEndpoint.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/StringSequenceDecoder.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/MyContainerInitializer.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/Echoer.java, 2012-08-03 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/jmx/PingerMBean.java, 2012-07-23 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/jmx/EchoerMBean.java, 2012-08-03 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/CommonComponent.java, 2012-07-23 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/PingServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp/src/main/java/org/eclipse/jetty/ee10/test/jmx/Pinger.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-jmx/jetty-ee10-jmx-webapp-it/src/test/java/org/eclipse/jetty/ee10/test/jmx/JmxIT.java, 2015-01-16 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/rfcs/RFC2616BaseTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/rfcs/RFC2616NIOHttpTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/rfcs/RFC2616NIOHttpsTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/DefaultHandlerTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/RecoverFailedSelectorTest.java, 2020-04-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AllowedResourceAliasCheckerTest.java, 2021-12-07 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/GzipWithSendErrorTest.java, 2020-11-18 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/HttpInputIntegrationTest.java, 2015-02-25 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/DeploymentErrorTest.java, 2018-01-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/jsp/JspAndDefaultWithoutAliasesTest.java, 2012-12-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/jsp/JspAndDefaultWithAliasesTest.java, 2012-12-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/jsp/FakeJspServlet.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AliasCheckerSymlinkTest.java, 2021-09-21 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/DigestPostTest.java, 2010-03-16 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/CustomRequestLogTest.java, 2018-11-06 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/FailedSelectorTest.java, 2019-08-30 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/AnnotatedAsyncListenerTest.java, 2019-06-07 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/HttpInputInterceptorTest.java, 2021-04-15 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/StringUtil.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpResponseTesterTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpTesting.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpSocketImpl.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpRequestTesterTest.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/rawhttp/HttpsSocketImpl.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/support/XmlBasedJettyServer.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/KeyStoreScannerTest.java, 2020-07-10 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/websocket/JettySimpleEchoSocket.java, 2012-06-27 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/websocket/JettyWebSocketTest.java, 2019-03-21 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/websocket/JakartaWebSocketTest.java, 2019-03-21 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/websocket/JakartaSimpleEchoSocket.java, 2009-03-24 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-integration/src/test/java/org/eclipse/jetty/ee10/test/DeploymentErrorInitializer.java, 2012-07-10 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/WebSocketClientServlet.java, 2020-09-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-client-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/EchoEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-webapp-rfc2616/src/main/java/org/eclipse/jetty/tests/webapp/HttpMethodsServlet.java, 2009-07-08 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/WebSocketClientServlet.java, 2020-09-29 -jetty-ee10/jetty-ee10-tests/jetty-ee10-test-websocket-client-provided-webapp/src/main/java/org/eclipse/jetty/ee10/tests/webapp/websocket/EchoEndpoint.java, 2012-07-09 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletRangesTest.java, 2012-08-27 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherForwardTest.java, 2014-05-09 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletWrapperTest.java, 2019-10-01 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ListenerHolderTest.java, 2020-03-09 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncServletLongPollTest.java, 2013-06-05 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncListenerTest.java, 2015-08-10 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletContextHandlerTest.java, 2011-05-11 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletHolderTest.java, 2015-12-14 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncContextDispatchWithQueryStrings.java, 2011-03-16 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletLifeCycleTest.java, 2019-09-13 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/ConstraintTest.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/PropertyUserStoreTest.java, 2010-10-12 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/TestLoginService.java, 2015-11-26 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/DataConstraintsTest.java, 2012-01-17 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/HashLoginServiceTest.java, 2019-05-07 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/SessionAuthenticationTest.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/DefaultIdentityServiceTest.java, 2021-08-25 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/UnauthenticatedTest.java, 2021-08-20 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/UserStoreTest.java, 2017-04-20 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/SpecExampleConstraintTest.java, 2012-09-28 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/ClientCertAuthenticatorTest.java, 2021-02-10 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/AliasedConstraintTest.java, 2014-06-26 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/security/authentication/SpnegoAuthenticatorTest.java, 2017-08-01 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/InitServletTest.java, 2019-11-25 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/FormTest.java, 2019-07-23 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/SessionHandlerTest.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/EncodedURITest.java, 2016-09-08 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/SSLAsyncIOServletTest.java, 2014-04-16 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletHandlerTest.java, 2013-01-14 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/PostServletTest.java, 2016-04-26 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ErrorPageTest.java, 2013-03-11 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletUpgradeTest.java, 2021-01-28 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncServletTest.java, 2013-03-08 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DispatcherTest.java, 2008-07-10 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/GzipHandlerCommitTest.java, 2020-05-01 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ComponentWrapTest.java, 2020-09-15 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletContextResourcesTest.java, 2016-06-22 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RegexServletTest.java, 2022-03-22 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ComplianceViolations2616Test.java, 2016-03-22 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletContainerInitializerHolderTest.java, 2021-02-19 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/IncludedServletTest.java, 2016-04-26 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/CharacterEncodingTest.java, 2022-12-13 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/CustomRequestLogTest.java, 2022-10-12 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ResponseHeadersTest.java, 2012-06-25 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/CacheControlHeaderTest.java, 2021-02-18 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestTest.java, 2022-09-13 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestURITest.java, 2014-03-19 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/RequestHeadersTest.java, 2013-03-19 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncContextListenersTest.java, 2013-08-21 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/InvokerTest.java, 2008-08-21 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/MultiPartServletTest.java, 2019-05-29 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/DefaultServletTest.java, 2009-04-21 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/GzipHandlerBreakEvenSizeTest.java, 2019-10-14 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncServletIOTest.java, 2013-05-24 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/FilterHolderTest.java, 2016-11-02 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/AsyncContextTest.java, 2012-02-14 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/GzipHandlerTest.java, 2011-06-20 -jetty-ee10/jetty-ee10-servlet/src/test/java/org/eclipse/jetty/ee10/servlet/ServletRequestLogTest.java, 2014-10-10 -jetty-ee10/jetty-ee10-servlet/src/test/resources/Foo.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/module-info.java, 2012-09-13 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/FilterHolder.java, 2001-11-07 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/jmx/HolderMBean.java, 2003-02-15 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/jmx/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/jmx/FilterMappingMBean.java, 2009-06-11 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/jmx/ServletMappingMBean.java, 2009-06-11 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletMapping.java, 2005-11-27 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletRequestHttpWrapper.java, 2010-09-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/AsyncContextEvent.java, 2013-04-22 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletRequestState.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletResponseHttpWrapper.java, 2010-09-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/DefaultUserIdentity.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/ConstraintSecurityHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/SpnegoUserIdentity.java, 2010-12-17 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/DefaultIdentityService.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/UserPrincipal.java, 2020-11-17 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/RolePrincipal.java, 2011-03-29 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/UserStore.java, 2017-04-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/SecurityHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/SpnegoUserPrincipal.java, 2010-12-17 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/ServerAuthException.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/DefaultAuthenticatorFactory.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/UserDataConstraint.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/Authentication.java, 2009-04-17 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/Authenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/UserAuthentication.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/WrappedAuthConfiguration.java, 2021-08-18 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/LoginService.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/ConstraintMapping.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/ConstraintAware.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/AbstractLoginService.java, 2015-11-26 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/LoggedOutAuthentication.java, 2019-03-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/EmptyLoginService.java, 2011-08-11 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/JDBCLoginService.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/PropertyUserStore.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/HashLoginService.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/IdentityService.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/RoleRunAsToken.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/RoleInfo.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/ConfigurableSpnegoLoginService.java, 2018-09-14 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/AbstractUserAuthentication.java, 2013-04-19 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/ConfigurableSpnegoAuthenticator.java, 2018-09-14 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/BasicAuthenticator.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/AuthorizationService.java, 2018-09-14 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/ClientCertAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/DigestAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/LoginCallback.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/SessionAuthentication.java, 2009-08-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/LoginAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/DeferredAuthentication.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/SslClientCertAuthenticator.java, 2021-02-10 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/FormAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/LoginCallbackImpl.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/UserIdentity.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/RunAsToken.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ContentProducer.java, 2020-03-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java, 2023-01-23 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Invoker.java, 2002-07-17 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextResponse.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Source.java, 2016-07-08 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiResponse.java, 2023-01-23 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/FilterMapping.java, 2005-11-27 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/NoJspServlet.java, 2005-11-27 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ListenerHolder.java, 2013-12-12 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/QuietServletException.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/BlockingContentProducer.java, 2020-03-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextRequest.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/listener/IntrospectorCleaner.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/listener/ContainerInitializer.java, 2019-05-28 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/listener/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContainerInitializerHolder.java, 2021-02-19 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ErrorPageErrorHandler.java, 2006-09-07 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ManagedAttributeListener.java, 2015-06-19 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletTester.java, 2012-07-13 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DecoratingListener.java, 2019-08-08 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DefaultServlet.java, 2005-11-27 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletPathMapping.java, 2020-05-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpInput.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Holder.java, 2001-11-07 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletMultiPartFormData.java, 2022-08-04 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHandler.java, 2006-12-29 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/BaseHolder.java, 2013-12-12 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/util/ServletOutputStreamWrapper.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/AsyncContentProducer.java, 2020-03-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/DebugListener.java, 2015-09-11 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/JspPropertyGroupServlet.java, 2013-02-25 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextHandler.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/Dispatcher.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/PushBuilderImpl.java, 2022-11-21 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ErrorHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletHolder.java, 2000-06-14 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/AsyncContextState.java, 2013-04-22 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletChannel.java, 2022-05-03 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/writer/ResponseWriter.java, 2015-04-29 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/writer/HttpWriter.java, 2009-03-24 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/writer/Utf8HttpWriter.java, 2012-08-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/writer/Iso88591HttpWriter.java, 2012-08-20 -jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/writer/EncodingHttpWriter.java, 2012-08-20 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/acme/ClassOne.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestAnnotationParser.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestSecurityAnnotationConversions.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ClassA.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestRunAsAnnotation.java, 2020-04-06 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ServletC.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ServletE.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ListenerC.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/Sample.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestAnnotationConfiguration.java, 2010-07-16 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ClassB.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/InterfaceD.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/Multi.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/resources/TestResourceAnnotations.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/resources/ResourceA.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/resources/ResourceB.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestAnnotationDecorator.java, 2020-03-09 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestAnnotationIntrospector.java, 2020-03-09 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/ServletD.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestDiscoveredServletContainerInitializerHolder.java, 2021-02-19 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/TestServletAnnotations.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/test/java/org/eclipse/jetty/ee10/annotations/FilterC.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/main/java/module-info.java, 2012-07-10 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationDecorator.java, 2010-07-16 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/ContainerInitializerAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebFilterAnnotation.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebServletAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AbstractDiscoverableAnnotationHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebListenerAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/MultiPartConfigAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/ClassInheritanceHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebServletAnnotation.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/ResourceAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebListenerAnnotation.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/ServletSecurityAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/ResourcesAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/WebFilterAnnotationHandler.java, 2011-07-07 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationParser.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/DeclareRolesAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/PostConstructAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationIntrospector.java, 2010-07-16 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/AnnotationConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/RunAsAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-annotations/src/main/java/org/eclipse/jetty/ee10/annotations/PreDestroyAnnotationHandler.java, 2009-07-22 -jetty-ee10/jetty-ee10-jndi/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-jndi/src/main/java/org/eclipse/jetty/ee10/jndi/factories/MailSessionReference.java, 2009-03-24 -jetty-ee10/jetty-ee10-jndi/src/main/java/org/eclipse/jetty/ee10/jndi/factories/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtEncoder.java, 2019-11-20 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/JwtDecoderTest.java, 2019-11-20 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentialsTest.java, 2021-08-16 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdProvider.java, 2019-09-11 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticationTest.java, 2019-08-29 -jetty-ee10/jetty-ee10-openid/src/test/java/org/eclipse/jetty/ee10/security/openid/OpenIdReamNameTest.java, 2021-11-10 -jetty-ee10/jetty-ee10-openid/src/main/java/module-info.java, 2013-07-12 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdConfiguration.java, 2019-08-29 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/JwtDecoder.java, 2019-11-20 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserPrincipal.java, 2011-03-29 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthenticatorFactory.java, 2019-08-29 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdAuthConfiguration.java, 2021-10-26 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdUserIdentity.java, 2010-12-17 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdLoginService.java, 2019-08-29 -jetty-ee10/jetty-ee10-openid/src/main/java/org/eclipse/jetty/ee10/security/openid/OpenIdCredentials.java, 2019-08-29 -jetty-ee10/jetty-ee10-jaspi/src/test/java/org/eclipse/jetty/ee10/security/jaspi/DefaultAuthConfigFactoryTest.java, 2021-08-18 -jetty-ee10/jetty-ee10-jaspi/src/test/java/org/eclipse/jetty/ee10/security/jaspi/JaspiTest.java, 2014-12-12 -jetty-ee10/jetty-ee10-jaspi/src/test/java/org/eclipse/jetty/ee10/security/jaspi/HttpHeaderAuthModule.java, 2014-12-12 -jetty-ee10/jetty-ee10-jaspi/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/JaspiMessageInfo.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/modules/BaseAuthModule.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/modules/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/modules/BasicAuthenticationAuthModule.java, 2019-08-27 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/SimpleAuthConfig.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/ServletCallbackHandler.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/JaspiAuthenticatorFactory.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/DefaultAuthConfigFactory.java, 2021-08-18 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/callback/CredentialValidationCallback.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/callback/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/provider/SimpleServerAuthContext.java, 2021-08-18 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/provider/SimpleAuthConfig.java, 2009-03-24 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/provider/JaspiAuthConfigProvider.java, 2021-08-18 -jetty-ee10/jetty-ee10-jaspi/src/main/java/org/eclipse/jetty/ee10/security/jaspi/JaspiAuthenticator.java, 2009-03-24 -jetty-ee10/jetty-ee10-examples/src/test/java/org/acme/MyServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-examples/src/test/java/org/eclipse/jetty/examples/Jetty12Example.java, 2022-05-03 -jetty-ee10/jetty-ee10-plus/src/test/java/org/eclipse/jetty/ee10/plus/jndi/NamingEntryUtilTest.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/test/java/org/eclipse/jetty/ee10/plus/jndi/TestNamingEntryUtil.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/test/java/org/eclipse/jetty/ee10/plus/jndi/TestNamingEntries.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/test/java/org/eclipse/jetty/ee10/plus/webapp/PlusDescriptorProcessorTest.java, 2011-07-07 -jetty-ee10/jetty-ee10-plus/src/test/java/org/eclipse/jetty/ee10/plus/annotation/LifeCycleCallbackCollectionTest.java, 2019-07-01 -jetty-ee10/jetty-ee10-plus/src/main/java/module-info.java, 2018-11-22 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/EnvEntry.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/Link.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/NamingEntryUtil.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/NamingEntry.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/NamingDump.java, 2019-06-18 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/Resource.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/jndi/Transaction.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/security/DataSourceLoginService.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/security/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/webapp/EnvConfiguration.java, 2006-03-14 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/webapp/package-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/webapp/PlusConfiguration.java, 2009-03-24 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/webapp/PlusDecorator.java, 2010-07-16 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/webapp/PlusDescriptorProcessor.java, 2010-07-16 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/PostConstructCallback.java, 2006-12-29 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/RunAs.java, 2006-11-12 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/InjectionCollection.java, 2006-12-29 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/RunAsCollection.java, 2007-02-14 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/Injection.java, 2006-12-29 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/PreDestroyCallback.java, 2006-12-29 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/LifeCycleCallback.java, 2006-12-29 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/package-info.java, 2012-11-02 -jetty-ee10/jetty-ee10-plus/src/main/java/org/eclipse/jetty/ee10/plus/annotation/LifeCycleCallbackCollection.java, 2006-12-29 -jetty-ee10/jetty-ee10-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/FooServlet.java, 2011-12-14 -jetty-ee10/jetty-ee10-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/TestQuickStart.java, 2017-04-12 -jetty-ee10/jetty-ee10-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/FooContextListener.java, 2009-03-24 -jetty-ee10/jetty-ee10-quickstart/src/test/java/org/eclipse/jetty/ee10/quickstart/FooFilter.java, 2009-03-24 -jetty-ee10/jetty-ee10-quickstart/src/main/java/module-info.java, 2009-03-24 -jetty-ee10/jetty-ee10-quickstart/src/main/java/org/eclipse/jetty/ee10/quickstart/QuickStartGeneratorConfiguration.java, 2014-07-09 -jetty-ee10/jetty-ee10-quickstart/src/main/java/org/eclipse/jetty/ee10/quickstart/QuickStartDescriptorProcessor.java, 2014-03-17 -jetty-ee10/jetty-ee10-quickstart/src/main/java/org/eclipse/jetty/ee10/quickstart/PreconfigureQuickStartWar.java, 2014-03-17 -jetty-ee10/jetty-ee10-quickstart/src/main/java/org/eclipse/jetty/ee10/quickstart/QuickStartConfiguration.java, 2014-03-17 -jetty-ee10/jetty-ee10-quickstart/src/main/java/org/eclipse/jetty/ee10/quickstart/ExtraXmlDescriptorProcessor.java, 2014-03-17 -tests/test-integration/src/test/java/org/eclipse/jetty/test/AliasCheckerMultipleResourceBasesTest.java, 2022-08-11 -tests/test-integration/src/test/java/org/eclipse/jetty/test/AliasCheckerSymlinkTest.java, 2021-09-21 -tests/test-jpms/test-jpms-websocket-core/src/test/java/WebSocketCoreJPMSTest.java, 2021-08-30 -tests/test-jpms/test-jpms-websocket-core/src/main/java/module-info.java, 2021-08-30 -tests/jetty-home-tester/src/main/java/org/eclipse/jetty/tests/hometester/JettyHomeTester.java, 2018-09-24 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/DeflaterPoolBenchmark.java, 2018-08-21 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/server/jmh/ListVsMapBenchmark.java, 2019-06-24 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/client/jmh/ConnectionPoolsBenchmark.java, 2020-07-31 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/http/jmh/HttpMethodBenchmark.java, 2020-11-11 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/io/jmh/ByteBufferBenchmark.java, 2018-11-05 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/requestlog/jmh/RequestLogBenchmark.java, 2018-11-01 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringReplaceBenchmark.java, 2018-08-21 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StringIsEmptyBenchmark.java, 2019-05-23 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTick.java, 2009-03-24 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormatBenchmark.java, 2018-03-06 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheBenchmark.java, 2018-03-06 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheSimpleDateFormat.java, 2009-03-24 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/jmh/DateCacheNoTickBenchmark.java, 2018-03-06 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/StreamVsIteratorBenchmark.java, 2018-08-21 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ThreadPoolBenchmark.java, 2018-03-06 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/jmh/ReservedThreadPoolBenchmark.java, 2018-03-06 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/AdaptiveExecutionStrategyBenchmark.java, 2018-02-27 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestConnection.java, 2018-02-27 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/thread/strategy/jmh/TestServer.java, 2018-02-27 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/PoolStrategyBenchmark.java, 2020-09-16 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/util/TrieBenchmark.java, 2021-01-05 -tests/jetty-jmh/src/main/java/org/eclipse/jetty/logging/jmh/IndentBenchmark.java, 2018-03-06 -tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/OpenIdTests.java, 2022-07-08 -tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/openid/JwtEncoder.java, 2019-11-20 -tests/test-distribution/test-ee10-distribution/src/test/java/org/eclipse/jetty/ee10/tests/distribution/openid/OpenIdProvider.java, 2019-09-11 -tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/OpenIdTests.java, 2022-07-08 -tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/JwtEncoder.java, 2019-11-20 -tests/test-distribution/test-ee9-distribution/src/test/java/org/eclipse/jetty/ee9/tests/distribution/openid/OpenIdProvider.java, 2019-09-11 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/BadAppTests.java, 2019-05-03 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/CDITests.java, 2019-06-05 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/StatsTests.java, 2020-11-16 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/JDBCSessionDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/InfinispanSessionDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionDistributionTests.java, 2011-08-11 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/HazelcastSessionDistributionTests.java, 2021-07-20 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/FileSessionWithMemcacheDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/MongodbSessionDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/AbstractSessionDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/session/GCloudSessionDistributionTests.java, 2021-08-06 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/ModulesTest.java, 2023-01-10 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/OsgiAppTests.java, 2019-06-12 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/GzipModuleTests.java, 2021-07-27 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DistributionTests.java, 2019-02-11 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DynamicListenerTests.java, 2019-06-12 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/LoggingOptionsTests.java, 2021-06-23 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java, 2020-09-21 -tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/AbstractJettyHomeTest.java, 2019-02-11 diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod index 7ff08b15ec42..052786e725c8 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod @@ -13,7 +13,7 @@ webapp [depends] demo-jaas ee8-deploy -ee8-jaas +jaas jdbc ee8-jsp ee8-annotations From eb29894cbe083b1af4d07485dcef1c8c0c5fb39b Mon Sep 17 00:00:00 2001 From: gregw Date: Tue, 11 Apr 2023 11:21:36 +0200 Subject: [PATCH 040/129] WIP --- .../src/main/config/etc/jetty-ee9-openid.xml | 2 +- jetty-home/pom.xml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/jetty-ee9/jetty-ee9-openid/src/main/config/etc/jetty-ee9-openid.xml b/jetty-ee9/jetty-ee9-openid/src/main/config/etc/jetty-ee9-openid.xml index fda52ab002ed..e8e3881cef9e 100644 --- a/jetty-ee9/jetty-ee9-openid/src/main/config/etc/jetty-ee9-openid.xml +++ b/jetty-ee9/jetty-ee9-openid/src/main/config/etc/jetty-ee9-openid.xml @@ -27,7 +27,7 @@ - + diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index b74641e51f22..8643cdec1dd3 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -535,6 +535,14 @@ org.eclipse.jetty jetty-deploy + + org.eclipse.jetty + jetty-security + + + org.eclipse.jetty + jetty-openid + org.eclipse.jetty jetty-util-ajax From 48701d9ddf381b394b7521a17b6d4e1ce9926775 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Tue, 11 Apr 2023 21:17:37 +1000 Subject: [PATCH 041/129] fix merge of jetty-12.0.x openid changes Signed-off-by: Lachlan Roberts --- .../src/main/config/etc/jetty-openid.xml | 3 + .../src/main/config/modules/openid.mod | 3 + .../security/openid/OpenIdAuthenticator.java | 54 +++-- .../openid/OpenIdAuthenticatorFactory.java | 3 +- .../openid/OpenIdAuthenticationTest.java | 186 +++++++++++++++++- .../jetty/security/openid/OpenIdProvider.java | 32 ++- .../src/main/config/etc/jetty-ee10-openid.xml | 0 .../src/main/config/modules/ee10-openid.mod | 0 8 files changed, 252 insertions(+), 29 deletions(-) rename {jetty-core/jetty-openid => jetty-ee10/jetty-ee10-openid}/src/main/config/etc/jetty-ee10-openid.xml (100%) rename {jetty-core/jetty-openid => jetty-ee10/jetty-ee10-openid}/src/main/config/modules/ee10-openid.mod (100%) diff --git a/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml b/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml index e8e3881cef9e..8aa00c86ab85 100644 --- a/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml +++ b/jetty-core/jetty-openid/src/main/config/etc/jetty-openid.xml @@ -38,6 +38,9 @@ + + + diff --git a/jetty-core/jetty-openid/src/main/config/modules/openid.mod b/jetty-core/jetty-openid/src/main/config/modules/openid.mod index 0225276bfd08..399c8494e783 100644 --- a/jetty-core/jetty-openid/src/main/config/modules/openid.mod +++ b/jetty-core/jetty-openid/src/main/config/modules/openid.mod @@ -45,3 +45,6 @@ etc/jetty-openid.xml ## What authentication method to use with the Token Endpoint (client_secret_post, client_secret_basic). # jetty.openid.authMethod=client_secret_post + +## Whether the user should be logged out after the idToken expires. +# jetty.openid.logoutWhenIdTokenIsExpired=false \ No newline at end of file diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java index 97a4e8aa4763..4efa0d086a71 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java @@ -252,12 +252,15 @@ public UserIdentity login(String username, Object credentials, Request request, public void logout(Request request, Response response) { attemptLogoutRedirect(request, response); + logoutWithoutRedirect(request, response); + } + + private void logoutWithoutRedirect(Request request, Response response) + { super.logout(request, response); Session session = request.getSession(false); - if (session == null) return; - synchronized (session) { session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); @@ -267,14 +270,25 @@ public void logout(Request request, Response response) } } + private boolean hasExpiredIdToken(Session session) + { + if (session != null) + { + Map claims = (Map)session.getAttribute(CLAIMS); + if (claims != null) + return OpenIdCredentials.checkExpiry(claims); + } + return false; + } + /** - * This will attempt to redirect the request to the end_session_endpoint, and finally to the {@link #REDIRECT_PATH}. + *

    This will attempt to redirect the request to the end_session_endpoint, and finally to the {@link #REDIRECT_PATH}.

    * - * If end_session_endpoint is defined the request will be redirected to the end_session_endpoint, the optional - * post_logout_redirect_uri parameter will be set if {@link #REDIRECT_PATH} is non-null. + *

    If end_session_endpoint is defined the request will be redirected to the end_session_endpoint, the optional + * post_logout_redirect_uri parameter will be set if {@link #REDIRECT_PATH} is non-null.

    * - * If the end_session_endpoint is not defined then the request will be redirected to {@link #REDIRECT_PATH} if it is a - * non-null value, otherwise no redirection will be done. + *

    If the end_session_endpoint is not defined then the request will be redirected to {@link #REDIRECT_PATH} if it is a + * non-null value, otherwise no redirection will be done.

    * * @param request the request to redirect. */ @@ -390,6 +404,10 @@ protected Fields getParameters(Request request) @Override public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) { + Session session = request.getSession(false); + if (_openIdConfiguration.isLogoutWhenIdTokenIsExpired() && hasExpiredIdToken(session)) + return Constraint.Authentication.REQUIRE; + if (isJSecurityCheck(pathInContext)) return Constraint.Authentication.REQUIRE; if (isErrorPage(pathInContext)) @@ -407,10 +425,18 @@ public Authentication validateRequest(Request request, Response response, Callba if (uri == null) uri = "/"; + Session session = request.getSession(false); + if (_openIdConfiguration.isLogoutWhenIdTokenIsExpired() && hasExpiredIdToken(session)) + { + // After logout, fall through to the code below and send another login challenge. + logoutWithoutRedirect(request, response); + } + try { // Get the Session. - Session session = request.getSession(true); + if (session == null) + session = request.getSession(true); if (session == null) { sendError(request, response, cb, "session could not be created"); @@ -496,10 +522,7 @@ public Authentication validateRequest(Request request, Response response, Callba { if (LOG.isDebugEnabled()) LOG.debug("auth revoked {}", authentication); - synchronized (session) - { - session.removeAttribute(SessionAuthentication.AUTHENTICATED_ATTRIBUTE); - } + logoutWithoutRedirect(request, response); } else { @@ -529,10 +552,11 @@ public Authentication validateRequest(Request request, Response response, Callba } } } + + if (LOG.isDebugEnabled()) + LOG.debug("auth {}", authentication); + return authentication; } - if (LOG.isDebugEnabled()) - LOG.debug("auth {}", authentication); - return authentication; } // If we can't send challenge. diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java index 504183d429e1..ec4b1bdac185 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticatorFactory.java @@ -19,7 +19,6 @@ import org.eclipse.jetty.security.LoginService; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.security.Constraint; public class OpenIdAuthenticatorFactory implements Authenticator.Factory { @@ -28,7 +27,7 @@ public Authenticator getAuthenticator(Server server, Context context, Authentica { LoginService loginService = configuration.getLoginService(); String auth = configuration.getAuthMethod(); - if (Constraint.__OPENID_AUTH.equalsIgnoreCase(auth)) + if (Authenticator.OPENID_AUTH.equalsIgnoreCase(auth)) { // If we have an OpenIdLoginService we can extract the configuration. if (loginService instanceof OpenIdLoginService) diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java index 170f4a5ca8d4..2c429a4a1109 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdAuthenticationTest.java @@ -16,17 +16,25 @@ import java.io.File; import java.io.PrintStream; import java.security.Principal; +import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import org.eclipse.jetty.client.ContentResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.io.Content; +import org.eclipse.jetty.security.AbstractLoginService; import org.eclipse.jetty.security.Authentication; import org.eclipse.jetty.security.Authenticator; import org.eclipse.jetty.security.Constraint; +import org.eclipse.jetty.security.LoginService; +import org.eclipse.jetty.security.RolePrincipal; import org.eclipse.jetty.security.SecurityHandler; +import org.eclipse.jetty.security.UserIdentity; +import org.eclipse.jetty.security.UserPrincipal; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; @@ -38,8 +46,8 @@ import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.util.security.Password; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -47,6 +55,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; @SuppressWarnings("unchecked") public class OpenIdAuthenticationTest @@ -59,8 +68,12 @@ public class OpenIdAuthenticationTest private ServerConnector connector; private HttpClient client; - @BeforeEach - public void setup() throws Exception + public void setup(LoginService loginService) throws Exception + { + setup(loginService, null); + } + + public void setup(LoginService loginService, Consumer configure) throws Exception { server = new Server(); connector = new ServerConnector(server); @@ -69,11 +82,16 @@ public void setup() throws Exception // Set up a local OIDC provider and add its configuration to the Server. openIdProvider = new OpenIdProvider(CLIENT_ID, CLIENT_SECRET); openIdProvider.start(); - server.addBean(new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET)); + + OpenIdConfiguration openIdConfiguration = new OpenIdConfiguration(openIdProvider.getProvider(), CLIENT_ID, CLIENT_SECRET); + if (configure != null) + configure.accept(openIdConfiguration); + server.addBean(openIdConfiguration); // Configure SecurityHandler. SecurityHandler.Mapped securityHandler = new SecurityHandler.Mapped(); assertThat(securityHandler.getKnownAuthenticatorFactories().size(), greaterThanOrEqualTo(2)); + securityHandler.setLoginService(loginService); securityHandler.setAuthMethod(Authenticator.OPENID_AUTH); securityHandler.setRealmName(openIdProvider.getProvider()); @@ -125,6 +143,7 @@ public void stop() throws Exception @Test public void testLoginLogout() throws Exception { + setup(null); openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); String appUriString = "http://localhost:" + connector.getLocalPort(); @@ -135,7 +154,7 @@ public void testLoginLogout() throws Exception String content = response.getContentAsString(); assertThat(content, containsString("not authenticated")); - // Request to log in is success. + // Request to login is success response = client.GET(appUriString + "/login"); assertThat(response.getStatus(), is(HttpStatus.OK_200)); content = response.getContentAsString(); @@ -178,6 +197,163 @@ public void testLoginLogout() throws Exception assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); } + @Test + public void testNestedLoginService() throws Exception + { + AtomicBoolean loggedIn = new AtomicBoolean(true); + setup(new AbstractLoginService() + { + + @Override + protected List loadRoleInfo(UserPrincipal user) + { + return List.of(new RolePrincipal("admin")); + } + + @Override + protected UserPrincipal loadUserInfo(String username) + { + return new UserPrincipal(username, new Password("")); + } + + @Override + public boolean validate(UserIdentity user) + { + if (!loggedIn.get()) + return false; + return super.validate(user); + } + }); + + openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); + + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Request to login is success + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("success")); + + // Now authenticated we can get info + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // The nested login service has supplied the admin role. + response = client.GET(appUriString + "/admin"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + + // This causes any validation of UserIdentity in the LoginService to fail + // causing subsequent requests to be redirected to the auth endpoint for login again. + loggedIn.set(false); + client.setFollowRedirects(false); + response = client.GET(appUriString + "/admin"); + assertThat(response.getStatus(), is(HttpStatus.SEE_OTHER_303)); + String location = response.getHeaders().get(HttpHeader.LOCATION); + assertThat(location, containsString(openIdProvider.getProvider() + "/auth")); + + // Note that we couldn't follow "OpenID Connect RP-Initiated Logout 1.0" because we redirect straight to auth endpoint. + assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); + } + + @Test + public void testExpiredIdToken() throws Exception + { + setup(null, config -> config.setLogoutWhenIdTokenIsExpired(true)); + long idTokenExpiryTime = 2000; + openIdProvider.setIdTokenDuration(idTokenExpiryTime); + openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); + + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Request to login is success + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("success")); + + // Now authenticated we can get info + client.setFollowRedirects(false); + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // After waiting past ID_Token expiry time we are no longer authenticated. + // Even though this page is non-mandatory authentication the OpenId attributes should be cleared. + // This then attempts re-authorization the first time even though it is non-mandatory page. + Thread.sleep(idTokenExpiryTime * 2); + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.SEE_OTHER_303)); + assertThat(response.getHeaders().get(HttpHeader.LOCATION), startsWith(openIdProvider.getProvider() + "/auth")); + + // User was never redirected to logout page. + assertThat(openIdProvider.getLoggedInUsers().getCurrent(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getMax(), equalTo(1L)); + assertThat(openIdProvider.getLoggedInUsers().getTotal(), equalTo(1L)); + } + + @Test + public void testExpiredIdTokenDisabled() throws Exception + { + setup(null); + long idTokenExpiryTime = 2000; + openIdProvider.setIdTokenDuration(idTokenExpiryTime); + openIdProvider.setUser(new OpenIdProvider.User("123456789", "Alice")); + + String appUriString = "http://localhost:" + connector.getLocalPort(); + + // Initially not authenticated + ContentResponse response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + String content = response.getContentAsString(); + assertThat(content, containsString("not authenticated")); + + // Request to login is success + response = client.GET(appUriString + "/login"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("success")); + + // Now authenticated we can get info + client.setFollowRedirects(false); + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + + // After waiting past ID_Token expiry time we are still authenticated because logoutWhenIdTokenIsExpired is false by default. + Thread.sleep(idTokenExpiryTime * 2); + response = client.GET(appUriString + "/"); + assertThat(response.getStatus(), is(HttpStatus.OK_200)); + content = response.getContentAsString(); + assertThat(content, containsString("userId: 123456789")); + assertThat(content, containsString("name: Alice")); + assertThat(content, containsString("email: Alice@example.com")); + } + public static class LoginPage extends ContextHandler { public LoginPage(String contextPath) diff --git a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java index acce4fc03e34..512237b8c6ec 100644 --- a/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java +++ b/jetty-core/jetty-openid/src/test/java/org/eclipse/jetty/security/openid/OpenIdProvider.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -61,13 +62,14 @@ public class OpenIdProvider extends ContainerLifeCycle private String provider; private User preAuthedUser; private final CounterStatistic loggedInUsers = new CounterStatistic(); + private long _idTokenDuration = Duration.ofSeconds(10).toMillis(); public static void main(String[] args) throws Exception { String clientId = "CLIENT_ID123"; String clientSecret = "PASSWORD123"; int port = 5771; - String redirectUri = "http://localhost:8080/openid/auth"; + String redirectUri = "http://localhost:8080/j_security_check"; OpenIdProvider openIdProvider = new OpenIdProvider(clientId, clientSecret); openIdProvider.addRedirectUri(redirectUri); @@ -102,6 +104,16 @@ public OpenIdProvider(String clientId, String clientSecret) addBean(server); } + public void setIdTokenDuration(long duration) + { + _idTokenDuration = duration; + } + + public long getIdTokenDuration() + { + return _idTokenDuration; + } + public void join() throws InterruptedException { server.join(); @@ -313,11 +325,11 @@ public boolean handle(Request request, Response response, Callback callback) thr } String accessToken = "ABCDEFG"; - long expiry = System.currentTimeMillis() + Duration.ofMinutes(10).toMillis(); + long accessTokenDuration = Duration.ofMinutes(10).toSeconds(); String content = "{" + "\"access_token\": \"" + accessToken + "\"," + - "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId)) + "\"," + - "\"expires_in\": " + expiry + "," + + "\"id_token\": \"" + JwtEncoder.encode(user.getIdToken(provider, clientId, _idTokenDuration)) + "\"," + + "\"expires_in\": " + accessTokenDuration + "," + "\"token_type\": \"Bearer\"" + "}"; @@ -410,10 +422,10 @@ public String getSubject() return subject; } - public String getIdToken(String provider, String clientId) + public String getIdToken(String provider, String clientId, long duration) { - long expiry = System.currentTimeMillis() + Duration.ofMinutes(1).toMillis(); - return JwtEncoder.createIdToken(provider, clientId, subject, name, expiry); + long expiryTime = Instant.now().plusMillis(duration).getEpochSecond(); + return JwtEncoder.createIdToken(provider, clientId, subject, name, expiryTime); } @Override @@ -423,5 +435,11 @@ public boolean equals(Object obj) return false; return Objects.equals(subject, ((User)obj).subject) && Objects.equals(name, ((User)obj).name); } + + @Override + public int hashCode() + { + return Objects.hash(subject, name); + } } } diff --git a/jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml b/jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml similarity index 100% rename from jetty-core/jetty-openid/src/main/config/etc/jetty-ee10-openid.xml rename to jetty-ee10/jetty-ee10-openid/src/main/config/etc/jetty-ee10-openid.xml diff --git a/jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod b/jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod similarity index 100% rename from jetty-core/jetty-openid/src/main/config/modules/ee10-openid.mod rename to jetty-ee10/jetty-ee10-openid/src/main/config/modules/ee10-openid.mod From 061197dc957ac6b865bba441eb856cef163b8f6c Mon Sep 17 00:00:00 2001 From: gregw Date: Tue, 11 Apr 2023 21:51:14 +0200 Subject: [PATCH 042/129] Update openid to access session --- .../eclipse/jetty/security/openid/OpenIdAuthenticator.java | 5 +++-- .../main/java/org/eclipse/jetty/security/Authenticator.java | 6 +++++- .../java/org/eclipse/jetty/security/SecurityHandler.java | 2 +- .../jetty/security/authentication/FormAuthenticator.java | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java index 4efa0d086a71..8e51f09d7a52 100644 --- a/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java +++ b/jetty-core/jetty-openid/src/main/java/org/eclipse/jetty/security/openid/OpenIdAuthenticator.java @@ -21,6 +21,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.ExecutionException; +import java.util.function.Function; import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.http.HttpMethod; @@ -402,9 +403,9 @@ protected Fields getParameters(Request request) } @Override - public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) + public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing, Function getSession) { - Session session = request.getSession(false); + Session session = getSession.apply(false); if (_openIdConfiguration.isLogoutWhenIdTokenIsExpired() && hasExpiredIdToken(session)) return Constraint.Authentication.REQUIRE; diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java index 9b2222a4be7c..8eaa1c3021e1 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/Authenticator.java @@ -14,12 +14,14 @@ package org.eclipse.jetty.security; import java.util.Set; +import java.util.function.Function; import org.eclipse.jetty.security.Authentication.User; import org.eclipse.jetty.server.Context; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.Response; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.Session; import org.eclipse.jetty.util.Callback; /** @@ -74,11 +76,13 @@ default Request prepareRequest(Request request, Authentication authentication) * this authenticator. This is typically used to vary protection on special URIs known to a * specific {@link Authenticator} (e.g. /j_security_check for * the {@link org.eclipse.jetty.security.authentication.FormAuthenticator}. + * * @param pathInContext The pathInContext to potentially constrain. * @param existing The existing authentication constraint for the pathInContext determined independently of {@link Authenticator} + * @param getSession Function to get or create a {@link Session}. * @return The {@link Constraint.Authentication} to apply. */ - default Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) + default Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing, Function getSession) { return existing == null ? Constraint.Authentication.REQUIRE_NONE : existing; } diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index 2277ff6b0bd8..b690c0513f86 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -445,7 +445,7 @@ public boolean handle(Request request, Response response, Callback callback) thr // Determine Constraint.Authentication Constraint.Authentication constraintAuthentication = constraint.getAuthentication(); - constraintAuthentication = _authenticator.getConstraintAuthentication(pathInContext, constraintAuthentication); + constraintAuthentication = _authenticator.getConstraintAuthentication(pathInContext, constraintAuthentication, request::getSession); boolean mustValidate = constraintAuthentication != Constraint.Authentication.REQUIRE_NONE; try diff --git a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java index 9086dc78ffba..c2e6ba801f25 100644 --- a/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java +++ b/jetty-core/jetty-security/src/main/java/org/eclipse/jetty/security/authentication/FormAuthenticator.java @@ -14,6 +14,7 @@ package org.eclipse.jetty.security.authentication; import java.util.concurrent.ExecutionException; +import java.util.function.Function; import org.eclipse.jetty.http.HttpMethod; import org.eclipse.jetty.http.HttpStatus; @@ -242,7 +243,7 @@ protected String encodeURL(String url) } @Override - public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing) + public Constraint.Authentication getConstraintAuthentication(String pathInContext, Constraint.Authentication existing, Function getSession) { if (isJSecurityCheck(pathInContext)) return Constraint.Authentication.REQUIRE; From 602307895e1cdc6d7e39f46e9de8d45a47f6a516 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 11:55:13 +0200 Subject: [PATCH 043/129] WIP --- .../src/main/config/modules/jaas.mod | 6 ++-- .../src/main/config/modules/ee8-demo-jaas.mod | 5 --- .../embedded-jetty-web-for-webbundle.xml | 2 +- .../main/config/modules/ee8-demo-jetty.mod | 2 +- .../src/main/config/modules/ee8-demo-spec.mod | 2 +- .../config/modules/demo.d/ee9-demo-jaas.xml | 2 +- .../src/main/config/modules/ee9-demo-jaas.mod | 5 --- .../src/main/etc/ee9-demo-login.conf | 5 --- .../embedded-jetty-web-for-webbundle.xml | 2 +- .../main/config/modules/ee9-demo-jetty.mod | 2 +- .../src/main/config/modules/ee9-demo-spec.mod | 2 +- .../templates/annotations-context-header.xml | 2 +- .../src/main/resources/modules/demo-jaas.mod | 8 +++-- .../resources/modules/demo.d/demo-login.conf | 18 ++-------- .../modules/demo.d/demo-login.properties | 0 ...properties => jetty-demo-realm.properties} | 0 ...e9-demo-realm.xml => jetty-demo-realm.xml} | 2 +- .../modules/demo.d/jetty-ee8-demo-realm.xml | 35 ------------------- .../demo.d/jetty-ee9-demo-realm.properties | 21 ----------- .../main/resources/modules/ee8-demo-realm.mod | 24 ------------- .../main/resources/modules/ee9-demo-realm.mod | 14 +++----- 21 files changed, 25 insertions(+), 134 deletions(-) delete mode 100644 jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/etc/ee9-demo-login.conf rename jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/demo.d/ee9-demo-login.properties => jetty-home/src/main/resources/modules/demo.d/demo-login.properties (100%) rename jetty-home/src/main/resources/modules/demo.d/{jetty-ee8-demo-realm.properties => jetty-demo-realm.properties} (100%) rename jetty-home/src/main/resources/modules/demo.d/{jetty-ee9-demo-realm.xml => jetty-demo-realm.xml} (97%) delete mode 100644 jetty-home/src/main/resources/modules/demo.d/jetty-ee8-demo-realm.xml delete mode 100644 jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.properties delete mode 100644 jetty-home/src/main/resources/modules/ee8-demo-realm.mod diff --git a/jetty-core/jetty-server/src/main/config/modules/jaas.mod b/jetty-core/jetty-server/src/main/config/modules/jaas.mod index c12d1fa9aee0..3f35dcfd393e 100644 --- a/jetty-core/jetty-server/src/main/config/modules/jaas.mod +++ b/jetty-core/jetty-server/src/main/config/modules/jaas.mod @@ -3,12 +3,12 @@ [description] Enables JAAS for deployed web applications. -[environment] -ee8 - [depend] security +[before] +deploy + [xml] etc/jetty-jaas.xml diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod index 052786e725c8..379100226e8d 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod @@ -22,9 +22,4 @@ ext [files] basehome:modules/demo.d/ee8-demo-jaas.xml|webapps/ee8-demo-jaas.xml basehome:modules/demo.d/ee8-demo-jaas.properties|webapps/ee8-demo-jaas.properties -basehome:modules/demo.d/ee8-demo-login.properties|etc/ee8-demo-login.properties maven://org.eclipse.jetty.ee8.demos/jetty-ee8-demo-jaas-webapp/${jetty.version}/war|webapps/ee8-demo-jaas.war - -[ini] -# Enable security via jaas, and configure it -jetty.jaas.login.conf?=etc/demo-login.conf diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml index 85875386a6be..6a7eaa3f6678 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jetty-webapp/src/main/assembly/embedded-jetty-web-for-webbundle.xml @@ -52,7 +52,7 @@ detected. Test Realm - /ee9-demo-realm.properties + /demo-realm.properties - - - - - - - - - - - - - - - - - - Test Realm - - false - - - - - - org.eclipse.jetty - - demo-realm is deployed. DO NOT USE IN PRODUCTION! - - - diff --git a/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.properties b/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.properties deleted file mode 100644 index 9d88b852b7f8..000000000000 --- a/jetty-home/src/main/resources/modules/demo.d/jetty-ee9-demo-realm.properties +++ /dev/null @@ -1,21 +0,0 @@ -# -# This file defines users passwords and roles for a HashUserRealm -# -# The format is -# : [, ...] -# -# Passwords may be clear text, obfuscated or checksummed. The class -# org.eclipse.util.Password should be used to generate obfuscated -# passwords or password checksums -# -# If DIGEST Authentication is used, the password must be in a recoverable -# format, either plain text or OBF:. -# -jetty: MD5:164c88b302622e17050af52c89945d44,user -admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin,user -other: OBF:1xmk1w261u9r1w1c1xmq,user -plain: plain,user -user: password,user - -# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password -digest: MD5:6e120743ad67abfbc385bc2bb754e297,user diff --git a/jetty-home/src/main/resources/modules/ee8-demo-realm.mod b/jetty-home/src/main/resources/modules/ee8-demo-realm.mod deleted file mode 100644 index 7be77416f947..000000000000 --- a/jetty-home/src/main/resources/modules/ee8-demo-realm.mod +++ /dev/null @@ -1,24 +0,0 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - -[description] -Configure a demo authentication realm. - -[environment] -ee8 - -[tags] -demo - -[depends] -ee8-security - -[xml] -etc/jetty-ee8-demo-realm.xml - -[files] -basehome:modules/demo.d/jetty-ee8-demo-realm.xml|etc/jetty-ee8-demo-realm.xml -basehome:modules/demo.d/jetty-ee8-demo-realm.properties|etc/jetty-ee8-demo-realm.properties - -[ini-template] -# Create and configure the test realm -jetty.demo.realm=etc/jetty-ee8-realm.properties diff --git a/jetty-home/src/main/resources/modules/ee9-demo-realm.mod b/jetty-home/src/main/resources/modules/ee9-demo-realm.mod index 60ff9e2bdda2..fa09d59693dd 100644 --- a/jetty-home/src/main/resources/modules/ee9-demo-realm.mod +++ b/jetty-home/src/main/resources/modules/ee9-demo-realm.mod @@ -3,23 +3,19 @@ [description] Configure a demo authentication realm. -[environment] -ee9 - [tags] demo [depends] -ee9-servlet -ee9-security +security [xml] -etc/jetty-ee9-demo-realm.xml +etc/jetty-demo-realm.xml [files] -basehome:modules/demo.d/jetty-ee9-demo-realm.xml|etc/jetty-ee9-demo-realm.xml -basehome:modules/demo.d/jetty-ee9-demo-realm.properties|etc/jetty-ee9-demo-realm.properties +basehome:modules/demo.d/jetty-demo-realm.xml|etc/jetty-demo-realm.xml +basehome:modules/demo.d/jetty-demo-realm.properties|etc/jetty-demo-realm.properties [ini-template] # Create and configure the test realm -jetty.demo.realm=etc/jetty-ee9-demo-realm.properties +jetty.demo.realm=etc/jetty-demo-realm.properties From 4aee191dd3455c55399408e15643a4ec98f3104f Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 14:01:28 +0200 Subject: [PATCH 044/129] Renamed "Core" environment to "Server" Maintained a "Core" environment for use by deployer for apps that only use core classes plus whatever else is configured for the core environment. --- .../deploy/providers/ContextProvider.java | 4 +- .../deploy/providers/ScanningAppProvider.java | 10 +-- .../java/org/eclipse/jetty/server/Server.java | 21 ----- .../org/eclipse/jetty/start/BaseBuilder.java | 4 +- .../org/eclipse/jetty/start/Environment.java | 9 ++- .../java/org/eclipse/jetty/start/Main.java | 26 +++--- .../java/org/eclipse/jetty/start/Modules.java | 8 +- .../org/eclipse/jetty/start/StartArgs.java | 79 ++++++++++--------- .../jetty/start/IncludeJettyDirTest.java | 2 +- .../org/eclipse/jetty/start/MainTest.java | 6 +- .../org/eclipse/jetty/start/ModulesTest.java | 8 +- .../jetty/start/usecases/AbstractUseCase.java | 6 +- .../jetty/start/usecases/BasicTest.java | 4 +- .../jetty/util/component/Environment.java | 21 ++++- 14 files changed, 104 insertions(+), 104 deletions(-) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java index 21f3e351ecf6..ad50028c7255 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java @@ -360,7 +360,7 @@ public void initializeDefaults(Object context) xmlc.setJettyStandardIdsAndProperties(getDeploymentManager().getServer(), path); // If it is a core context environment, then look for a classloader - ClassLoader coreContextClassLoader = Environment.CORE.equals(environment) ? findCoreContextClassLoader(path) : null; + ClassLoader coreContextClassLoader = Environment.SERVER.equals(environment) ? findCoreContextClassLoader(path) : null; if (coreContextClassLoader != null) Thread.currentThread().setContextClassLoader(coreContextClassLoader); @@ -455,7 +455,7 @@ protected ClassLoader findCoreContextClassLoader(Path path) throws IOException if (urls.isEmpty()) return null; - return new URLClassLoader(urls.toArray(new URL[0]), Environment.CORE.getClassLoader()); + return new URLClassLoader(urls.toArray(new URL[0]), Environment.SERVER.getClassLoader()); } protected void initializeContextPath(ContextHandler context, Path path) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java index 96867e23b5e1..b4d93130994a 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java @@ -161,13 +161,13 @@ protected App createApp(Path path) Files.exists(path.getParent().resolve(basename + ".WAR")) || Files.exists(path.getParent().resolve(basename + "/WEB-INF"))); boolean coreProvider = _deploymentManager.getAppProviders().stream() - .map(AppProvider::getEnvironmentName).anyMatch(Environment.CORE.getName()::equals); + .map(AppProvider::getEnvironmentName).anyMatch(Environment.SERVER.getName()::equals); // TODO review these heuristics... or even if we should have them at all if (isWebapp || (Files.isDirectory(path) && _deploymentManager.getDefaultEnvironmentName() != null)) environmentName = _deploymentManager.getDefaultEnvironmentName(); else if (coreProvider) - environmentName = Environment.CORE.getName(); + environmentName = Environment.SERVER.getName(); if (StringUtil.isNotBlank(environmentName)) { @@ -213,10 +213,10 @@ protected void doStart() throws Exception throw new IllegalStateException("No configuration dir specified"); if (_environmentName == null) { - List nonCore = Environment.getAll().stream().filter(environment -> !environment.equals(Environment.CORE)).toList(); - if (nonCore.size() != 1) + List nonServer = Environment.getAll().stream().filter(environment -> !environment.equals(Environment.SERVER)).toList(); + if (nonServer.size() != 1) throw new IllegalStateException("No environment configured"); - _environmentName = nonCore.get(0).getName(); + _environmentName = nonServer.get(0).getName(); } Environment environment = Environment.get(_environmentName); diff --git a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index b3cf953e3d93..60a8b14e27bb 100644 --- a/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -931,25 +931,4 @@ public String toString() return "ServerContext@%x".formatted(Server.this.hashCode()); } } - - private class ServerEnvironment extends Attributes.Wrapper implements Environment - { - private ServerEnvironment() - { - super(Server.this); - } - - @Override - public String getName() - { - return "Server"; - } - - @Override - public ClassLoader getClassLoader() - { - return Server.class.getClassLoader(); - } - } - } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java index ba73d40bc8e5..2a943bbb358c 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java @@ -293,13 +293,13 @@ public boolean accept(Path entry) // if (explicitly added and ini file modified) if (startArgs.getStartModules().contains(module.getName())) { - ini = builder.get().addModule(module, startArgs.getCoreEnvironment().getProperties()); + ini = builder.get().addModule(module, startArgs.getServerEnvironment().getProperties()); if (ini != null) modified.set(true); } for (String file : module.getFiles()) { - files.add(new FileArg(module, startArgs.getCoreEnvironment().getProperties().expand(file))); + files.add(new FileArg(module, startArgs.getServerEnvironment().getProperties().expand(file))); } } } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java index 42e990afef49..45e6a93b391c 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java @@ -23,6 +23,11 @@ import java.util.List; import java.util.Properties; +/** + * A start environment that contains the configurations that will be used to + * build a runtime {@code org.eclipse.jetty.util.component.Environment} via + * {@code --env} arguments passed to {@code org.eclipse.jetty.xml.XmlConfiguration#main(java.lang.String...)} + */ public class Environment { private final BaseHome _baseHome; @@ -79,8 +84,8 @@ public void addPropertyFileRef(String arg) public void addUniquePropertyFile(String propertyFileRef, Path propertyFile) throws IOException { - if (!"core".equalsIgnoreCase(getName())) - throw new IllegalStateException("Property files not supported in non core environments"); + if (!"server".equalsIgnoreCase(getName())) + throw new IllegalStateException("Property files not supported in non Server environments"); if (!FS.canReadFile(propertyFile)) { diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index 0c58f46ca7c2..bba618385d7d 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -239,14 +239,14 @@ public void listConfig(PrintStream out, StartArgs args) args.dumpSystemProperties(out); - Environment coreEnvironment = args.getCoreEnvironment(); + Environment serverEnvironment = args.getServerEnvironment(); - // Dump Core Properties - coreEnvironment.dumpProperties(out); - // Dump Core Classpath - dumpClasspathWithVersions(coreEnvironment.getName(), out, coreEnvironment.getClasspath()); - // Dump Core Resolved XMLs - coreEnvironment.dumpActiveXmls(out); + // Dump Server Properties + serverEnvironment.dumpProperties(out); + // Dump Server Classpath + dumpClasspathWithVersions(serverEnvironment.getName(), out, serverEnvironment.getClasspath()); + // Dump Server Resolved XMLs + serverEnvironment.dumpActiveXmls(out); for (Environment environment : args.getEnvironments()) { @@ -317,7 +317,7 @@ public StartArgs processCommandLine(String[] cmdLine) throws Exception Props props = baseHome.getConfigSources().getProps(); Prop home = props.getProp(BaseHome.JETTY_HOME); - Props argProps = args.getCoreEnvironment().getProperties(); + Props argProps = args.getServerEnvironment().getProperties(); if (!argProps.containsKey(BaseHome.JETTY_HOME)) argProps.setProperty(home); argProps.setProperty(BaseHome.JETTY_HOME + ".uri", @@ -390,7 +390,7 @@ public void start(StartArgs args) throws IOException, InterruptedException StartLog.debug("StartArgs: %s", args); // Get Desired Classpath based on user provided Active Options. - Classpath classpath = args.getCoreEnvironment().getClasspath(); + Classpath classpath = args.getServerEnvironment().getClasspath(); // Show the usage information and return if (args.isHelp()) @@ -401,7 +401,7 @@ public void start(StartArgs args) throws IOException, InterruptedException // Show the version information and return if (args.isListClasspath()) { - dumpClasspathWithVersions("Core", System.out, classpath); + dumpClasspathWithVersions("Server", System.out, classpath); } // Show configuration @@ -428,7 +428,7 @@ public void start(StartArgs args) throws IOException, InterruptedException Path outputFile = baseHome.getBasePath(args.getModuleGraphFilename()); System.out.printf("Generating GraphViz Graph of Jetty Modules at %s%n", baseHome.toShortForm(outputFile)); ModuleGraphWriter writer = new ModuleGraphWriter(); - writer.config(args.getCoreEnvironment().getProperties()); + writer.config(args.getServerEnvironment().getProperties()); writer.write(args.getAllModules(), outputFile); } @@ -451,7 +451,7 @@ public void start(StartArgs args) throws IOException, InterruptedException { for (StartIni ini : config.getStartInis()) { - ini.update(baseHome, args.getCoreEnvironment().getProperties()); + ini.update(baseHome, args.getServerEnvironment().getProperties()); } } } @@ -534,7 +534,7 @@ public void start() throws Exception private void doStop(StartArgs args) { - Props argsProps = args.getCoreEnvironment().getProperties(); + Props argsProps = args.getServerEnvironment().getProperties(); final Prop stopHostProp = argsProps.getProp("STOP.HOST", true); final Prop stopPortProp = argsProps.getProp("STOP.PORT", true); final Prop stopKeyProp = argsProps.getProp("STOP.KEY", true); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java index ca5292610e85..a9255306c9de 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -56,7 +56,7 @@ public Modules(BaseHome basehome, StartArgs args) this._args = args; // Allow override mostly for testing - if (!args.getCoreEnvironment().getProperties().containsKey("java.version")) + if (!args.getServerEnvironment().getProperties().containsKey("java.version")) { String javaVersion = System.getProperty("java.version"); if (javaVersion != null) @@ -458,13 +458,13 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, newlyEnabled.add(module.getName()); // Expand module properties - module.expandDependencies(_args.getCoreEnvironment().getProperties()); + module.expandDependencies(_args.getServerEnvironment().getProperties()); // Apply default configuration if (module.hasDefaultConfig()) { String source = module.getName() + "[ini]"; - Environment environment = _args.getCoreEnvironment(); + Environment environment = _args.getServerEnvironment(); environment = _args.parse(environment, "--module=" + module.getName(), source); for (String line : module.getIniSection()) @@ -497,7 +497,7 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, Path file = _baseHome.getPath("modules/" + dependentModule + ".mod"); if (!isConditional || Files.exists(file)) { - registerModule(file).expandDependencies(_args.getCoreEnvironment().getProperties()); + registerModule(file).expandDependencies(_args.getServerEnvironment().getProperties()); providers = _provided.get(dependentModule); if (providers == null || providers.isEmpty()) throw new UsageException("Module %s does not provide %s", _baseHome.toShortForm(file), dependentModule); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index fcc0957eea63..2b4e9fba7739 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -32,6 +32,7 @@ import java.util.Map; import java.util.Set; import java.util.StringTokenizer; +import java.util.TreeMap; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.stream.Collectors; @@ -133,7 +134,7 @@ public class StartArgs private final Map systemPropertySource = new HashMap<>(); - private static final Map _environments = new HashMap<>(); + private static final Map _environments = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); // jetty.base - build out commands /** @@ -193,25 +194,25 @@ public class StartArgs private boolean allowInsecureHttpDownloads = false; private boolean approveAllLicenses = false; - private final Environment coreEnvironment; + private final Environment serverEnvironment; public StartArgs(BaseHome baseHome) { this.baseHome = baseHome; - coreEnvironment = new Environment("Core", baseHome); + serverEnvironment = new Environment("Server", baseHome); } public void expandEnvironments(List activeModules) throws IOException { // 5) Lib & XML Expansion / Resolution expandSystemProperties(); - coreEnvironment.resolveLibs(); + serverEnvironment.resolveLibs(); expandModules(activeModules); // 6) Resolve Extra XMLs // 7) JPMS Expansion // 8) Resolve Property Files - coreEnvironment.resolve(); + serverEnvironment.resolve(); // 7) JPMS Expansion resolveJPMS(activeModules); // TODO we need layers @@ -224,9 +225,9 @@ public void expandEnvironments(List activeModules) throws IOException } } - public Environment getCoreEnvironment() + public Environment getServerEnvironment() { - return coreEnvironment; + return serverEnvironment; } public Collection getEnvironments() @@ -256,7 +257,7 @@ private void addFile(Module module, String uriLocation) private Environment getEnvironment(Module module) { String envName = module == null ? null : module.getEnvironment(); - Environment environment = envName == null ? getCoreEnvironment() : getEnvironment(envName); + Environment environment = envName == null ? getServerEnvironment() : getEnvironment(envName); return environment; } @@ -278,16 +279,16 @@ public void dumpJavaEnvironment(PrintStream out) dumpSystemProperty(out, "user.language"); dumpSystemProperty(out, "user.country"); - // Jetty Environment + // Jetty Server Environment out.println(); - out.println("Jetty Core Environment:"); - out.println("-----------------------"); - Environment coreEnvironment = getCoreEnvironment(); - coreEnvironment.dumpProperty(out, JETTY_VERSION_KEY); - coreEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); - coreEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); - coreEnvironment.dumpProperty(out, "jetty.home"); - coreEnvironment.dumpProperty(out, "jetty.base"); + out.println("Jetty Server Environment:"); + out.println("-------------------------"); + Environment serverEnvironment = getServerEnvironment(); + serverEnvironment.dumpProperty(out, JETTY_VERSION_KEY); + serverEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); + serverEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); + serverEnvironment.dumpProperty(out, "jetty.home"); + serverEnvironment.dumpProperty(out, "jetty.base"); // Jetty Configuration Environment out.println(); @@ -371,13 +372,13 @@ private void ensureSystemPropertySet(String key) return; // done } - if (getCoreEnvironment().getProperties().containsKey(key)) + if (getServerEnvironment().getProperties().containsKey(key)) { - Prop prop = getCoreEnvironment().getProperties().getProp(key); + Prop prop = getServerEnvironment().getProperties().getProp(key); if (prop == null) return; // no value set; - String val = getCoreEnvironment().getProperties().expand(prop.value); + String val = getServerEnvironment().getProperties().expand(prop.value); // setup system property systemPropertySource.put(key, "property:" + prop.source); System.setProperty(key, val); @@ -393,10 +394,10 @@ public void expandSystemProperties() for (String key : systemPropertySource.keySet()) { - String value = getCoreEnvironment().getProperties().getString(key); + String value = getServerEnvironment().getProperties().getString(key); if (value != null) { - String expanded = getCoreEnvironment().getProperties().expand(value); + String expanded = getServerEnvironment().getProperties().expand(value); if (!value.equals(expanded)) System.setProperty(key, expanded); } @@ -529,7 +530,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException cmd.addRawArg("-Djetty.home=" + baseHome.getHome()); cmd.addRawArg("-Djetty.base=" + baseHome.getBase()); - Props properties = coreEnvironment.getProperties(); + Props properties = serverEnvironment.getProperties(); for (String x : getJvmArgSources().keySet()) { if (x.startsWith("-D")) @@ -559,7 +560,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException { if (isJPMS()) { - Map> dirsAndFiles = StreamSupport.stream(coreEnvironment.getClasspath().spliterator(), false) + Map> dirsAndFiles = StreamSupport.stream(serverEnvironment.getClasspath().spliterator(), false) .collect(Collectors.groupingBy(Files::isDirectory)); Set files = new HashSet<>(dirsAndFiles.get(false)); @@ -567,7 +568,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // ee9 may use jakarta.annotation 2.0.0 // but ee10 use jakarta.annotation 2.1.0 // and both having different module-info. - getEnvironments().stream().filter(environment -> !environment.getName().equals(coreEnvironment.getName())) + getEnvironments().stream().filter(environment -> !environment.getName().equals(serverEnvironment.getName())) .forEach(environment -> { Map> dirsAndFilesModules = StreamSupport.stream(environment.getClasspath().spliterator(), false) @@ -609,7 +610,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException else { cmd.addRawArg("--class-path"); - cmd.addRawArg(coreEnvironment.getClasspath().toString()); + cmd.addRawArg(serverEnvironment.getClasspath().toString()); } } @@ -623,7 +624,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // do properties and xmls if (parts.contains("args")) { - Props properties = coreEnvironment.getProperties(); + Props properties = serverEnvironment.getProperties(); if (dryRun && execProperties == null) { // pass properties as args @@ -653,12 +654,12 @@ else if (properties.size() > 0) cmd.addRawArg(propPath.toAbsolutePath().toString()); } - for (Path xml : coreEnvironment.getXmlFiles()) + for (Path xml : serverEnvironment.getXmlFiles()) { cmd.addRawArg(xml.toAbsolutePath().toString()); } - for (Path propertyFile : coreEnvironment.getPropertyFiles()) + for (Path propertyFile : serverEnvironment.getPropertyFiles()) { cmd.addRawArg(propertyFile.toAbsolutePath().toString()); } @@ -668,7 +669,7 @@ else if (properties.size() > 0) { for (Environment environment : getEnvironments()) { - if (environment == coreEnvironment) + if (environment == serverEnvironment) continue; cmd.addArg("--env"); cmd.addArg(environment.getName()); @@ -702,7 +703,7 @@ private void resolveJPMS(List activeModules) throws IOException { for (String line : module.getJPMS()) { - line = getCoreEnvironment().getProperties().expand(line); + line = getServerEnvironment().getProperties().expand(line); String directive; if (line.startsWith(directive = "add-modules:")) { @@ -793,7 +794,7 @@ private void generateJpmsArgs(CommandLineBuilder cmd) public String getMainClassname() { String mainClass = System.getProperty("jetty.server", isJPMS() ? MODULE_MAIN_CLASS : MAIN_CLASS); - Prop mainClassProp = getCoreEnvironment().getProperties().getProp("main.class", true); + Prop mainClassProp = getServerEnvironment().getProperties().getProp("main.class", true); if (mainClassProp != null) return mainClassProp.value; return mainClass; @@ -801,7 +802,7 @@ public String getMainClassname() public String getMavenLocalRepoDir() { - String localRepo = getCoreEnvironment().getProperties().getString("maven.local.repo"); + String localRepo = getServerEnvironment().getProperties().getString("maven.local.repo"); if (Utils.isBlank(localRepo)) localRepo = System.getenv("JETTY_MAVEN_LOCAL_REPO"); @@ -1003,8 +1004,8 @@ public void parse(ConfigSources sources) ListIterator iter = sources.reverseListIterator(); while (iter.hasPrevious()) { - // Each source starts with core environment. - Environment environment = getCoreEnvironment(); + // Each source starts with server environment. + Environment environment = getServerEnvironment(); ConfigSource source = iter.previous(); for (RawArgs.Entry arg : source.getArgs()) @@ -1264,7 +1265,7 @@ public Environment parse(Environment environment, String arg, String source) selectModules(source, moduleNames); Module module = getAllModules().get(moduleNames.get(moduleNames.size() - 1)); String envName = module == null ? null : module.getEnvironment(); - return envName == null ? coreEnvironment : getEnvironment(envName); + return envName == null ? serverEnvironment : getEnvironment(envName); } // Skip [files] validation on a module @@ -1284,7 +1285,7 @@ public Environment parse(Environment environment, String arg, String source) } if (environment == null) - environment = getCoreEnvironment(); + environment = getServerEnvironment(); // Arbitrary Libraries if (arg.startsWith("--lib=") || arg.startsWith("--libs=")) @@ -1431,7 +1432,7 @@ public void setAllModules(Modules allModules) public void setProperty(Environment environment, String key, String value, String source) { if (environment == null) - environment = getCoreEnvironment(); + environment = getServerEnvironment(); Props properties = environment.getProperties(); // Special / Prevent override from start.ini's @@ -1501,6 +1502,6 @@ public void setRun(boolean run) public String toString() { return String.format("%s[enabledModules=%s, xml=%s, properties=%s, jvmArgs=%s]", - getClass().getSimpleName(), modules, getCoreEnvironment().getXmlFiles(), getCoreEnvironment().getProperties(), jvmArgSources.keySet()); + getClass().getSimpleName(), modules, getServerEnvironment().getXmlFiles(), getServerEnvironment().getProperties(), jvmArgSources.keySet()); } } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java index a0a834ebd27a..fe19f0b9a4a6 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java @@ -59,7 +59,7 @@ public void assertSearchOrder(List expectedSearchOrder) public void assertProperty(String key, String expectedValue) { - Prop prop = args.getCoreEnvironment().getProperties().getProp(key); + Prop prop = args.getServerEnvironment().getProperties().getProp(key); String prefix = "Prop[" + key + "]"; assertThat(prefix + " should have a value", prop, notNullValue()); assertThat(prefix + " value", prop.value, is(expectedValue)); diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java index e5bf1652a0e8..4d238bfcbca4 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java @@ -58,9 +58,9 @@ public void testStopProcessing() throws Exception StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[0])); // assertEquals(0, args.getEnabledModules().size(), "--stop should not build module tree"); - assertEquals("10000", args.getCoreEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); - assertEquals("foo", args.getCoreEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); - assertEquals("300", args.getCoreEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); + assertEquals("10000", args.getServerEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); + assertEquals("foo", args.getServerEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); + assertEquals("300", args.getServerEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); } @Test diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java index c643a122e51c..d74010504349 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java @@ -69,7 +69,7 @@ public void testLoadAllModules() throws IOException modules.registerAll(); // Check versions - String platformProperty = args.getCoreEnvironment().getProperties().getString("java.version.platform"); + String platformProperty = args.getServerEnvironment().getProperties().getString("java.version.platform"); assertThat("java.version.platform", Integer.parseInt(platformProperty), greaterThanOrEqualTo(8)); List moduleNames = new ArrayList<>(); @@ -247,7 +247,7 @@ public void testResolveNotRequiredModuleNotFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getCoreEnvironment().getProperties(); + Props props = args.getServerEnvironment().getProperties(); assertThat(props.getString("bar.name"), is(nullValue())); } @@ -298,7 +298,7 @@ public void testResolveNotRequiredModuleFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getCoreEnvironment().getProperties(); + Props props = args.getServerEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dive")); } @@ -349,7 +349,7 @@ public void testResolveNotRequiredModuleFoundDynamic() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getCoreEnvironment().getProperties(); + Props props = args.getServerEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dynamic")); } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java index 651a626495be..82b7b51480fe 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java @@ -157,7 +157,7 @@ public static class ExecResults public List getXmls() { - return startArgs.getCoreEnvironment().getXmlFiles().stream() + return startArgs.getServerEnvironment().getXmlFiles().stream() .map(p -> baseHome.toShortForm(p)) .collect(Collectors.toList()); } @@ -165,7 +165,7 @@ public List getXmls() public List getLibs() { return StreamSupport.stream( - Spliterators.spliteratorUnknownSize(startArgs.getCoreEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) + Spliterators.spliteratorUnknownSize(startArgs.getServerEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) .map(f -> baseHome.toShortForm(f)) .collect(Collectors.toList()); } @@ -182,7 +182,7 @@ public Environment getEnvironment(String name) public List getProperties() { - Props props = startArgs.getCoreEnvironment().getProperties(); + Props props = startArgs.getServerEnvironment().getProperties(); Predicate propPredicate = (p) -> { diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java index 70865b216f8b..50ae507d6436 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java @@ -98,7 +98,7 @@ public void testBasicProcessing() throws Exception PathAssert.assertDirExists("Required Directory: maindir/", results.baseHome.getPath("maindir/")); // === Validate home/base property uri values - Props props = results.startArgs.getCoreEnvironment().getProperties(); + Props props = results.startArgs.getServerEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); @@ -408,7 +408,7 @@ public void testHomeWithSpaces() throws Exception assertThat("Properties", actualProperties, containsInAnyOrder(expectedProperties.toArray())); // === Validate home/base property uri values - Props props = results.startArgs.getCoreEnvironment().getProperties(); + Props props = results.startArgs.getServerEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java index d9ca8e671e8b..b246a466762e 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java @@ -17,14 +17,17 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.TreeMap; import org.eclipse.jetty.util.Attributes; import org.eclipse.jetty.util.TypeUtil; +/** + * A named runtime environment containing a {@link ClassLoader} and {@link Attributes}. + */ public interface Environment extends Attributes { - Environment CORE = ensure("core"); + Environment SERVER = ensure("Server"); static Collection getAll() { @@ -46,10 +49,22 @@ static Environment set(Environment environment) return Named.__environments.put(environment.getName(), environment); } + /** + * @return The case insensitvie name of the environment. + */ String getName(); + /** + * @return The {@link ClassLoader} for the environment or if non set, then the {@link ClassLoader} that + * loaded the environment implementation. + */ ClassLoader getClassLoader(); + /** + * Run a {@link Runnable} in the environment, i.e. with current {@link Thread#getContextClassLoader()} set to + * {@link #getClassLoader()}. + * @param runnable The {@link Runnable} to run in the environment. + */ default void run(Runnable runnable) { ClassLoader old = Thread.currentThread().getContextClassLoader(); @@ -66,7 +81,7 @@ default void run(Runnable runnable) class Named extends Attributes.Mapped implements Environment, Dumpable { - private static final Map __environments = new ConcurrentHashMap<>(); + private static final Map __environments = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private final String _name; private final ClassLoader _classLoader; From fff8ef1ad1265699d51280b7c1c5155bdb72009e Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 14:29:05 +0200 Subject: [PATCH 045/129] fixed jaas --- .../java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java index 5b9cd9b13548..281b40bc8bd0 100644 --- a/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java +++ b/jetty-ee9/jetty-ee9-webapp/src/main/java/org/eclipse/jetty/ee9/webapp/JaasConfiguration.java @@ -33,7 +33,7 @@ public JaasConfiguration() { addDependencies(WebXmlConfiguration.class, MetaInfConfiguration.class, WebInfConfiguration.class, FragmentConfiguration.class); addDependents(WebAppConfiguration.class); - protectAndExpose("org.eclipse.jetty.ee9.jaas."); + protectAndExpose("org.eclipse.jetty.security.jaas."); } @Override From 5cec2c35d65a8b3e8c657000fae6de50e9856e12 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 14:51:32 +0200 Subject: [PATCH 046/129] more jaas cleanup --- .../src/main/config/modules/demo.d/ee10-demo-jaas.xml | 2 +- .../main/config/modules/demo.d/ee10-demo-login.properties | 1 - .../src/main/config/modules/ee10-demo-jaas.mod | 5 ----- .../src/main/config/modules/demo.d/ee8-demo-jaas.xml | 2 +- .../main/config/modules/demo.d/ee8-demo-login.properties | 1 - .../src/main/config/modules/ee8-demo-jaas.mod | 2 +- .../src/main/config/modules/ee9-demo-jaas.mod | 2 +- .../modules/{ee9-demo-realm.mod => demo-realm.mod} | 0 .../jetty/tests/distribution/DemoModulesTests.java | 8 ++++---- 9 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-login.properties delete mode 100644 jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-login.properties rename jetty-home/src/main/resources/modules/{ee9-demo-realm.mod => demo-realm.mod} (100%) diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-jaas.xml b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-jaas.xml index 3466d90dfdf6..dc3ce345c0a1 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-jaas.xml +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-jaas.xml @@ -16,7 +16,7 @@ Demo JAAS Realm - ee10-xyz + demo diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-login.properties b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-login.properties deleted file mode 100644 index 61e32037316b..000000000000 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/demo.d/ee10-demo-login.properties +++ /dev/null @@ -1 +0,0 @@ -me=me,me,roleA diff --git a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/ee10-demo-jaas.mod b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/ee10-demo-jaas.mod index 6ab2602110fd..eed7045eecf3 100644 --- a/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/ee10-demo-jaas.mod +++ b/jetty-ee10/jetty-ee10-demos/jetty-ee10-demo-jaas-webapp/src/main/config/modules/ee10-demo-jaas.mod @@ -21,9 +21,4 @@ ext [files] basehome:modules/demo.d/ee10-demo-jaas.xml|webapps/ee10-demo-jaas.xml -basehome:modules/demo.d/ee10-demo-login.properties|etc/ee10-demo-login.properties maven://org.eclipse.jetty.ee10.demos/jetty-ee10-demo-jaas-webapp/${jetty.version}/war|webapps/ee10-demo-jaas.war - -[ini] -# Enable security via jaas, and configure it -jetty.jaas.login.conf?=etc/demo-login.conf diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml index 9b2f6e9dbbd5..9532bb9b7358 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-jaas.xml @@ -16,7 +16,7 @@ Demo JAAS Realm - ee8-xyz + demo diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-login.properties b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-login.properties deleted file mode 100644 index 61e32037316b..000000000000 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/demo.d/ee8-demo-login.properties +++ /dev/null @@ -1 +0,0 @@ -me=me,me,roleA diff --git a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod index 379100226e8d..e5e8aff612df 100644 --- a/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod +++ b/jetty-ee8/jetty-ee8-demos/jetty-ee8-demo-jaas-webapp/src/main/config/modules/ee8-demo-jaas.mod @@ -1,7 +1,7 @@ # DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Demo Spec webapp +Demo EE8 JAAS webapp [environment] ee8 diff --git a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod index 984a6198dcca..b1a8ffb985cd 100644 --- a/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod +++ b/jetty-ee9/jetty-ee9-demos/jetty-ee9-demo-jaas-webapp/src/main/config/modules/ee9-demo-jaas.mod @@ -1,7 +1,7 @@ # DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html [description] -Demo Spec webapp +Demo EE9 JAAS webapp [environment] ee9 diff --git a/jetty-home/src/main/resources/modules/ee9-demo-realm.mod b/jetty-home/src/main/resources/modules/demo-realm.mod similarity index 100% rename from jetty-home/src/main/resources/modules/ee9-demo-realm.mod rename to jetty-home/src/main/resources/modules/demo-realm.mod diff --git a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java index 1e2d7b3543de..5e11182dfa3c 100644 --- a/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java +++ b/tests/test-distribution/test-distribution-common/src/test/java/org/eclipse/jetty/tests/distribution/DemoModulesTests.java @@ -109,7 +109,7 @@ public void testJspDump(String env) throws Exception assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { - "--add-modules=http," + toEnvironment("demos", env) + "--add-modules=http," + toEnvironment("demo-jsp", env) }; String baseURI = "http://localhost:%d/%s-demo-jsp".formatted(httpPort, env); @@ -158,7 +158,7 @@ public void testJaasDemo(String env) throws Exception assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { - "--add-modules=http," + toEnvironment("demos", env) + "--add-modules=http," + toEnvironment("demo-jaas", env) }; String baseURI = "http://localhost:%d/%s-test-jaas".formatted(httpPort, env); @@ -208,7 +208,7 @@ public void testJstlDemo(String env) throws Exception assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { - "--add-modules=http," + toEnvironment("demos", env) + "--add-modules=http," + toEnvironment("demo-jsp", env) }; String baseURI = "http://localhost:%d/%s-demo-jsp".formatted(httpPort, env); @@ -259,7 +259,7 @@ public void testAsyncRest(String env) throws Exception assertThat("httpPort != httpsPort", httpPort, is(not(httpsPort))); String[] argsConfig = { - "--add-modules=http," + toEnvironment("demos", env) + "--add-modules=http," + toEnvironment("demo-async-rest", env) }; String baseURI = "http://localhost:%d/%s-demo-async-rest".formatted(httpPort, env); From 90a547db9cde05c37961d39fe93c2d44aa776ec7 Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 17:50:00 +0200 Subject: [PATCH 047/129] Server env exists only in startArgs. --- .../deploy/providers/ContextProvider.java | 4 ++-- .../deploy/providers/ScanningAppProvider.java | 21 ++++++++++--------- .../org/eclipse/jetty/start/StartArgs.java | 2 ++ .../jetty/util/component/Environment.java | 3 ++- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java index ad50028c7255..21f3e351ecf6 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextProvider.java @@ -360,7 +360,7 @@ public void initializeDefaults(Object context) xmlc.setJettyStandardIdsAndProperties(getDeploymentManager().getServer(), path); // If it is a core context environment, then look for a classloader - ClassLoader coreContextClassLoader = Environment.SERVER.equals(environment) ? findCoreContextClassLoader(path) : null; + ClassLoader coreContextClassLoader = Environment.CORE.equals(environment) ? findCoreContextClassLoader(path) : null; if (coreContextClassLoader != null) Thread.currentThread().setContextClassLoader(coreContextClassLoader); @@ -455,7 +455,7 @@ protected ClassLoader findCoreContextClassLoader(Path path) throws IOException if (urls.isEmpty()) return null; - return new URLClassLoader(urls.toArray(new URL[0]), Environment.SERVER.getClassLoader()); + return new URLClassLoader(urls.toArray(new URL[0]), Environment.CORE.getClassLoader()); } protected void initializeContextPath(ContextHandler context, Path path) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java index b4d93130994a..a7b16d667bda 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java @@ -150,6 +150,7 @@ protected App createApp(Path path) String environmentName = app.getEnvironmentName(); + String defaultEnvironmentName = _deploymentManager.getDefaultEnvironmentName(); if (StringUtil.isBlank(environmentName)) { // We may be able to default the environmentName @@ -161,13 +162,13 @@ protected App createApp(Path path) Files.exists(path.getParent().resolve(basename + ".WAR")) || Files.exists(path.getParent().resolve(basename + "/WEB-INF"))); boolean coreProvider = _deploymentManager.getAppProviders().stream() - .map(AppProvider::getEnvironmentName).anyMatch(Environment.SERVER.getName()::equals); + .map(AppProvider::getEnvironmentName).anyMatch(Environment.CORE.getName()::equalsIgnoreCase); // TODO review these heuristics... or even if we should have them at all - if (isWebapp || (Files.isDirectory(path) && _deploymentManager.getDefaultEnvironmentName() != null)) - environmentName = _deploymentManager.getDefaultEnvironmentName(); + if (isWebapp || (Files.isDirectory(path) && defaultEnvironmentName != null)) + environmentName = defaultEnvironmentName; else if (coreProvider) - environmentName = Environment.SERVER.getName(); + environmentName = Environment.CORE.getName(); if (StringUtil.isNotBlank(environmentName)) { @@ -180,7 +181,7 @@ else if (coreProvider) if (StringUtil.isNotBlank(environmentName)) { // If the app specifies the environment for this provider, then this deployer will deploy it. - if (Objects.equals(environmentName, getEnvironmentName())) + if (environmentName.equalsIgnoreCase(getEnvironmentName())) { if (LOG.isDebugEnabled()) LOG.debug("{} created {}", this, app); @@ -188,11 +189,11 @@ else if (coreProvider) } // If we are the default provider then we may warn - if (Objects.equals(getEnvironmentName(), _deploymentManager.getDefaultEnvironmentName())) + if (defaultEnvironmentName != null && defaultEnvironmentName.equalsIgnoreCase(getEnvironmentName())) { // if the app specified an environment name, then produce warning if there is no provider for it. boolean appProvider4env = _deploymentManager.getAppProviders().stream() - .map(AppProvider::getEnvironmentName).anyMatch(environmentName::equals); + .map(AppProvider::getEnvironmentName).anyMatch(environmentName::equalsIgnoreCase); if (!appProvider4env) LOG.warn("No AppProvider with environment {} for {}", environmentName, app); return null; @@ -213,10 +214,10 @@ protected void doStart() throws Exception throw new IllegalStateException("No configuration dir specified"); if (_environmentName == null) { - List nonServer = Environment.getAll().stream().filter(environment -> !environment.equals(Environment.SERVER)).toList(); - if (nonServer.size() != 1) + List nonCore = Environment.getAll().stream().filter(environment -> !environment.equals(Environment.CORE)).toList(); + if (nonCore.size() != 1) throw new IllegalStateException("No environment configured"); - _environmentName = nonServer.get(0).getName(); + _environmentName = nonCore.get(0).getName(); } Environment environment = Environment.get(_environmentName); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 2b4e9fba7739..0abf975d60d9 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -194,6 +194,8 @@ public class StartArgs private boolean allowInsecureHttpDownloads = false; private boolean approveAllLicenses = false; + /** The server environment holds the main configuration for the server. It is never created + * as a real environment within the server, as it ultimately becomes the JVM environment. */ private final Environment serverEnvironment; public StartArgs(BaseHome baseHome) diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java index b246a466762e..5b7fb1125fe1 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java @@ -27,7 +27,8 @@ */ public interface Environment extends Attributes { - Environment SERVER = ensure("Server"); + // Ensure there is a core environment for possible later deployments to it + Environment CORE = ensure("Core"); static Collection getAll() { From a4adc6206b977f83cf71e9bc45c8c1a7683cea7c Mon Sep 17 00:00:00 2001 From: gregw Date: Wed, 12 Apr 2023 18:07:45 +0200 Subject: [PATCH 048/129] rename Server env to JVM --- .../org/eclipse/jetty/start/BaseBuilder.java | 4 +- .../java/org/eclipse/jetty/start/Main.java | 12 +-- .../java/org/eclipse/jetty/start/Modules.java | 8 +- .../org/eclipse/jetty/start/StartArgs.java | 80 +++++++++---------- .../jetty/start/IncludeJettyDirTest.java | 2 +- .../org/eclipse/jetty/start/MainTest.java | 6 +- .../org/eclipse/jetty/start/ModulesTest.java | 8 +- .../jetty/start/usecases/AbstractUseCase.java | 6 +- .../jetty/start/usecases/BasicTest.java | 4 +- 9 files changed, 65 insertions(+), 65 deletions(-) diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java index 2a943bbb358c..f54e5e2236f2 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java @@ -293,13 +293,13 @@ public boolean accept(Path entry) // if (explicitly added and ini file modified) if (startArgs.getStartModules().contains(module.getName())) { - ini = builder.get().addModule(module, startArgs.getServerEnvironment().getProperties()); + ini = builder.get().addModule(module, startArgs.getJvmEnvironment().getProperties()); if (ini != null) modified.set(true); } for (String file : module.getFiles()) { - files.add(new FileArg(module, startArgs.getServerEnvironment().getProperties().expand(file))); + files.add(new FileArg(module, startArgs.getJvmEnvironment().getProperties().expand(file))); } } } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index bba618385d7d..58fc1929946d 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -239,7 +239,7 @@ public void listConfig(PrintStream out, StartArgs args) args.dumpSystemProperties(out); - Environment serverEnvironment = args.getServerEnvironment(); + Environment serverEnvironment = args.getJvmEnvironment(); // Dump Server Properties serverEnvironment.dumpProperties(out); @@ -317,7 +317,7 @@ public StartArgs processCommandLine(String[] cmdLine) throws Exception Props props = baseHome.getConfigSources().getProps(); Prop home = props.getProp(BaseHome.JETTY_HOME); - Props argProps = args.getServerEnvironment().getProperties(); + Props argProps = args.getJvmEnvironment().getProperties(); if (!argProps.containsKey(BaseHome.JETTY_HOME)) argProps.setProperty(home); argProps.setProperty(BaseHome.JETTY_HOME + ".uri", @@ -390,7 +390,7 @@ public void start(StartArgs args) throws IOException, InterruptedException StartLog.debug("StartArgs: %s", args); // Get Desired Classpath based on user provided Active Options. - Classpath classpath = args.getServerEnvironment().getClasspath(); + Classpath classpath = args.getJvmEnvironment().getClasspath(); // Show the usage information and return if (args.isHelp()) @@ -428,7 +428,7 @@ public void start(StartArgs args) throws IOException, InterruptedException Path outputFile = baseHome.getBasePath(args.getModuleGraphFilename()); System.out.printf("Generating GraphViz Graph of Jetty Modules at %s%n", baseHome.toShortForm(outputFile)); ModuleGraphWriter writer = new ModuleGraphWriter(); - writer.config(args.getServerEnvironment().getProperties()); + writer.config(args.getJvmEnvironment().getProperties()); writer.write(args.getAllModules(), outputFile); } @@ -451,7 +451,7 @@ public void start(StartArgs args) throws IOException, InterruptedException { for (StartIni ini : config.getStartInis()) { - ini.update(baseHome, args.getServerEnvironment().getProperties()); + ini.update(baseHome, args.getJvmEnvironment().getProperties()); } } } @@ -534,7 +534,7 @@ public void start() throws Exception private void doStop(StartArgs args) { - Props argsProps = args.getServerEnvironment().getProperties(); + Props argsProps = args.getJvmEnvironment().getProperties(); final Prop stopHostProp = argsProps.getProp("STOP.HOST", true); final Prop stopPortProp = argsProps.getProp("STOP.PORT", true); final Prop stopKeyProp = argsProps.getProp("STOP.KEY", true); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java index a9255306c9de..c3487e94b72f 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -56,7 +56,7 @@ public Modules(BaseHome basehome, StartArgs args) this._args = args; // Allow override mostly for testing - if (!args.getServerEnvironment().getProperties().containsKey("java.version")) + if (!args.getJvmEnvironment().getProperties().containsKey("java.version")) { String javaVersion = System.getProperty("java.version"); if (javaVersion != null) @@ -458,13 +458,13 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, newlyEnabled.add(module.getName()); // Expand module properties - module.expandDependencies(_args.getServerEnvironment().getProperties()); + module.expandDependencies(_args.getJvmEnvironment().getProperties()); // Apply default configuration if (module.hasDefaultConfig()) { String source = module.getName() + "[ini]"; - Environment environment = _args.getServerEnvironment(); + Environment environment = _args.getJvmEnvironment(); environment = _args.parse(environment, "--module=" + module.getName(), source); for (String line : module.getIniSection()) @@ -497,7 +497,7 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, Path file = _baseHome.getPath("modules/" + dependentModule + ".mod"); if (!isConditional || Files.exists(file)) { - registerModule(file).expandDependencies(_args.getServerEnvironment().getProperties()); + registerModule(file).expandDependencies(_args.getJvmEnvironment().getProperties()); providers = _provided.get(dependentModule); if (providers == null || providers.isEmpty()) throw new UsageException("Module %s does not provide %s", _baseHome.toShortForm(file), dependentModule); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 0abf975d60d9..359078ef5634 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -194,27 +194,27 @@ public class StartArgs private boolean allowInsecureHttpDownloads = false; private boolean approveAllLicenses = false; - /** The server environment holds the main configuration for the server. It is never created - * as a real environment within the server, as it ultimately becomes the JVM environment. */ - private final Environment serverEnvironment; + /** The JVM environment holds the main configuration for the JVM. It is never created + * as a real environment within the server. */ + private final Environment jvmEnvironment; public StartArgs(BaseHome baseHome) { this.baseHome = baseHome; - serverEnvironment = new Environment("Server", baseHome); + jvmEnvironment = new Environment("JVM", baseHome); } public void expandEnvironments(List activeModules) throws IOException { // 5) Lib & XML Expansion / Resolution expandSystemProperties(); - serverEnvironment.resolveLibs(); + jvmEnvironment.resolveLibs(); expandModules(activeModules); // 6) Resolve Extra XMLs // 7) JPMS Expansion // 8) Resolve Property Files - serverEnvironment.resolve(); + jvmEnvironment.resolve(); // 7) JPMS Expansion resolveJPMS(activeModules); // TODO we need layers @@ -227,9 +227,9 @@ public void expandEnvironments(List activeModules) throws IOException } } - public Environment getServerEnvironment() + public Environment getJvmEnvironment() { - return serverEnvironment; + return jvmEnvironment; } public Collection getEnvironments() @@ -259,7 +259,7 @@ private void addFile(Module module, String uriLocation) private Environment getEnvironment(Module module) { String envName = module == null ? null : module.getEnvironment(); - Environment environment = envName == null ? getServerEnvironment() : getEnvironment(envName); + Environment environment = envName == null ? getJvmEnvironment() : getEnvironment(envName); return environment; } @@ -267,8 +267,8 @@ public void dumpJavaEnvironment(PrintStream out) { // Java Details out.println(); - out.println("Java Environment:"); - out.println("-----------------"); + out.println("Key System Properties:"); + out.println("----------------------"); dumpSystemProperty(out, "java.home"); dumpSystemProperty(out, "java.vm.vendor"); dumpSystemProperty(out, "java.vm.version"); @@ -283,14 +283,14 @@ public void dumpJavaEnvironment(PrintStream out) // Jetty Server Environment out.println(); - out.println("Jetty Server Environment:"); - out.println("-------------------------"); - Environment serverEnvironment = getServerEnvironment(); - serverEnvironment.dumpProperty(out, JETTY_VERSION_KEY); - serverEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); - serverEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); - serverEnvironment.dumpProperty(out, "jetty.home"); - serverEnvironment.dumpProperty(out, "jetty.base"); + out.println("JVM Environment:"); + out.println("----------------"); + Environment jvmEnvironment = getJvmEnvironment(); + jvmEnvironment.dumpProperty(out, JETTY_VERSION_KEY); + jvmEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); + jvmEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); + jvmEnvironment.dumpProperty(out, "jetty.home"); + jvmEnvironment.dumpProperty(out, "jetty.base"); // Jetty Configuration Environment out.println(); @@ -374,13 +374,13 @@ private void ensureSystemPropertySet(String key) return; // done } - if (getServerEnvironment().getProperties().containsKey(key)) + if (getJvmEnvironment().getProperties().containsKey(key)) { - Prop prop = getServerEnvironment().getProperties().getProp(key); + Prop prop = getJvmEnvironment().getProperties().getProp(key); if (prop == null) return; // no value set; - String val = getServerEnvironment().getProperties().expand(prop.value); + String val = getJvmEnvironment().getProperties().expand(prop.value); // setup system property systemPropertySource.put(key, "property:" + prop.source); System.setProperty(key, val); @@ -396,10 +396,10 @@ public void expandSystemProperties() for (String key : systemPropertySource.keySet()) { - String value = getServerEnvironment().getProperties().getString(key); + String value = getJvmEnvironment().getProperties().getString(key); if (value != null) { - String expanded = getServerEnvironment().getProperties().expand(value); + String expanded = getJvmEnvironment().getProperties().expand(value); if (!value.equals(expanded)) System.setProperty(key, expanded); } @@ -532,7 +532,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException cmd.addRawArg("-Djetty.home=" + baseHome.getHome()); cmd.addRawArg("-Djetty.base=" + baseHome.getBase()); - Props properties = serverEnvironment.getProperties(); + Props properties = jvmEnvironment.getProperties(); for (String x : getJvmArgSources().keySet()) { if (x.startsWith("-D")) @@ -562,7 +562,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException { if (isJPMS()) { - Map> dirsAndFiles = StreamSupport.stream(serverEnvironment.getClasspath().spliterator(), false) + Map> dirsAndFiles = StreamSupport.stream(jvmEnvironment.getClasspath().spliterator(), false) .collect(Collectors.groupingBy(Files::isDirectory)); Set files = new HashSet<>(dirsAndFiles.get(false)); @@ -570,7 +570,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // ee9 may use jakarta.annotation 2.0.0 // but ee10 use jakarta.annotation 2.1.0 // and both having different module-info. - getEnvironments().stream().filter(environment -> !environment.getName().equals(serverEnvironment.getName())) + getEnvironments().stream().filter(environment -> !environment.getName().equals(jvmEnvironment.getName())) .forEach(environment -> { Map> dirsAndFilesModules = StreamSupport.stream(environment.getClasspath().spliterator(), false) @@ -612,7 +612,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException else { cmd.addRawArg("--class-path"); - cmd.addRawArg(serverEnvironment.getClasspath().toString()); + cmd.addRawArg(jvmEnvironment.getClasspath().toString()); } } @@ -626,7 +626,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // do properties and xmls if (parts.contains("args")) { - Props properties = serverEnvironment.getProperties(); + Props properties = jvmEnvironment.getProperties(); if (dryRun && execProperties == null) { // pass properties as args @@ -656,12 +656,12 @@ else if (properties.size() > 0) cmd.addRawArg(propPath.toAbsolutePath().toString()); } - for (Path xml : serverEnvironment.getXmlFiles()) + for (Path xml : jvmEnvironment.getXmlFiles()) { cmd.addRawArg(xml.toAbsolutePath().toString()); } - for (Path propertyFile : serverEnvironment.getPropertyFiles()) + for (Path propertyFile : jvmEnvironment.getPropertyFiles()) { cmd.addRawArg(propertyFile.toAbsolutePath().toString()); } @@ -671,7 +671,7 @@ else if (properties.size() > 0) { for (Environment environment : getEnvironments()) { - if (environment == serverEnvironment) + if (environment == jvmEnvironment) continue; cmd.addArg("--env"); cmd.addArg(environment.getName()); @@ -705,7 +705,7 @@ private void resolveJPMS(List activeModules) throws IOException { for (String line : module.getJPMS()) { - line = getServerEnvironment().getProperties().expand(line); + line = getJvmEnvironment().getProperties().expand(line); String directive; if (line.startsWith(directive = "add-modules:")) { @@ -796,7 +796,7 @@ private void generateJpmsArgs(CommandLineBuilder cmd) public String getMainClassname() { String mainClass = System.getProperty("jetty.server", isJPMS() ? MODULE_MAIN_CLASS : MAIN_CLASS); - Prop mainClassProp = getServerEnvironment().getProperties().getProp("main.class", true); + Prop mainClassProp = getJvmEnvironment().getProperties().getProp("main.class", true); if (mainClassProp != null) return mainClassProp.value; return mainClass; @@ -804,7 +804,7 @@ public String getMainClassname() public String getMavenLocalRepoDir() { - String localRepo = getServerEnvironment().getProperties().getString("maven.local.repo"); + String localRepo = getJvmEnvironment().getProperties().getString("maven.local.repo"); if (Utils.isBlank(localRepo)) localRepo = System.getenv("JETTY_MAVEN_LOCAL_REPO"); @@ -1007,7 +1007,7 @@ public void parse(ConfigSources sources) while (iter.hasPrevious()) { // Each source starts with server environment. - Environment environment = getServerEnvironment(); + Environment environment = getJvmEnvironment(); ConfigSource source = iter.previous(); for (RawArgs.Entry arg : source.getArgs()) @@ -1267,7 +1267,7 @@ public Environment parse(Environment environment, String arg, String source) selectModules(source, moduleNames); Module module = getAllModules().get(moduleNames.get(moduleNames.size() - 1)); String envName = module == null ? null : module.getEnvironment(); - return envName == null ? serverEnvironment : getEnvironment(envName); + return envName == null ? jvmEnvironment : getEnvironment(envName); } // Skip [files] validation on a module @@ -1287,7 +1287,7 @@ public Environment parse(Environment environment, String arg, String source) } if (environment == null) - environment = getServerEnvironment(); + environment = getJvmEnvironment(); // Arbitrary Libraries if (arg.startsWith("--lib=") || arg.startsWith("--libs=")) @@ -1434,7 +1434,7 @@ public void setAllModules(Modules allModules) public void setProperty(Environment environment, String key, String value, String source) { if (environment == null) - environment = getServerEnvironment(); + environment = getJvmEnvironment(); Props properties = environment.getProperties(); // Special / Prevent override from start.ini's @@ -1504,6 +1504,6 @@ public void setRun(boolean run) public String toString() { return String.format("%s[enabledModules=%s, xml=%s, properties=%s, jvmArgs=%s]", - getClass().getSimpleName(), modules, getServerEnvironment().getXmlFiles(), getServerEnvironment().getProperties(), jvmArgSources.keySet()); + getClass().getSimpleName(), modules, getJvmEnvironment().getXmlFiles(), getJvmEnvironment().getProperties(), jvmArgSources.keySet()); } } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java index fe19f0b9a4a6..60e4aaaeab64 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java @@ -59,7 +59,7 @@ public void assertSearchOrder(List expectedSearchOrder) public void assertProperty(String key, String expectedValue) { - Prop prop = args.getServerEnvironment().getProperties().getProp(key); + Prop prop = args.getJvmEnvironment().getProperties().getProp(key); String prefix = "Prop[" + key + "]"; assertThat(prefix + " should have a value", prop, notNullValue()); assertThat(prefix + " value", prop.value, is(expectedValue)); diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java index 4d238bfcbca4..4a0e28795bce 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java @@ -58,9 +58,9 @@ public void testStopProcessing() throws Exception StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[0])); // assertEquals(0, args.getEnabledModules().size(), "--stop should not build module tree"); - assertEquals("10000", args.getServerEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); - assertEquals("foo", args.getServerEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); - assertEquals("300", args.getServerEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); + assertEquals("10000", args.getJvmEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); + assertEquals("foo", args.getJvmEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); + assertEquals("300", args.getJvmEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); } @Test diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java index d74010504349..6d6d499b6bea 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java @@ -69,7 +69,7 @@ public void testLoadAllModules() throws IOException modules.registerAll(); // Check versions - String platformProperty = args.getServerEnvironment().getProperties().getString("java.version.platform"); + String platformProperty = args.getJvmEnvironment().getProperties().getString("java.version.platform"); assertThat("java.version.platform", Integer.parseInt(platformProperty), greaterThanOrEqualTo(8)); List moduleNames = new ArrayList<>(); @@ -247,7 +247,7 @@ public void testResolveNotRequiredModuleNotFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getServerEnvironment().getProperties(); + Props props = args.getJvmEnvironment().getProperties(); assertThat(props.getString("bar.name"), is(nullValue())); } @@ -298,7 +298,7 @@ public void testResolveNotRequiredModuleFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getServerEnvironment().getProperties(); + Props props = args.getJvmEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dive")); } @@ -349,7 +349,7 @@ public void testResolveNotRequiredModuleFoundDynamic() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getServerEnvironment().getProperties(); + Props props = args.getJvmEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dynamic")); } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java index 82b7b51480fe..c9502af81894 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java @@ -157,7 +157,7 @@ public static class ExecResults public List getXmls() { - return startArgs.getServerEnvironment().getXmlFiles().stream() + return startArgs.getJvmEnvironment().getXmlFiles().stream() .map(p -> baseHome.toShortForm(p)) .collect(Collectors.toList()); } @@ -165,7 +165,7 @@ public List getXmls() public List getLibs() { return StreamSupport.stream( - Spliterators.spliteratorUnknownSize(startArgs.getServerEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) + Spliterators.spliteratorUnknownSize(startArgs.getJvmEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) .map(f -> baseHome.toShortForm(f)) .collect(Collectors.toList()); } @@ -182,7 +182,7 @@ public Environment getEnvironment(String name) public List getProperties() { - Props props = startArgs.getServerEnvironment().getProperties(); + Props props = startArgs.getJvmEnvironment().getProperties(); Predicate propPredicate = (p) -> { diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java index 50ae507d6436..463ab775f8d5 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java @@ -98,7 +98,7 @@ public void testBasicProcessing() throws Exception PathAssert.assertDirExists("Required Directory: maindir/", results.baseHome.getPath("maindir/")); // === Validate home/base property uri values - Props props = results.startArgs.getServerEnvironment().getProperties(); + Props props = results.startArgs.getJvmEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); @@ -408,7 +408,7 @@ public void testHomeWithSpaces() throws Exception assertThat("Properties", actualProperties, containsInAnyOrder(expectedProperties.toArray())); // === Validate home/base property uri values - Props props = results.startArgs.getServerEnvironment().getProperties(); + Props props = results.startArgs.getJvmEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); From 8f2fcb2f624f669219df6c0c93a38e4009b10d03 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 13 Apr 2023 00:15:20 +0200 Subject: [PATCH 049/129] rename of the rename of the rename updates from review --- .../jetty/deploy/DeploymentManager.java | 6 + .../deploy/providers/ScanningAppProvider.java | 7 +- .../org/eclipse/jetty/start/BaseBuilder.java | 4 +- .../java/org/eclipse/jetty/start/Main.java | 27 +++-- .../java/org/eclipse/jetty/start/Modules.java | 8 +- .../org/eclipse/jetty/start/StartArgs.java | 107 +++++++++--------- ...Environment.java => StartEnvironment.java} | 10 +- .../jetty/start/IncludeJettyDirTest.java | 2 +- .../org/eclipse/jetty/start/MainTest.java | 6 +- .../org/eclipse/jetty/start/ModulesTest.java | 8 +- .../jetty/start/usecases/AbstractUseCase.java | 12 +- .../jetty/start/usecases/BasicTest.java | 4 +- .../start/usecases/EnvironmentsTest.java | 4 +- .../jetty/util/component/Environment.java | 2 +- 14 files changed, 106 insertions(+), 101 deletions(-) rename jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/{Environment.java => StartEnvironment.java} (97%) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java index 7399b7620617..ee62442605e0 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java @@ -187,6 +187,12 @@ public void setAppProviders(Collection providers) } } + public boolean hasAppProviderFor(String name) + { + return name != null && getAppProviders().stream() + .map(AppProvider::getEnvironmentName).anyMatch(name::equalsIgnoreCase); + } + public Collection getAppProviders() { return Collections.unmodifiableList(_providers); diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java index a7b16d667bda..b023112f34ef 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java @@ -161,8 +161,7 @@ protected App createApp(Path path) Files.exists(path.getParent().resolve(basename + ".war")) || Files.exists(path.getParent().resolve(basename + ".WAR")) || Files.exists(path.getParent().resolve(basename + "/WEB-INF"))); - boolean coreProvider = _deploymentManager.getAppProviders().stream() - .map(AppProvider::getEnvironmentName).anyMatch(Environment.CORE.getName()::equalsIgnoreCase); + boolean coreProvider = _deploymentManager.hasAppProviderFor(Environment.CORE.getName()); // TODO review these heuristics... or even if we should have them at all if (isWebapp || (Files.isDirectory(path) && defaultEnvironmentName != null)) @@ -192,9 +191,7 @@ else if (coreProvider) if (defaultEnvironmentName != null && defaultEnvironmentName.equalsIgnoreCase(getEnvironmentName())) { // if the app specified an environment name, then produce warning if there is no provider for it. - boolean appProvider4env = _deploymentManager.getAppProviders().stream() - .map(AppProvider::getEnvironmentName).anyMatch(environmentName::equalsIgnoreCase); - if (!appProvider4env) + if (!_deploymentManager.hasAppProviderFor(environmentName)) LOG.warn("No AppProvider with environment {} for {}", environmentName, app); return null; } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java index f54e5e2236f2..b0a460e81e45 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/BaseBuilder.java @@ -293,13 +293,13 @@ public boolean accept(Path entry) // if (explicitly added and ini file modified) if (startArgs.getStartModules().contains(module.getName())) { - ini = builder.get().addModule(module, startArgs.getJvmEnvironment().getProperties()); + ini = builder.get().addModule(module, startArgs.getJettyEnvironment().getProperties()); if (ini != null) modified.set(true); } for (String file : module.getFiles()) { - files.add(new FileArg(module, startArgs.getJvmEnvironment().getProperties().expand(file))); + files.add(new FileArg(module, startArgs.getJettyEnvironment().getProperties().expand(file))); } } } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java index 58fc1929946d..0500e4361aba 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Main.java @@ -238,17 +238,16 @@ public void listConfig(PrintStream out, StartArgs args) // Dump System Properties args.dumpSystemProperties(out); + StartEnvironment jettyEnvironment = args.getJettyEnvironment(); - Environment serverEnvironment = args.getJvmEnvironment(); + // Dump Jetty Properties + jettyEnvironment.dumpProperties(out); + // Dump Jetty Classpath + dumpClasspathWithVersions(jettyEnvironment.getName(), out, jettyEnvironment.getClasspath()); + // Dump Jetty Resolved XMLs + jettyEnvironment.dumpActiveXmls(out); - // Dump Server Properties - serverEnvironment.dumpProperties(out); - // Dump Server Classpath - dumpClasspathWithVersions(serverEnvironment.getName(), out, serverEnvironment.getClasspath()); - // Dump Server Resolved XMLs - serverEnvironment.dumpActiveXmls(out); - - for (Environment environment : args.getEnvironments()) + for (StartEnvironment environment : args.getEnvironments()) { // Dump Properties environment.dumpProperties(out); @@ -317,7 +316,7 @@ public StartArgs processCommandLine(String[] cmdLine) throws Exception Props props = baseHome.getConfigSources().getProps(); Prop home = props.getProp(BaseHome.JETTY_HOME); - Props argProps = args.getJvmEnvironment().getProperties(); + Props argProps = args.getJettyEnvironment().getProperties(); if (!argProps.containsKey(BaseHome.JETTY_HOME)) argProps.setProperty(home); argProps.setProperty(BaseHome.JETTY_HOME + ".uri", @@ -390,7 +389,7 @@ public void start(StartArgs args) throws IOException, InterruptedException StartLog.debug("StartArgs: %s", args); // Get Desired Classpath based on user provided Active Options. - Classpath classpath = args.getJvmEnvironment().getClasspath(); + Classpath classpath = args.getJettyEnvironment().getClasspath(); // Show the usage information and return if (args.isHelp()) @@ -428,7 +427,7 @@ public void start(StartArgs args) throws IOException, InterruptedException Path outputFile = baseHome.getBasePath(args.getModuleGraphFilename()); System.out.printf("Generating GraphViz Graph of Jetty Modules at %s%n", baseHome.toShortForm(outputFile)); ModuleGraphWriter writer = new ModuleGraphWriter(); - writer.config(args.getJvmEnvironment().getProperties()); + writer.config(args.getJettyEnvironment().getProperties()); writer.write(args.getAllModules(), outputFile); } @@ -451,7 +450,7 @@ public void start(StartArgs args) throws IOException, InterruptedException { for (StartIni ini : config.getStartInis()) { - ini.update(baseHome, args.getJvmEnvironment().getProperties()); + ini.update(baseHome, args.getJettyEnvironment().getProperties()); } } } @@ -534,7 +533,7 @@ public void start() throws Exception private void doStop(StartArgs args) { - Props argsProps = args.getJvmEnvironment().getProperties(); + Props argsProps = args.getJettyEnvironment().getProperties(); final Prop stopHostProp = argsProps.getProp("STOP.HOST", true); final Prop stopPortProp = argsProps.getProp("STOP.PORT", true); final Prop stopKeyProp = argsProps.getProp("STOP.KEY", true); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java index c3487e94b72f..8ab5328881ce 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Modules.java @@ -56,7 +56,7 @@ public Modules(BaseHome basehome, StartArgs args) this._args = args; // Allow override mostly for testing - if (!args.getJvmEnvironment().getProperties().containsKey("java.version")) + if (!args.getJettyEnvironment().getProperties().containsKey("java.version")) { String javaVersion = System.getProperty("java.version"); if (javaVersion != null) @@ -458,13 +458,13 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, newlyEnabled.add(module.getName()); // Expand module properties - module.expandDependencies(_args.getJvmEnvironment().getProperties()); + module.expandDependencies(_args.getJettyEnvironment().getProperties()); // Apply default configuration if (module.hasDefaultConfig()) { String source = module.getName() + "[ini]"; - Environment environment = _args.getJvmEnvironment(); + StartEnvironment environment = _args.getJettyEnvironment(); environment = _args.parse(environment, "--module=" + module.getName(), source); for (String line : module.getIniSection()) @@ -497,7 +497,7 @@ private void enable(Set newlyEnabled, Module module, String enabledFrom, Path file = _baseHome.getPath("modules/" + dependentModule + ".mod"); if (!isConditional || Files.exists(file)) { - registerModule(file).expandDependencies(_args.getJvmEnvironment().getProperties()); + registerModule(file).expandDependencies(_args.getJettyEnvironment().getProperties()); providers = _provided.get(dependentModule); if (providers == null || providers.isEmpty()) throw new UsageException("Module %s does not provide %s", _baseHome.toShortForm(file), dependentModule); diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java index 359078ef5634..603b1862005c 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartArgs.java @@ -134,7 +134,7 @@ public class StartArgs private final Map systemPropertySource = new HashMap<>(); - private static final Map _environments = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private static final Map environments = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); // jetty.base - build out commands /** @@ -194,32 +194,34 @@ public class StartArgs private boolean allowInsecureHttpDownloads = false; private boolean approveAllLicenses = false; - /** The JVM environment holds the main configuration for the JVM. It is never created - * as a real environment within the server. */ - private final Environment jvmEnvironment; + /** + * The jetty environment holds the main configuration used from the primary classloader for Jetty. + * It is never created as a real environment within the server. + * */ + private final StartEnvironment jettyEnvironment; public StartArgs(BaseHome baseHome) { this.baseHome = baseHome; - jvmEnvironment = new Environment("JVM", baseHome); + jettyEnvironment = new StartEnvironment("Jetty", baseHome); } public void expandEnvironments(List activeModules) throws IOException { // 5) Lib & XML Expansion / Resolution expandSystemProperties(); - jvmEnvironment.resolveLibs(); + jettyEnvironment.resolveLibs(); expandModules(activeModules); // 6) Resolve Extra XMLs // 7) JPMS Expansion // 8) Resolve Property Files - jvmEnvironment.resolve(); + jettyEnvironment.resolve(); // 7) JPMS Expansion resolveJPMS(activeModules); // TODO we need layers - for (Environment environment : _environments.values()) + for (StartEnvironment environment : environments.values()) { environment.resolveLibs(); environment.resolve(); @@ -227,19 +229,19 @@ public void expandEnvironments(List activeModules) throws IOException } } - public Environment getJvmEnvironment() + public StartEnvironment getJettyEnvironment() { - return jvmEnvironment; + return jettyEnvironment; } - public Collection getEnvironments() + public Collection getEnvironments() { - return _environments.values(); + return environments.values(); } - public Environment getEnvironment(String envName) + public StartEnvironment getEnvironment(String envName) { - return _environments.computeIfAbsent(envName, k -> new Environment(k, baseHome)); + return environments.computeIfAbsent(envName, k -> new StartEnvironment(k, baseHome)); } private void addFile(Module module, String uriLocation) @@ -250,16 +252,16 @@ private void addFile(Module module, String uriLocation) return; } - Environment environment = getEnvironment(module); + StartEnvironment environment = getEnvironment(module); FileArg arg = new FileArg(module, environment.getProperties().expand(uriLocation)); if (!files.contains(arg)) files.add(arg); } - private Environment getEnvironment(Module module) + private StartEnvironment getEnvironment(Module module) { String envName = module == null ? null : module.getEnvironment(); - Environment environment = envName == null ? getJvmEnvironment() : getEnvironment(envName); + StartEnvironment environment = envName == null ? getJettyEnvironment() : getEnvironment(envName); return environment; } @@ -283,14 +285,14 @@ public void dumpJavaEnvironment(PrintStream out) // Jetty Server Environment out.println(); - out.println("JVM Environment:"); - out.println("----------------"); - Environment jvmEnvironment = getJvmEnvironment(); - jvmEnvironment.dumpProperty(out, JETTY_VERSION_KEY); - jvmEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); - jvmEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); - jvmEnvironment.dumpProperty(out, "jetty.home"); - jvmEnvironment.dumpProperty(out, "jetty.base"); + out.println("Jetty Version:"); + out.println("--------------"); + StartEnvironment jettyEnvironment = getJettyEnvironment(); + jettyEnvironment.dumpProperty(out, JETTY_VERSION_KEY); + jettyEnvironment.dumpProperty(out, JETTY_TAG_NAME_KEY); + jettyEnvironment.dumpProperty(out, JETTY_BUILDNUM_KEY); + jettyEnvironment.dumpProperty(out, "jetty.home"); + jettyEnvironment.dumpProperty(out, "jetty.base"); // Jetty Configuration Environment out.println(); @@ -374,13 +376,14 @@ private void ensureSystemPropertySet(String key) return; // done } - if (getJvmEnvironment().getProperties().containsKey(key)) + StartEnvironment jettyEnvironment = getJettyEnvironment(); + if (jettyEnvironment.getProperties().containsKey(key)) { - Prop prop = getJvmEnvironment().getProperties().getProp(key); + Prop prop = jettyEnvironment.getProperties().getProp(key); if (prop == null) return; // no value set; - String val = getJvmEnvironment().getProperties().expand(prop.value); + String val = jettyEnvironment.getProperties().expand(prop.value); // setup system property systemPropertySource.put(key, "property:" + prop.source); System.setProperty(key, val); @@ -396,10 +399,10 @@ public void expandSystemProperties() for (String key : systemPropertySource.keySet()) { - String value = getJvmEnvironment().getProperties().getString(key); + String value = getJettyEnvironment().getProperties().getString(key); if (value != null) { - String expanded = getJvmEnvironment().getProperties().expand(value); + String expanded = getJettyEnvironment().getProperties().expand(value); if (!value.equals(expanded)) System.setProperty(key, expanded); } @@ -417,7 +420,7 @@ public void expandModules(List activeModules) throws IOException StartLog.debug("Expanding Modules"); for (Module module : activeModules) { - Environment environment = getEnvironment(module); + StartEnvironment environment = getEnvironment(module); // Find and Expand Libraries for (String rawlibref : module.getLibs()) @@ -532,7 +535,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException cmd.addRawArg("-Djetty.home=" + baseHome.getHome()); cmd.addRawArg("-Djetty.base=" + baseHome.getBase()); - Props properties = jvmEnvironment.getProperties(); + Props properties = jettyEnvironment.getProperties(); for (String x : getJvmArgSources().keySet()) { if (x.startsWith("-D")) @@ -562,7 +565,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException { if (isJPMS()) { - Map> dirsAndFiles = StreamSupport.stream(jvmEnvironment.getClasspath().spliterator(), false) + Map> dirsAndFiles = StreamSupport.stream(jettyEnvironment.getClasspath().spliterator(), false) .collect(Collectors.groupingBy(Files::isDirectory)); Set files = new HashSet<>(dirsAndFiles.get(false)); @@ -570,7 +573,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // ee9 may use jakarta.annotation 2.0.0 // but ee10 use jakarta.annotation 2.1.0 // and both having different module-info. - getEnvironments().stream().filter(environment -> !environment.getName().equals(jvmEnvironment.getName())) + getEnvironments().stream().filter(environment -> !environment.getName().equals(jettyEnvironment.getName())) .forEach(environment -> { Map> dirsAndFilesModules = StreamSupport.stream(environment.getClasspath().spliterator(), false) @@ -612,7 +615,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException else { cmd.addRawArg("--class-path"); - cmd.addRawArg(jvmEnvironment.getClasspath().toString()); + cmd.addRawArg(jettyEnvironment.getClasspath().toString()); } } @@ -626,7 +629,7 @@ public CommandLineBuilder getMainArgs(Set parts) throws IOException // do properties and xmls if (parts.contains("args")) { - Props properties = jvmEnvironment.getProperties(); + Props properties = jettyEnvironment.getProperties(); if (dryRun && execProperties == null) { // pass properties as args @@ -656,12 +659,12 @@ else if (properties.size() > 0) cmd.addRawArg(propPath.toAbsolutePath().toString()); } - for (Path xml : jvmEnvironment.getXmlFiles()) + for (Path xml : jettyEnvironment.getXmlFiles()) { cmd.addRawArg(xml.toAbsolutePath().toString()); } - for (Path propertyFile : jvmEnvironment.getPropertyFiles()) + for (Path propertyFile : jettyEnvironment.getPropertyFiles()) { cmd.addRawArg(propertyFile.toAbsolutePath().toString()); } @@ -669,9 +672,9 @@ else if (properties.size() > 0) if (parts.contains("envs")) { - for (Environment environment : getEnvironments()) + for (StartEnvironment environment : getEnvironments()) { - if (environment == jvmEnvironment) + if (environment == jettyEnvironment) continue; cmd.addArg("--env"); cmd.addArg(environment.getName()); @@ -705,7 +708,7 @@ private void resolveJPMS(List activeModules) throws IOException { for (String line : module.getJPMS()) { - line = getJvmEnvironment().getProperties().expand(line); + line = getJettyEnvironment().getProperties().expand(line); String directive; if (line.startsWith(directive = "add-modules:")) { @@ -796,7 +799,7 @@ private void generateJpmsArgs(CommandLineBuilder cmd) public String getMainClassname() { String mainClass = System.getProperty("jetty.server", isJPMS() ? MODULE_MAIN_CLASS : MAIN_CLASS); - Prop mainClassProp = getJvmEnvironment().getProperties().getProp("main.class", true); + Prop mainClassProp = getJettyEnvironment().getProperties().getProp("main.class", true); if (mainClassProp != null) return mainClassProp.value; return mainClass; @@ -804,7 +807,7 @@ public String getMainClassname() public String getMavenLocalRepoDir() { - String localRepo = getJvmEnvironment().getProperties().getString("maven.local.repo"); + String localRepo = getJettyEnvironment().getProperties().getString("maven.local.repo"); if (Utils.isBlank(localRepo)) localRepo = System.getenv("JETTY_MAVEN_LOCAL_REPO"); @@ -1007,7 +1010,7 @@ public void parse(ConfigSources sources) while (iter.hasPrevious()) { // Each source starts with server environment. - Environment environment = getJvmEnvironment(); + StartEnvironment environment = getJettyEnvironment(); ConfigSource source = iter.previous(); for (RawArgs.Entry arg : source.getArgs()) @@ -1021,7 +1024,7 @@ public void parse(ConfigSources sources) * @param arg the raw argument to parse * @param source the origin of this line of argument */ - public Environment parse(Environment environment, String arg, String source) + public StartEnvironment parse(StartEnvironment environment, String arg, String source) { StartLog.debug("parse(\"%s\", \"%s\")", arg, source); @@ -1066,7 +1069,7 @@ public Environment parse(Environment environment, String arg, String source) StartLog.info("reading commands from %s", baseHome.toShortForm(commands)); String s = source + "|" + baseHome.toShortForm(commands); - Environment originalEnvironment = environment; + StartEnvironment originalEnvironment = environment; for (String line : file) environment = parse(environment, line, s); environment = originalEnvironment; // environment doesn't propagate beyond command file. @@ -1267,7 +1270,7 @@ public Environment parse(Environment environment, String arg, String source) selectModules(source, moduleNames); Module module = getAllModules().get(moduleNames.get(moduleNames.size() - 1)); String envName = module == null ? null : module.getEnvironment(); - return envName == null ? jvmEnvironment : getEnvironment(envName); + return envName == null ? jettyEnvironment : getEnvironment(envName); } // Skip [files] validation on a module @@ -1287,7 +1290,7 @@ public Environment parse(Environment environment, String arg, String source) } if (environment == null) - environment = getJvmEnvironment(); + environment = getJettyEnvironment(); // Arbitrary Libraries if (arg.startsWith("--lib=") || arg.startsWith("--libs=")) @@ -1385,7 +1388,7 @@ else if (source != null) return new Prop(key, value, source); } - private void processAndSetProperty(Environment environment, String key, String value, String source) + private void processAndSetProperty(StartEnvironment environment, String key, String value, String source) { if (key.endsWith("+")) { @@ -1431,10 +1434,10 @@ public void setAllModules(Modules allModules) this.allModules = allModules; } - public void setProperty(Environment environment, String key, String value, String source) + public void setProperty(StartEnvironment environment, String key, String value, String source) { if (environment == null) - environment = getJvmEnvironment(); + environment = getJettyEnvironment(); Props properties = environment.getProperties(); // Special / Prevent override from start.ini's @@ -1504,6 +1507,6 @@ public void setRun(boolean run) public String toString() { return String.format("%s[enabledModules=%s, xml=%s, properties=%s, jvmArgs=%s]", - getClass().getSimpleName(), modules, getJvmEnvironment().getXmlFiles(), getJvmEnvironment().getProperties(), jvmArgSources.keySet()); + getClass().getSimpleName(), modules, getJettyEnvironment().getXmlFiles(), getJettyEnvironment().getProperties(), jvmArgSources.keySet()); } } diff --git a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartEnvironment.java similarity index 97% rename from jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java rename to jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartEnvironment.java index 45e6a93b391c..6c328cdf595b 100644 --- a/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/Environment.java +++ b/jetty-core/jetty-start/src/main/java/org/eclipse/jetty/start/StartEnvironment.java @@ -28,7 +28,7 @@ * build a runtime {@code org.eclipse.jetty.util.component.Environment} via * {@code --env} arguments passed to {@code org.eclipse.jetty.xml.XmlConfiguration#main(java.lang.String...)} */ -public class Environment +public class StartEnvironment { private final BaseHome _baseHome; private final String _name; @@ -62,7 +62,7 @@ public class Environment private final List _libRefs = new ArrayList<>(); - Environment(String name, BaseHome baseHome) + StartEnvironment(String name, BaseHome baseHome) { _name = name; _baseHome = baseHome; @@ -84,8 +84,8 @@ public void addPropertyFileRef(String arg) public void addUniquePropertyFile(String propertyFileRef, Path propertyFile) throws IOException { - if (!"server".equalsIgnoreCase(getName())) - throw new IllegalStateException("Property files not supported in non Server environments"); + if (!"Jetty".equalsIgnoreCase(getName())) + throw new IllegalStateException("Property files not supported in environment " + getName()); if (!FS.canReadFile(propertyFile)) { @@ -141,7 +141,7 @@ public void dumpProperties(PrintStream out) { out.println(); out.printf("Properties: %s%n", _name); - out.printf("--------------%n", "-".repeat(_name.length())); + out.printf("------------%s%n", "-".repeat(_name.length())); List sortedKeys = new ArrayList<>(); for (Props.Prop prop : _properties) diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java index 60e4aaaeab64..1e93bd7dd184 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/IncludeJettyDirTest.java @@ -59,7 +59,7 @@ public void assertSearchOrder(List expectedSearchOrder) public void assertProperty(String key, String expectedValue) { - Prop prop = args.getJvmEnvironment().getProperties().getProp(key); + Prop prop = args.getJettyEnvironment().getProperties().getProp(key); String prefix = "Prop[" + key + "]"; assertThat(prefix + " should have a value", prop, notNullValue()); assertThat(prefix + " value", prop.value, is(expectedValue)); diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java index 4a0e28795bce..7d7dee687fef 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/MainTest.java @@ -58,9 +58,9 @@ public void testStopProcessing() throws Exception StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[0])); // assertEquals(0, args.getEnabledModules().size(), "--stop should not build module tree"); - assertEquals("10000", args.getJvmEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); - assertEquals("foo", args.getJvmEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); - assertEquals("300", args.getJvmEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); + assertEquals("10000", args.getJettyEnvironment().getProperties().getString("STOP.PORT"), "--stop missing port"); + assertEquals("foo", args.getJettyEnvironment().getProperties().getString("STOP.KEY"), "--stop missing key"); + assertEquals("300", args.getJettyEnvironment().getProperties().getString("STOP.WAIT"), "--stop missing wait"); } @Test diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java index 6d6d499b6bea..f47b74a63f6b 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/ModulesTest.java @@ -69,7 +69,7 @@ public void testLoadAllModules() throws IOException modules.registerAll(); // Check versions - String platformProperty = args.getJvmEnvironment().getProperties().getString("java.version.platform"); + String platformProperty = args.getJettyEnvironment().getProperties().getString("java.version.platform"); assertThat("java.version.platform", Integer.parseInt(platformProperty), greaterThanOrEqualTo(8)); List moduleNames = new ArrayList<>(); @@ -247,7 +247,7 @@ public void testResolveNotRequiredModuleNotFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getJvmEnvironment().getProperties(); + Props props = args.getJettyEnvironment().getProperties(); assertThat(props.getString("bar.name"), is(nullValue())); } @@ -298,7 +298,7 @@ public void testResolveNotRequiredModuleFound() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getJvmEnvironment().getProperties(); + Props props = args.getJettyEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dive")); } @@ -349,7 +349,7 @@ public void testResolveNotRequiredModuleFoundDynamic() throws IOException assertThat("Resolved Names: " + actualNames, actualNames, contains(expectedNames.toArray())); - Props props = args.getJvmEnvironment().getProperties(); + Props props = args.getJettyEnvironment().getProperties(); assertThat(props.getString("bar.name"), is("dynamic")); } diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java index c9502af81894..a8c4c9a9482f 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/AbstractUseCase.java @@ -33,10 +33,10 @@ import java.util.stream.StreamSupport; import org.eclipse.jetty.start.BaseHome; -import org.eclipse.jetty.start.Environment; import org.eclipse.jetty.start.Main; import org.eclipse.jetty.start.Props; import org.eclipse.jetty.start.StartArgs; +import org.eclipse.jetty.start.StartEnvironment; import org.eclipse.jetty.start.StartLog; import org.eclipse.jetty.toolchain.test.FS; import org.eclipse.jetty.toolchain.test.jupiter.WorkDir; @@ -157,7 +157,7 @@ public static class ExecResults public List getXmls() { - return startArgs.getJvmEnvironment().getXmlFiles().stream() + return startArgs.getJettyEnvironment().getXmlFiles().stream() .map(p -> baseHome.toShortForm(p)) .collect(Collectors.toList()); } @@ -165,24 +165,24 @@ public List getXmls() public List getLibs() { return StreamSupport.stream( - Spliterators.spliteratorUnknownSize(startArgs.getJvmEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) + Spliterators.spliteratorUnknownSize(startArgs.getJettyEnvironment().getClasspath().iterator(), Spliterator.ORDERED), false) .map(f -> baseHome.toShortForm(f)) .collect(Collectors.toList()); } - public Collection getEnvironments() + public Collection getEnvironments() { return startArgs.getEnvironments(); } - public Environment getEnvironment(String name) + public StartEnvironment getEnvironment(String name) { return startArgs.getEnvironment(name); } public List getProperties() { - Props props = startArgs.getJvmEnvironment().getProperties(); + Props props = startArgs.getJettyEnvironment().getProperties(); Predicate propPredicate = (p) -> { diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java index 463ab775f8d5..be3db8f0d438 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/BasicTest.java @@ -98,7 +98,7 @@ public void testBasicProcessing() throws Exception PathAssert.assertDirExists("Required Directory: maindir/", results.baseHome.getPath("maindir/")); // === Validate home/base property uri values - Props props = results.startArgs.getJvmEnvironment().getProperties(); + Props props = results.startArgs.getJettyEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); @@ -408,7 +408,7 @@ public void testHomeWithSpaces() throws Exception assertThat("Properties", actualProperties, containsInAnyOrder(expectedProperties.toArray())); // === Validate home/base property uri values - Props props = results.startArgs.getJvmEnvironment().getProperties(); + Props props = results.startArgs.getJettyEnvironment().getProperties(); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(results.baseHome.getHome())); assertThat("Props(jetty.home)", props.getString("jetty.home"), is(not(startsWith("file:")))); diff --git a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java index a08fecbac29b..c6c0f5ecc151 100644 --- a/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java +++ b/jetty-core/jetty-start/src/test/java/org/eclipse/jetty/start/usecases/EnvironmentsTest.java @@ -20,7 +20,7 @@ import java.util.List; import java.util.Set; -import org.eclipse.jetty.start.Environment; +import org.eclipse.jetty.start.StartEnvironment; import org.eclipse.jetty.toolchain.test.FS; import org.junit.jupiter.api.Test; @@ -113,7 +113,7 @@ public void testTwoEnvironments() throws Exception assertThat(results.getEnvironments(), hasSize(2)); for (String e : List.of("envA", "envB")) { - Environment environment = results.getEnvironment(e); + StartEnvironment environment = results.getEnvironment(e); assertThat(environment, notNullValue()); assertThat(environment.getName(), is(e)); assertThat(environment.getClasspath().getElements(), contains(baseDir.resolve("lib/%s.jar".formatted(e)))); diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java index 5b7fb1125fe1..c4afe74b57a0 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/component/Environment.java @@ -28,7 +28,7 @@ public interface Environment extends Attributes { // Ensure there is a core environment for possible later deployments to it - Environment CORE = ensure("Core"); + Environment CORE = ensure("core"); static Collection getAll() { From 8b3ec422746c9805349aca751213c9c46bc17397 Mon Sep 17 00:00:00 2001 From: gregw Date: Thu, 13 Apr 2023 08:37:31 +0200 Subject: [PATCH 050/129] updates from review --- .../org/eclipse/jetty/deploy/providers/ScanningAppProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java index b023112f34ef..8f9fc6c760a0 100644 --- a/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java +++ b/jetty-core/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ScanningAppProvider.java @@ -188,7 +188,7 @@ else if (coreProvider) } // If we are the default provider then we may warn - if (defaultEnvironmentName != null && defaultEnvironmentName.equalsIgnoreCase(getEnvironmentName())) + if (getEnvironmentName().equalsIgnoreCase(defaultEnvironmentName)) { // if the app specified an environment name, then produce warning if there is no provider for it. if (!_deploymentManager.hasAppProviderFor(environmentName)) From 652eac87934d7529d77ca60691458625c29dd294 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 13 Apr 2023 17:56:19 +0200 Subject: [PATCH 051/129] Add new security jar to osgi container deployment --- .../test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java index 4d4d13b2c4a9..9e48c46c49a5 100644 --- a/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java +++ b/jetty-ee10/jetty-ee10-osgi/test-jetty-ee10-osgi/src/test/java/org/eclipse/jetty/ee10/osgi/test/TestOSGiUtil.java @@ -201,6 +201,7 @@ public static void coreJettyDependencies(List