DEV Community

Cover image for Spring Security 103: Exploring Default Security Configuration
Priya
Priya

Posted on • Edited on

Spring Security 103: Exploring Default Security Configuration

In this blog post, we'll delve into the default security settings that Spring Security applies to your application. We’ll examine how authentication, CORS, CSRF protection, and frame options are configured out of the box and discuss their implications for securing your application.

➼ Comprehensive Protection

By default, Spring Security applies robust security measures across your entire application. Whether you're building a web application or a REST API, every endpoint is protected. This means that even to check if a URL exists, users must be authenticated. This secure-by-default approach is crucial for preventing unauthorized access to your application's resources.


➼ Built-in Form Authentication

Spring Security provides a built-in login mechanism for web applications, which includes:

  • Default Pages: A standard login page accessible at /login and a logout page at /logout.
  • Session Management: Upon successful login, a session ID is generated and sent to the user's browser as a session cookie. This cookie is included in every subsequent request, maintaining the user's authenticated state.

Session cookie

Customizing Authentication Pages

You can easily customize the login and logout pages to fit your application's design.

1. Create login.jsp

Ensure your JSP files are in src/main/webapp/WEB-INF/jsp/:

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <h1>Login</h1>
    <form action="/login" method="post">
        <table>
            <tr>
                <td>Username:</td>
                <td><input type="text" name="username" required></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type="password" name="password" required></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" value="Login"></td>
            </tr>
        </table>
    </form>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

2. Configure application.properties

Add the following configuration to your application.properties file to set up the view resolver for JSPs:

spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
Enter fullscreen mode Exit fullscreen mode

3. Create LoginController.java:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login"; // Refers to /WEB-INF/jsp/login.jsp
    }

    @GetMapping("/logout-success")
    public String logoutSuccess() {
        return "logout"; // Refers to /WEB-INF/jsp/logout.jsp
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Configure Spring Security

Ensure your Spring Security configuration points to the custom login and logout pages:

SecurityConfiguration.java:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated() 
                .and()
            .formLogin()
                .loginPage("/login") // Custom login page URL
                .permitAll() // Allow everyone to access it
                .and()
            .logout()
                .logoutUrl("/logout") // Custom logout URL
                .logoutSuccessUrl("/logout-success") // Redirect after logout
                .permitAll() // Allow everyone to access it
        return http.build();
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Ensure Dependencies

Verify that your pom.xml includes the necessary dependencies (to use JSP, you need tomcat jasper):

For Maven:

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <version>9.0.58</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

➼ Default Basic Authentication

In the context of REST APIs, Basic Authentication involves sending credentials in the Authorization header of HTTP requests:

Authorization: Basic {Base64 encoded username:password}
Enter fullscreen mode Exit fullscreen mode

When using API clients like Postman or Talend, you'll input the credentials directly to access protected endpoints.

Basic authorization

Limitations of Basic Authentication

  • Encoded, Not Encrypted: Credentials are Base64-encoded but not encrypted, making them vulnerable to interception and decoding by attackers.
  • No Built-In Expiration: Basic Authentication lacks mechanisms for expiring or refreshing credentials, which can lead to security risks.
  • Limited Authorization Control: It doesn’t support fine-grained authorization, which restricts its use in more complex applications.

For enhanced security, JWT Authentication is recommended. JWT offers more robust security features and greater flexibility, though it comes with added complexity. We'll cover JWT and its configuration in upcoming posts.


➼ CORS Configuration

CORS, or Cross-Origin Resource Sharing, is a security feature implemented by browsers to prevent web pages from making requests to a different domain than the one that served the web page. It helps protect users from malicious websites attempting to access resources or data from another origin without permission.

Default Behavior

By default, browsers restrict cross-origin requests to enhance security. For example, if you have a REST API deployed on example1.com and try to access it from a frontend application deployed on example2.com, you will encounter a CORS error.

Configuration Example

To configure CORS and allow your application to accept requests from different origins, you can customize the WebMvcConfigurer class like this:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this code snippet:

  • addMapping("/**") specifies the URL patterns that the CORS configuration should apply to. Here, "/**" means that CORS settings will apply to all endpoints in your application.
  • allowedOrigins("*") allows requests from any origin. For production, it's recommended to specify exact origins to enhance security, e.g., allowedOrigins("https://example2.com").

➼ CSRF Protection

CSRF, or Cross-Site Request Forgery, is a security vulnerability that allows an attacker to trick a user into performing actions on a web application without their knowledge. This is done by exploiting the user’s authenticated session with that application.

Example: Understanding CSRF Through a Real-World Scenario

  1. User Authentication: Imagine a user logs in to their bank’s website, entering their credentials to access their account.
  2. Session Creation: Upon successful login, the bank’s website creates a session for the user. This session is stored in the user's browser as a session cookie, which is automatically included in all subsequent requests to the bank’s server.
  3. Automatic Authentication: Now, whenever the user interacts with the bank’s website—whether checking their balance or making a transfer—the session cookie is sent along with the request, allowing the server to authenticate the user without requiring them to log in again.
  4. Visiting a Malicious Site: Later, the user unknowingly visits a malicious website while still logged in to the bank’s website. This malicious site is crafted by an attacker and contains hidden forms or scripts designed to exploit the user’s active session with the bank.
  5. Exploiting the Session: The malicious website silently sends a request to the bank’s server using the user's session cookie. Because the session is still active, the bank’s server trusts the request and processes it as if it were made by the user.
  6. Unintended Actions: As a result, the attacker can trick the user into performing unauthorized actions, such as transferring money to the attacker’s account, without the user’s knowledge or consent.

How Spring Security Protects Against CSRF

Spring Security helps mitigate CSRF attacks by requiring a unique CSRF token to be included with every state-changing request (such as POST, PUT, DELETE). This token is generated by the server and must be included in the request for it to be processed. If the token is missing or incorrect, the request will be rejected, ensuring that only legitimate actions are performed by authenticated users.

Configuration Example

In certain scenarios, such as when building a stateless REST API, you might want to disable CSRF protection.

SecurityConfiguration.java:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // Disable CSRF
            .authorizeRequests()
                .anyRequest().authenticated() 
                .and()
            .formLogin()
                .loginPage("/login") // Custom login page URL
                .permitAll() // Allow everyone to access it
                .and()
            .logout()
                .logoutUrl("/logout") // Custom logout URL
                .logoutSuccessUrl("/logout-success") // Redirect after logout
                .permitAll() // Allow everyone to access it
        return http.build();
    }
}
Enter fullscreen mode Exit fullscreen mode

