Expected Behavior

FormLogin should be configurable to take in username and password as a predefined json object.

Current Behavior

FormLogin currently only accepts requests with form parameters.

Context

Most people today that write front end application deal with json and not form parameters. Its very easy to send form parameters using javascript fetch, but most just dont do it. They usually want to send data using json, and in 99% of the cases they send it as:

{
    "username": "foobar",
    "password": "secret"
}

currently the only way to get spring security to handle this is to completely opt-out from form login, and instead write either a custom filter or a custom endpoint which has to create the security context manually. This leads to many confusing questions on stack overflow, faulty implementations, and general opinions on spring security being overly complex just to do something as simple as a json formatted login.

My proposal is that either formLogin should be, just like the oauth resource server part of spring security (that can be configured to either take an opague token or a jwt) configurable to take form login parameters or json login parameters.

Example:

formLogin(formLoginSpec::json)

Many also wish to return JWTs after login to establish a session (which im not a big fan of but that is my personal opinion) then they can leverage features in form login like AuthenticationSuccessHandlers to build their JWTs, which i find fits the spring security features better than many constructing custom filters etc.

Comment From: sjohnr

@Tandolf, thanks for the suggestion! Have a look at AuthenticationFilter. This class has strong parity with AuthenticationWebFilter and is highly flexible, yet isn't used in any built-in configurers as of yet. I'm curious what your thoughts are on using this class for this use case.

Comment From: Toerktumlare

Hi @sjohnr i had a look at it and that class does look viable for the usercase above. But in the case of using that filter there needs to be a written a custom AuthenticationConverter supplied as a Bean that will convert the given json to a Authentication object.

But i believe that the filter you linked with a custom converter does solve the usercase. And then the option to configure the usage of it when opting in for formLogin.

I dont know if it even should be called formLogin, or if it should be called jsonLogin or just login. I leave the api up to the spring team.

Comment From: sjohnr

Hi @Tandolf, I agree that naming is tough, often the most difficult part! 😄 This definitely sounds different from formLogin. But perhaps we can forestall that decision and focus on the converter first.

We could look at OAuth2AccessTokenResponseHttpMessageConverter in oauth2-client module for possible inspiration.

Comment From: Toerktumlare

i cloned spring security and tried to get it to build but im not that well versed with gradle. I get a 401 unauthorized when it is trying to fetch a plugin io.spring.gradle-enterprise-conventions.gradle.plugin-0.0.2.jar during build.

But i looked a bit at the class you suggested but guess we could maybe use MappingJackson2HttpMessageConverter to convert the incoming json?

Comment From: sjohnr

I'd have to double check in all scenarios, but I believe Jackson is an optional dependency (at least in oauth2-client). Therefore, OAuth2AccessTokenResponseHttpMessageConverter uses an internal utility HttpMessageConverters.getJsonMessageConverter() to resolve a GenericHttpMessageConverter. That's one possible approach to think about.

Comment From: mrksph

Hey there, I’d like to bring this up for discussion again.

When Spring Boot is used as a REST API for a separate frontend (a very common setup), it’s also quite common for login requests to send credentials in the request body as JSON (i.e., using the application/json content type), rather than as form data parameters. For example: { "username" / "email": "...", "password": "..." }.

It would be really helpful to have a predefined authentication filter that can read credentials from a JSON request body, where users can simply configure which field names to use (e.g., username, email, etc.).

Comment From: Toerktumlare

@mrksph Currently when using FormLogin credentials are already sent in the body in the FORM format.

I’m assuming you mean that you want the credentials in the body in a different format, and i guess you are meaning JSON?

Comment From: mrksph

@Toerktumlare sorry, my mistake you are totally right, I will edit my post.