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

HttpServletRequest.login() not creating Form Authentication cookie #169

Open
melloware opened this issue Nov 17, 2024 · 3 comments
Open

Comments

@melloware
Copy link
Contributor

melloware commented Nov 17, 2024

Zulip: https://quarkusio.zulipchat.com/#narrow/channel/187038-dev/topic/j_security_check.20Programmatic.20Login.3F

Original Issue: melloware/quarkus-faces#409

Issue

If you do servletRequest.login(user, pass) no Quakrus Cookie is created when it should be.

Workaround

A hack workaround is to manually call /j_security_check, get the response, and if it contains the set-cookie header which is set by Quarkus, I also set that cookie in the original FacesContext Response. But I don't like this approach.

@Named
@RequestScoped
public class LoginController {

  String username;
  String password;

  @ConfigProperty(name = "quarkus.http.auth.form.cookie-name")
  String cookieName;

  @Inject
  FacesContext facesContext;

  public void login() {
    var request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
    var securityCheckUrl = request.getRequestURL().toString()
          .replace("/login.xhtml", "/j_security_check");
    var response = HttpClient.newHttpClient().send(HttpRequest.newBuilder()
          .uri(URI.create(securityCheckUrl))
          .POST(HttpRequest.BodyPublishers.ofString(
              "j_username=" + username + "&j_password=" + password))
          .header("Content-Type", "application/x-www-form-urlencoded")
          .build(), HttpResponse.BodyHandlers.ofString());
    var fcResponse = (HttpServletResponse) facesContext.getExternalContext().getResponse();
    var responseMap = response.headers().map();
    if (responseMap.containsKey("set-cookie")) {
      var cookieString = responseMap.get("set-cookie").get(0);
      var quarkusCookie = new Cookie(cookieName, cookieString.split("=")[1]);
      quarkusCookie.setMaxAge(8 * 60 * 60);
      quarkusCookie.setHttpOnly(true);
      fcResponse.addCookie(quarkusCookie);
    }
    facesContext.getExternalContext().redirect("/mainPage.xhtml");
  }
}

Undertow Code

Here is the current Undertow code:

@Override
public void login(final String username, final String password) throws ServletException {
if (username == null || password == null) {
throw UndertowServletMessages.MESSAGES.loginFailed();
}
SecurityContext sc = exchange.getSecurityContext();
if (sc.isAuthenticated()) {
throw UndertowServletMessages.MESSAGES.userAlreadyLoggedIn();
}
boolean login = false;
try {
login = sc.login(username, password);
} catch (SecurityException se) {
if (se.getCause() instanceof ServletException)
throw (ServletException) se.getCause();
throw new ServletException(se);
}
if (!login) {
throw UndertowServletMessages.MESSAGES.loginFailed();
}
}

@melloware
Copy link
Contributor Author

@stuartwdouglas @cescoffier i am not familiar enough with how core Quarkus adds the quarkus.http.auth.form.cookie-name credential cookie but from this code it looks like SecurityContext.login(username, password) should also be doing it or maybe if not part of that it should be right after that line of code if login == true ?

@melloware
Copy link
Contributor Author

Debugging this I can verify the FormAuthenticationMechanism is not in the chain.

Image

@melloware melloware changed the title HttpServletRequest.login() not creating cookies HttpServletRequest.login() not creating Form Authentication cookie Nov 18, 2024
@melloware
Copy link
Contributor Author

Reproducer:
quarkus-faces-formauth.zip

  1. Run mvn quarkus:dev
  2. Navigate to http://localhost:8080
  3. Press the "Login" button.
  4. Note that no quarkus-credential cookie is created in the browser.
  5. Press "Login" again and you will get error "Already authenticated".

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

No branches or pull requests

1 participant