Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jetty 12 - Added a core Session abstraction #9223

Merged
merged 8 commits into from
Feb 2, 2023

Conversation

gregw
Copy link
Contributor

@gregw gregw commented Jan 30, 2023

Sessions were already a core mechanism, but there was no API for them.

There is now a new Session interface that is available via the Request API. It is intended only for users of sessions.

The previous concrete class Session has been renamed to ManagedSession and it is used by classes that extend AbstractSessionManager.

Sessions were already a core mechanism, but there was no API for them.
There is now a new Session interface that is available via the Request API.  It is intended only for users of sessions.
The previous concrete class Session has been renamed to ManagedSession and it is used by classes that extend AbstractSessionManager.
…core-sessions

# Conflicts:
#	jetty-core/jetty-session/src/main/java/org/eclipse/jetty/session/SessionManager.java
#	jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/AbstractSessionManagerTest.java
#	jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/SimpleSessionHandler.java
#	jetty-core/jetty-session/src/test/java/org/eclipse/jetty/session/TestableSessionManager.java
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletApiRequest.java
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletContextResponse.java
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/SessionHandler.java
#	jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/security/authentication/LoginAuthenticator.java
#	jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Request.java
#	jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Response.java
#	jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/SessionHandler.java
#	jetty-ee9/jetty-ee9-security/src/main/java/org/eclipse/jetty/ee9/security/authentication/LoginAuthenticator.java
@gregw gregw marked this pull request as ready for review January 31, 2023 01:54
@joakime joakime added this to the 12.0.x milestone Jan 31, 2023
@joakime joakime changed the title Added a core Session abstraction Jetty 12 - Added a core Session abstraction Jan 31, 2023
Copy link
Contributor

@janbartel janbartel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple of questions/suggestions.

@@ -339,6 +335,7 @@ public boolean isInvalid()
{
try (AutoLock l = _lock.lock())
{
// TODO this is not the inverse of isValue???? what about CHANGING
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VALID is self evident. INVALID also. CHANGING means in the process of changing the session id and INVALIDATING means in the process of becoming invalid. The spec says that when session callbacks happen during invalidation, the session must still be readable, but is mute about what should happen when the session is changing its id. See checkValidForRead and checkValidForWrite which try to implement what the spec wants wrt to session validity. We could probably re-evaluate how isValid and isInvalid are used and see if it can be simplified - after this PR is done with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed a few usages of it and then renamed to isInvalidOrInvalidating

@@ -75,33 +76,33 @@ public interface SessionManager extends LifeCycle, SessionConfig
*/
String __MaxAgeProperty = "org.eclipse.jetty.servlet.MaxAge";

Session getSession(String id) throws Exception;
ManagedSession getManagedSession(String id) throws Exception;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be Session and not ManagedSession?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Users and/or extenders of SessionManager are using the concrete ManagedSession. For example, soon after calling getManagedSession(id), the access method may be called on the returned session. This is not available in the public Session API as an application should not call access.

return httpSession.getId();
}

public ManagedSession getManagedSession()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the signature should be Session?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The callers of this method are doing ManagedSession stuff like:

  • resetting cookies on response.reset() (and cookies are not a known part of the application Session API. Cookies are implementation details as we can track sessions with other mechanisms.
  • committing the response so they need to flush the session to any datastore. This is an implementation detail.
  • completing the response... ditto.

return null;
_api = _manager.newSessionAPIWrapper(this);
if (_api != null && _api.getSession() != this)
throw new IllegalStateException("APISession must wrap this session");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
throw new IllegalStateException("APISession must wrap this session");
throw new IllegalStateException("Session.API must wrap this session");

}

public void setAPISession(Object o)
public <T extends API> T getAPISession()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public <T extends API> T getAPISession()
public <T extends API> T getAPI()

private Authentication _authentication;
private String _method;
private ServletMultiPartFormData.Parts _parts;
private ServletPathMapping _servletPathMapping;
private boolean _asyncSupported = true;

protected ServletApiRequest(ServletContextRequest servletContextRequest)
{
this._request = servletContextRequest;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
this._request = servletContextRequest;
_request = servletContextRequest;

@@ -107,7 +108,7 @@ public abstract class AbstractSessionCache extends ContainerLifeCycle implements
* @return a new Session object
*/
@Override
public abstract Session newSession(SessionData data);
public abstract ManagedSession newSession(SessionData data);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do these all need to use the ManagedSession class and not the Session interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Applications use Session.
Implementations of Session use SessionManagers and SessionHandlers and SessionCaches and SessionData to implement a ManagedSession, thus they communicate within themselves with ManagedSession.

If you are just a handler/servlet that wants to use a session, you just see/use Session interface. But if you are implementing/extending our style of concrete session you see/use ManagedSession

Improved javadoc
used util Attributes interface.

return _coreSession.getAPISession();
if (session.isNew() && getAuthentication() instanceof Authentication.User)
session.setAttribute(ManagedSession.SESSION_CREATED_SECURE, Boolean.TRUE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You said you would move this attribute onto Session interface instead of ManagedSession?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a security feature. When you move ee10 security to core then I'll move this... or better yet do away with it. For now it has no good home and it's a bit of leaked implementation, so ManagedSession is probably the right place.

ServletApiRequest servletApiRequest = _response.getServletContextRequest().getServletApiRequest();
Session session = servletApiRequest.getCoreSession();
ManagedSession session = servletApiRequest.getServletContextRequest().getManagedSession();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like that the servlet layer is dependent on a particular implementation of the Session interface.

Is it possible to generalize this so that it can all be done through the jetty-server Session interface so it would work if you used a different implementation of Session.

Maybe SessionManager should be a jetty-server interface as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably possible. But currently ManagedSession contains servlet specific features like passivation and listeners. It would need to be split to move those boys into some servlet common module.... That we don't yet have. So a good thing to look at, but that's a different PR i think.

Copy link
Contributor

@lachlan-roberts lachlan-roberts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't like the design that jetty-server has the Session interface, but any implementation you can use must be based off the ManagedSession from jetty-session module.

Id rather a more complete set of interfaces in jetty-server, or have jetty-session use an attribute to store session instead of having a direct getter on the jetty-server request.

But hopefully this can be improved in further PRs.

@gregw
Copy link
Contributor Author

gregw commented Feb 2, 2023

I still don't like the design that jetty-server has the Session interface, but any implementation you can use must be based off the ManagedSession from jetty-session module.

Again this is because all our current usages are based on servlet API, which has a lot of it's implementation in ManagedSession.

When we (you) move security to core, it should just use the session interface and nothing else.

We can also eventually split the servlet stuff out of ManagedSession and put in a servlet common package.

Id rather a more complete set of interfaces in jetty-server, or have jetty-session use an attribute to store session instead of having a direct getter on the jetty-server request.

I don't see how using an attribute would help?

@gregw gregw merged commit ebc6cca into jetty-12.0.x Feb 2, 2023
@gregw gregw deleted the jetty-12.0.x-core-sessions branch February 2, 2023 20:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants