Skip to content

Improved Session Management #240

Merged
ndp-opendap merged 34 commits intomasterfrom
ndp/session-shenanigans
Sep 17, 2025
Merged

Improved Session Management #240
ndp-opendap merged 34 commits intomasterfrom
ndp/session-shenanigans

Conversation

@ndp-opendap
Copy link
Contributor

All the things:

  • invalidate after auth
  • client finger printing.

Copy link
Member

@jgallagher59701 jgallagher59701 left a comment

Choose a reason for hiding this comment

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

Thanks

}

value = request.getHeader(USER_AGENT_KEY);
if( d_clientUserAgent == null || !d_clientUserAgent.equals(value) ) {
Copy link
Member

Choose a reason for hiding this comment

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

Is it usual that authentication requires a valid User-Agent value? Ah, I see it is, at least according to Google, that makes sense:

However, in practical terms, many servers and web applications expect the User-Agent header to be present and may behave differently or even reject requests that do not include it.

And there's probably no way to test this other than let the code sit in UAT for a while and see what shakes loose.

* @return The enum value for the units
*/
TimeUnits stringToTimeUnits(String timeUnitsStr) {
if(timeUnitsStr!=null){
Copy link
Collaborator

Choose a reason for hiding this comment

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

for each of these, is it worth supporting the user inadvertently using singular rather than plural units? or is that unlikely/deemed user error? especially since the fallback is to return as if the unit was seconds....

// <MaxSessionLife units="weeks">2</MaxSessionLife>

vs

// <MaxSessionLife units="week">1</MaxSessionLife>

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 was debating startsWith("w") etc...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

        if(timeUnitsStr.toLowerCase().startsWith("min")){

Copy link
Contributor Author

@ndp-opendap ndp-opendap Sep 15, 2025

Choose a reason for hiding this comment

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

Something has been nagging me about this and I looked a little closer:

I don't think implementing: TimeUnits stringToTimeUnits(String timeUnitsStr) is the way when one can:

        TimeUnits units = TimeUnits.valueOf(unitsStr.toUpperCase());

It also enforces correct spelling, and it throws IllegalArgumentException if the string doesn't map to a value.

Which doesn't make it lenient as you suggested, but it does utilize more built in machinery.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yep, that sounds good to me---especially if this is something that would be exposed to a user who encountered it.

...this would be someone standing up a hyrax server for the first time, right? so they'd definitely see the message and the failure and be able to do something about it?

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 would show up in the tomcat logs. And many users would struggle to figure it out.

I am thinking maybe lenient is better.

Consider:

    TimeUnits stringToTimeUnits(String timeUnitsStr) {
        if(timeUnitsStr!=null){
            if(timeUnitsStr.toLowerCase().startsWith("mil")){
                return TimeUnits.MILLISECONDS;
            }
            if(timeUnitsStr.toLowerCase().startsWith("s")){
                return TimeUnits.SECONDS;
            }
            if(timeUnitsStr.toLowerCase().startsWith("min")){
                return TimeUnits.MINUTES;
            }
            if(timeUnitsStr.toLowerCase().startsWith("h")){
                return TimeUnits.HOURS;
            }
            if(timeUnitsStr.toLowerCase().startsWith("d")){
                return TimeUnits.DAYS;
            }
            if(timeUnitsStr.toLowerCase().startsWith("w")){
                return TimeUnits.WEEKS;
            }
        }
        return TimeUnits.SECONDS;
    }

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, that looks good to me---esp if there's a default option that at the very least logs a warning that we've fallen back to the default case

}
if(timeUnitsStr.equalsIgnoreCase("weeks")){
return TimeUnits.WEEKS;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

worth adding a warning here (to debug/log) with the unrecognized unit?

if(sessionIsExpired(session)){
log.debug("Invalidating expired session: {}", session.getId());
session.invalidate();
session = request.getSession(true);
Copy link
Collaborator

Choose a reason for hiding this comment

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

is there ever a way we could get caught in a loop through recursion here? if the maxSessionTimeSeconds is really small (or takes roughly the same amount of time as it takes to create a new session via request.getSession(true)...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the user could contrive to deploy with some tiny max session time and break their deployment.

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 should add that the clients would prolly end up with a "too may redirects" error

log = LoggerFactory.getLogger(this.getClass());
setAuthContext(DEFAULT_AUTH_CONTEXT);
setDescription("The NASA Earthdata Login (formerly known as URS)");
setDescription("NASA Earthdata Login");
Copy link
Collaborator

Choose a reason for hiding this comment

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

🫡

* @return An EarthDataLoginAccessToken object built from the response from the EDL SSO.
* @throws IOException
*/
public EarthDataLoginAccessToken exchangeAuthCodeForEdlToken(String code, String returnToUrl) throws IOException {
Copy link
Collaborator

Choose a reason for hiding this comment

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

...this refactor (pulling this set of code into a new exchangeAuthCodeForEdlToken function) is orthogonal to the task at hand, right? Or am I misunderstanding and there's a specific reason to do it as part of this PR? If possible, I'd prefer to do it as a separate follow-up PR, esp since we already know we have some EDL auth cleanup/refactoring to do in the near future.

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 know this is a bad thing I did, but I couldn't follow the mess of complexity. And I doubt we will ever get back here to do any meaningful cleanup refactoring . We should discuss in person I think.

sb.append(indent).append("\"").append(getClass().getName()).append("\" : {");

String l2i = l1i +indent_inc;
String jsonObjName = getClass().getName().replace(".","_");
Copy link
Collaborator

Choose a reason for hiding this comment

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

love 2 hand-build json string :D

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah - this is addressed in a my ndp/profile-serialization branch. There's a bunch of work there and a lot of change. More merge challenges for sure.

@sonarqubecloud
Copy link

@ndp-opendap ndp-opendap merged commit 4544ba5 into master Sep 17, 2025
3 checks passed
@ndp-opendap ndp-opendap deleted the ndp/session-shenanigans branch September 17, 2025 15:11
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.

3 participants