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

Fix 'response head already sent' when the login request to form-based authentication when proactive authentication is disabled #46418

Conversation

michalvavrik
Copy link
Member

Copy link

quarkus-bot bot commented Feb 21, 2025

Thanks for your pull request!

Your pull request does not follow our editorial rules. Could you have a look?

  • title should preferably start with an uppercase character (if it makes sense!)
  • title should not start with chore/docs/feat/fix/refactor but be a proper sentence

This message is automatically generated by a bot.

@michalvavrik michalvavrik changed the title fix(security): expect form post-location to authenticate and end Fix 'response already sent' when the login request to form-based authentication when proactive authentication is disabled Feb 21, 2025
@michalvavrik michalvavrik changed the title Fix 'response already sent' when the login request to form-based authentication when proactive authentication is disabled Fix 'response head already sent' when the login request to form-based authentication when proactive authentication is disabled Feb 21, 2025
// we expect that form-based authentication mechanism to recognize the post-location,
// authenticate and if user provided credentials in form attribute, response will be ended
if (!event.response().ended()) {
event.response().end();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is event.response().end(); actually intended here? Why not event.next()?

Copy link
Member Author

@michalvavrik michalvavrik Feb 21, 2025

Choose a reason for hiding this comment

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

Is event.response().end(); actually intended here? Why not event.next()?

It is, I don't know why Stuart implemented this whole endpoint this way, I think one they someone will report bug regarding other authentication mechanisms interfering, but when you call https://quarkus.io/guides/all-config#quarkus-vertx-http_quarkus-http-auth-form-post-location request path, you are supposed to be logged in and that is it. It should not continue let say to Quarkus REST (which is what was happening) or somewhere else. There is following property:

  • quarkus.http.auth.form.landing-page that is where Quarkus redirects you if this request was successful to log in
  • is it is not set, e.g. like quarkus.http.auth.form.landing-page=, then we return 200 (for SPA where JS determines what next)

So I never actually expect this to be not ended. I was strongly considering to return 500 and log some error message, but there are users that inherit from this mechanism and customize it, I am not 100 % sure what they do, hence just ending it.

Copy link
Member Author

Choose a reason for hiding this comment

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

of course we can continue using event.next(), but I don't see a point. if you have an idea, I can change it, it is not the root cause

Copy link
Member Author

Choose a reason for hiding this comment

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

also I am not 100 % there is always some handler that ends the response, I never checked if Vert.x or Quarkus has something like "last resort handler" that ends it if noone else did?

Copy link
Member Author

Choose a reason for hiding this comment

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

I suppose it is implemented this way to align with proactive auth.

Copy link
Member Author

Choose a reason for hiding this comment

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

@sberyozkin I am just fixing bug (IMHO correctly), it is not my design/code, that is how it worked from the start (I assume).

No, I don't think it can be constrained to the FormAuthenticationMechanism because we know some users inherits this mechanism, some can use delegate pattern and call that mechanism completely differently. We would break their applications. This code is basically same thing as:

  • enforce authentication for path /j_security_check

So it is completely safe, I just don't think it is always reliable, like if there are other authentication mechanisms like the code flow, they can interfere). So maybe some users will need to use path-based authentication if they combine multiple authentication mechanisms.

Copy link
Member Author

@michalvavrik michalvavrik Feb 21, 2025

Choose a reason for hiding this comment

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

One more thing, from @geoand and @sberyozkin questions I am not sure it is clear, maybe I should had written it to the PR description. The issue here was that FormAuthenticationMechanism does what is supposed to do, it sends the response, but this code still did next(). The fact that I added end(), well, it just felt right. :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, what you did feels right to me too, but I am not privy to this code at all

Copy link
Member

@sberyozkin sberyozkin Feb 21, 2025

Choose a reason for hiding this comment

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

@michalvavrik Oh, this code is specific to the form processing, done inside the form specific handler, it was not easy to see it in the PR, so LGTM

Copy link
Member Author

Choose a reason for hiding this comment

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

fun fact, I think this issue #30637 is example of such unreliability I mentioned; wdyt @sberyozkin ? we can move discussion into the issue

Copy link

quarkus-bot bot commented Feb 21, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit e1b6dd3.

✅ The latest workflow run for the pull request has completed successfully.

It should be safe to merge provided you have a look at the other checks in the summary.

You can consult the Develocity build scans.


Flaky tests - Develocity

⚙️ JVM Tests - JDK 17

📦 extensions/infinispan-cache/deployment

io.quarkus.cache.infinispan.InfinispanCacheTest.testGetAsyncWithParallelCalls - History

  • expected: "thread1" but was: "thread2" - org.opentest4j.AssertionFailedError
org.opentest4j.AssertionFailedError: 

expected: "thread1"
 but was: "thread2"
	at io.quarkus.cache.infinispan.InfinispanCacheTest.testGetAsyncWithParallelCalls(InfinispanCacheTest.java:283)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at io.quarkus.test.QuarkusUnitTest.runExtensionMethod(QuarkusUnitTest.java:513)
	at io.quarkus.test.QuarkusUnitTest.interceptTestMethod(QuarkusUnitTest.java:427)

⚙️ JVM Tests - JDK 21

📦 extensions/hibernate-orm/deployment

io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest.testFieldAccess - History

  • expected: io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest$ContainedEntity@5adafe99 but was: null - org.opentest4j.AssertionFailedError
org.opentest4j.AssertionFailedError: 

expected: io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest$ContainedEntity@5adafe99
 but was: null
	at io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest$FieldAccessEnhancedDelegate$5.assertValueAndLaziness(PublicFieldAccessAssociationsTest.java:240)
	at io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest.doTestFieldAccess(PublicFieldAccessAssociationsTest.java:106)
	at io.quarkus.hibernate.orm.applicationfieldaccess.PublicFieldAccessAssociationsTest.testFieldAccess(PublicFieldAccessAssociationsTest.java:60)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)

@sberyozkin sberyozkin merged commit 85febb0 into quarkusio:main Feb 21, 2025
55 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.21 - main milestone Feb 21, 2025
@michalvavrik michalvavrik deleted the feature/fix-form-post-location-response-already-sent branch February 21, 2025 14:10
@gsmet gsmet modified the milestones: 3.21 - main, 3.19.1 Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IllegalStateException: Response head already sent during login
4 participants