Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I setup Login with Spring Security and Vue.js?

I'm currently developing a Web Application using Spring (with Spring Security) and Vue.js. I've built some Web Applications before but they are just for school purposes so they're mostly incomplete when it comes to Authentication and Authorization. So, as you can see, I'm really unexperienced when it comes to Spring Boot and Spring Security stuff.

My project is setup the following way:

project-folder

  • project-server (Spring -> localhost:9000)
  • project-web (Vue.js CLI -> localhost:8080)

I was following a tutorial to implement Spring Security and, right now, I can use the built-in Login form to authenticate my User with the credentials I have stored in my MySQL database.

The problem is I don't want to use this Login Page and I want to create my own in my frontend project. I've looked it up and I can change the Login Page but I believe it needs to be in my resources folder inside my backend project folders. However, my project isn't set up this way and I'd rather not change it (if possible). I thought I could just reference my API through the URL but I noticed Spring Security does not send a HTTP 200 Response when Login succeeds but instead sends a HTTP 302 Redirect Response. I've seen solutions that disable the form login and then use JWT's for authentication but I've also seen that it's not a good practice because there's no way to revoke this token.

Here's how my ApplicationSecurityConfig looks

@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {

private final PasswordEncoder passwordEncoder;
private final ApplicationUserService applicationUserService;

@Autowired
public ApplicationSecurityConfig(PasswordEncoder passwordEncoder,
                                 ApplicationUserService applicationUserService) {
    this.passwordEncoder = passwordEncoder;
    this.applicationUserService = applicationUserService;
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/", "/css/*", "/js/*").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .usernameParameter("email")
            .and()
            .logout()
                .logoutUrl("/logout")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "GET"))
                .clearAuthentication(true)
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID", "remember-me")
                .logoutSuccessUrl("/login");
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .userDetailsService(applicationUserService)
            .passwordEncoder(passwordEncoder);
}

}

So, is there a way to create an external login page and use Spring Security authentication and authorization features?

like image 530
jmbds Avatar asked Oct 30 '25 19:10

jmbds


1 Answers

There are many solutions for this problem and it mostly depends on what your requirements are and how you are structuring the application, here are a couple of scenarios that come to my mind:

REST API + Vuejs + JWT

If the entire front-end is built with Vuejs then probably the back-end will only consist of a REST API that sends and receives JSON, in this case a stateless authentication mechanism is what works better, like JSON Web Token(JWT).

In this scenario the the server exposes an endpoint, let's say /auth/login, at which you can send a username and password and the server will answer with a token. Once the Vue front has a valid token it must send it as part of the request header for each subsequent API call that is under authentication, this will ensure the user is who claims to be and has the right permissions for accessing the API.

The way JWT works is because is composed of three parts:

  • A header which contains information about the algorithm used to sign the token.
  • A body with the information about the logged in user (username, roles, token expiration date, custom fields, etc.).
  • A signature which consists of a hash of the header, the body and a secret key only known by the server.

With this information the server can verify the user has a valid token (it has been generated by the server after successful login and is not expired) without the need of a session.

For more information about JWT check https://jwt.io/ and RFC 7519, also if you need a good Java implementation i've used the one from Auth0 in the past and works very well.

Mixed server side templating + Vuejs + Cookie

In some cases you will have a mixed application when part of the front is being generated by some template engine in the server and some will be managed by Vuejs on the client side, and probably you will already have a session based authentication in pace. If that's the case you can still integrate the authentication, remember that at the end the server is only sending the client a cookie with the session ID stored on the server, so if you send back the cookie with every request the server will recognize the user as authenticated and allow the API to be called.

The problem in this case is that you are making requests from different domains so the cookie will not get propagated, you could configure webpack from the Vue side to build the project under project-server/src/main/resources/static and serve the page from Spring so that the front and back end are under the same domain and the cookie should get sent with the ajax requests.

like image 54
Daniel Camarda Avatar answered Nov 02 '25 10:11

Daniel Camarda