Caution: Disabling CSRF protection should be done with caution and only when you're confident that your application doesn’t need this protection. For most web applications, CSRF protection is crucial to prevent unauthorized actions.


➼ Frame Options

The X-Frame-Options HTTP header controls whether a web page can be embedded in an iframe, frame, or object. This helps protect your application from clickjacking attacks, where an attacker tricks users into clicking on something different from what they perceive.

Default Configuration

By default, Spring Security includes the following HTTP header to prevent your content from being embedded in frames:

X-Frame-Options: DENY
Enter fullscreen mode Exit fullscreen mode

However, there are cases, such as when using the H2 database console, where you might need to adjust this setting.

Allowing Frames from Specific Origins

If you need to allow your pages to be framed by specific origins, you can configure it as follows:

Configuration Example:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfiguration {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated() 
                .and()
            .formLogin()
                .loginPage("/login") // Custom login page URL
                .permitAll() // Allow everyone to access it
                .and()
            .logout()
                .logoutUrl("/logout") // Custom logout URL
                .logoutSuccessUrl("/logout-success") // Redirect after logout
                .permitAll() // Allow everyone to access it
                .and()
            .headers()
                .frameOptions()
                .sameOrigin(); // Allow framing from the same domain
        return http.build();
    }
}
Enter fullscreen mode Exit fullscreen mode

Note: Whenever you override the SecurityFilterChain, you need to define the entire chain. This is essential for ensuring that all security filters are correctly configured.


In this post, we’ve explored the default security settings provided by Spring Security. We’ve covered built-in form authentication, Basic Authentication, CORS, CSRF protection, and frame options. Understanding these default settings is essential for securing your Spring Boot applications effectively.

Next Steps

Feel free to reach out with any questions or feedback!

Happy Coding! 😊

Top comments (0)