Master Spring Security: From Basic Auth to Custom Login Pages

This article walks through Spring Security fundamentals, covering authentication mechanisms, authorization configuration, dependency setup, custom user details with database integration, and how to replace the default login page with a custom one, all illustrated with code snippets and screenshots.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Security: From Basic Auth to Custom Login Pages

1. Introduction

Spring Security is a framework that provides authentication, authorization, and protection against common attacks for both servlet‑based and reactive applications. It is the de‑facto standard for securing Spring applications.

1.1 Authentication

Authentication verifies the identity of a user, typically via username and password. Spring Security supports many authentication mechanisms, including:

Username & password

OAuth2 (OpenID Connect) login

SAML 2.0 login

CAS

Remember‑me after session expiration

JAAS

OpenID (not OpenID Connect)

External mechanisms such as SiteMinder or Java EE security

X.509 certificates

In practice we most often use “username & password” and OAuth2, so this article focuses on the former.

1.2 Authorization

Regardless of the authentication method, Spring Security offers a consistent and simple way to apply authorization rules in your application.

2. Practical Example

2.1 Dependency Management

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Adding this dependency causes all requests to be intercepted by default and a random password is printed at startup; the default user is “user”.

Default login page
Default login page

2.2 Custom User Configuration

Define username and password in application.yml:

spring:
  security:
    user:
      name: pack
      password: 123456

After this configuration the console no longer prints a random password.

2.3 Custom Authorization Rules

To protect only specific endpoints and allow static resources, configure a SecurityFilterChain bean:

@Bean
public SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
  http.csrf(csrf -> csrf.disable());
  http.authorizeHttpRequests().antMatchers("/api/**").authenticated();
  http.authorizeHttpRequests().antMatchers("*.js","*.css","*.html").permitAll();
  http.formLogin(withDefaults());
  return http.build();
}

Roles can be required for particular patterns:

http.authorizeHttpRequests().antMatchers("/api/**").hasAnyRole("MGR");
http.authorizeHttpRequests().antMatchers("/admin/**").hasAnyRole("SUPER");

Roles are defined in the configuration file:

spring:
  security:
    user:
      roles:
        - SUPER
Access denied page
Access denied page

2.4 Database‑Backed User Details

When users are stored in a database, add Spring Data JPA dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Define a JPA entity implementing UserDetails and a UserDetailsService bean that loads users from the repository:

@Entity
@Table(name = "p_user")
public class User implements UserDetails {
  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String username;
  private String password;
  private String email;
  private String address;
  private Integer age;
  // authorities, getters, and other UserDetails methods omitted for brevity
}
@Bean
UserDetailsService packUserDetailsService(UserRepository repo) {
  return username -> repo.findByUsername(username);
}
@Bean
PasswordEncoder packPasswordEncoder() {
  return NoOpPasswordEncoder.getInstance(); // not for production
}
public interface UserRepository extends JpaRepository<User, Long> {
  @Query(value = "select * from p_user u where u.username = ?1 limit 1", nativeQuery = true)
  User findByUsername(String username);
}

2.5 Custom Login Page

Replace the default login page by adding an HTML file (e.g., /login.html) and configuring the filter chain:

http.formLogin(login -> login.loginPage("/login.html").loginProcessingUrl("/login"));
Custom login page
Custom login page

That concludes the complete walkthrough.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring BootAuthenticationAuthorizationspring-security
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.