Skip to the content.

🧠 Lesson 2: Securing a Legacy Jakarta EE Web App with Spring Security Authorization (Spring 5.3.x)

🚨 Builds on: Lesson 1 β€” Authenticating Users in a Legacy Spring Web Application


🎯 Lesson Objectives

By the end of this lesson, participants will:

βœ… Replace custom authentication filters with Spring Security’s standard form login

βœ… Enable URL and method-level authorization using Java config and annotations

βœ… Apply Spring Security tags to JSP views

βœ… Understand how Spring Security makes authorization decisions

βœ… Configure ACLs for fine-grained access (optional advanced section)


πŸ§‘β€πŸ’» Assumptions

The application currently uses:

We will replace these with Spring Security equivalents.


🧭 1. Introduction (15 minutes)

🧩 Bridge from Lesson 1:

βœ… Key Shifts:

Before (Lesson 1) Now (Lesson 2)
AuthenticationFilter springSecurityFilterChain bean
Session-managed UserAdminPrincipal Spring Security Authentication object
Manual login controller Spring Security form login flow

πŸ” 2. Spring Security Authentication Flow (20 minutes)

πŸ”§ Configuration: SecurityConfig.java

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/login", "/resources/**").permitAll()
            .antMatchers("/registration/**", "/chat/**", "/session/**").authenticated()
            .anyRequest().authenticated()
        .and()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/registration/list", true)
            .failureUrl("/login?error")
        .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout")
        .and()
        .csrf()
        .and()
        .sessionManagement().maximumSessions(1);

    return http.build();
}

🧠 Notes:


🧱 3. URL-Based Authorization Rules (20 minutes)

Goal:

Replace hardcoded role checks and servlet filter protection with declarative config.

Exercise:

Modify SecurityConfig to restrict:

http
    .authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .antMatchers("/registration/**").hasRole("USER")
        .anyRequest().authenticated();

🏷 4. Securing Business Logic with Annotations (35 minutes)

Enable Method Security:

@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)

Sample Service:

@PreAuthorize("hasRole('ADMIN')")
public void deleteRegistration(Long id) { ... }

@PreAuthorize("hasRole('USER') and #userId == authentication.name")
public void updateProfile(String userId, ...) { ... }

Exercise:


🧩 5. JSP View Security with <sec:authorize> (20 minutes)

Taglib Use:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<sec:authorize access="hasRole('ADMIN')">
    <a href="/admin/panel">Admin Panel</a>
</sec:authorize>

Exercise:

<form action="${pageContext.request.contextPath}/logout" method="post">
  <input type="submit" value="Logout"/>
</form>

🧠 6. Authorization Decision Flow (25 minutes)

Concepts:

Optional Exercise:

Implement BusinessHoursVoter to restrict /chat access outside 9–5.


πŸ—‚ 7. (Advanced) ACLs and Object-Level Security (Optional – 30 minutes)

Concepts:

Exercise:

@PreAuthorize("hasPermission(#registration, 'WRITE')")

βœ… 8. Wrap-Up and Q\&A (15 minutes)

Recap:

Feature Legacy (Lesson 1) Spring Security (Lesson 2)
Login Filter AuthenticationFilter formLogin()
Session Management Manual Spring-managed
Logout Manual controller .logout()
Authorization Manual if checks Annotations, expressions
View Security N/A <sec:authorize>

πŸ“¦ Instructor Notes


πŸ“˜ Bonus Reading / Follow-Up