From dfd2447a6de2d1f9e03950b7825b8e058ecf3fd1 Mon Sep 17 00:00:00 2001 From: Andreas Kaiberger Date: Mon, 27 Apr 2026 13:32:41 +0200 Subject: [PATCH 1/4] Update `SecurityConfig` to refine request authorization rules - Add role-based access control for `/admin/**`, `/handler/**`, and `/user/**` paths - Include `/favicon.ico` in permitted requests - Update exception handling to redirect to the home page on access denial --- .../untitled/config/SecurityConfig.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/example/untitled/config/SecurityConfig.java b/src/main/java/org/example/untitled/config/SecurityConfig.java index dcab62e..324cd7f 100644 --- a/src/main/java/org/example/untitled/config/SecurityConfig.java +++ b/src/main/java/org/example/untitled/config/SecurityConfig.java @@ -32,11 +32,15 @@ public SecurityConfig(UserDetailsService userDetailsService) { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests( - auth -> - auth.requestMatchers("/auth/**", "/", "/home", "/images/**", "/style.css", "/upload/**", "/login", "/register") - .permitAll() - .anyRequest() - .authenticated()) + auth -> auth + .requestMatchers("/auth/**", "/", "/home", "/images/**", "/style.css", + "/upload/**", "/login", "/register", "/favicon.ico") + .permitAll() + .requestMatchers("/admin/**").hasRole("ADMIN") + .requestMatchers("/handler/**").hasAnyRole("HANDLER", "SUPERVISOR", "ADMIN") + .requestMatchers("/user/**").hasRole("USER") + .anyRequest() + .authenticated()) .authenticationProvider(authenticationProvider()) .formLogin(form -> form .loginPage("/login") @@ -44,7 +48,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .permitAll()) .logout(logout -> logout .logoutSuccessUrl("/login") - .permitAll()); + .permitAll()) + .exceptionHandling(ex -> ex + .accessDeniedPage("/")); + return http.build(); } From addd4283ae65fd4459b51dff6fae0967bb8f2324 Mon Sep 17 00:00:00 2001 From: Andreas Kaiberger Date: Mon, 27 Apr 2026 13:43:07 +0200 Subject: [PATCH 2/4] Improve access denied handling in `SecurityConfig` and UI - Update `SecurityConfig` to redirect to `/access-denied` on access denial - Add `/access-denied` mapping in `HomeController` with HTTP 403 status - Create `access_denied.html` template for denied access page visual feedback --- .../org/example/untitled/HomeController.java | 8 ++++++++ .../untitled/config/SecurityConfig.java | 2 +- .../resources/templates/access_denied.html | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/templates/access_denied.html diff --git a/src/main/java/org/example/untitled/HomeController.java b/src/main/java/org/example/untitled/HomeController.java index 1960b17..a73fa1f 100644 --- a/src/main/java/org/example/untitled/HomeController.java +++ b/src/main/java/org/example/untitled/HomeController.java @@ -1,7 +1,9 @@ package org.example.untitled; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseStatus; @Controller public class HomeController { @@ -15,4 +17,10 @@ public String landingPage(){ public String home(){ return "index"; } + + @GetMapping("/access-denied") + @ResponseStatus(HttpStatus.FORBIDDEN) + public String accessDenied() { + return "access_denied"; + } } diff --git a/src/main/java/org/example/untitled/config/SecurityConfig.java b/src/main/java/org/example/untitled/config/SecurityConfig.java index 324cd7f..79eed2f 100644 --- a/src/main/java/org/example/untitled/config/SecurityConfig.java +++ b/src/main/java/org/example/untitled/config/SecurityConfig.java @@ -50,7 +50,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .logoutSuccessUrl("/login") .permitAll()) .exceptionHandling(ex -> ex - .accessDeniedPage("/")); + .accessDeniedPage("/access-denied")); return http.build(); diff --git a/src/main/resources/templates/access_denied.html b/src/main/resources/templates/access_denied.html new file mode 100644 index 0000000..a6d983c --- /dev/null +++ b/src/main/resources/templates/access_denied.html @@ -0,0 +1,19 @@ + + + + + Access Denied + + + +
+
+

Access Denied

+

You do not have permission to view this page.

+ +
+
+ + From ccb01fd572afbb19a14e53225d12a2e3a26317fc Mon Sep 17 00:00:00 2001 From: Andreas Kaiberger Date: Mon, 27 Apr 2026 14:33:51 +0200 Subject: [PATCH 3/4] Refactor CustomAuthenticationSuccessHandler to @Component and use constructor injection in SecurityConfig. --- .../org/example/untitled/config/SecurityConfig.java | 13 +++++-------- .../CustomAuthenticationSuccessHandler.java | 4 +++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/example/untitled/config/SecurityConfig.java b/src/main/java/org/example/untitled/config/SecurityConfig.java index fd3b841..16720a4 100644 --- a/src/main/java/org/example/untitled/config/SecurityConfig.java +++ b/src/main/java/org/example/untitled/config/SecurityConfig.java @@ -14,7 +14,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; @Configuration @EnableWebSecurity @@ -22,9 +21,12 @@ public class SecurityConfig { private final UserDetailsService userDetailsService; + private final CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; - public SecurityConfig(UserDetailsService userDetailsService) { + public SecurityConfig(UserDetailsService userDetailsService, + CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler) { this.userDetailsService = userDetailsService; + this.customAuthenticationSuccessHandler = customAuthenticationSuccessHandler; } @Bean @@ -42,7 +44,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authenticationProvider(authenticationProvider()) .formLogin(form -> form .loginPage("/login") - .successHandler(customAuthenticationSuccessHandler()) + .successHandler(customAuthenticationSuccessHandler) .permitAll()) .logout(logout -> logout .logoutSuccessUrl("/login") @@ -70,11 +72,6 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration c } } - @Bean - public AuthenticationSuccessHandler customAuthenticationSuccessHandler() { - return new CustomAuthenticationSuccessHandler(); - } - @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); diff --git a/src/main/java/org/example/untitled/security/CustomAuthenticationSuccessHandler.java b/src/main/java/org/example/untitled/security/CustomAuthenticationSuccessHandler.java index fc5c2dc..d44ae88 100644 --- a/src/main/java/org/example/untitled/security/CustomAuthenticationSuccessHandler.java +++ b/src/main/java/org/example/untitled/security/CustomAuthenticationSuccessHandler.java @@ -8,10 +8,12 @@ import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.SavedRequest; +import org.springframework.stereotype.Component; import java.io.IOException; import java.util.Optional; +@Component public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { private final HttpSessionRequestCache requestCache = new HttpSessionRequestCache(); @@ -40,4 +42,4 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo clearAuthenticationAttributes(request); getRedirectStrategy().sendRedirect(request, response, targetUrl); } -} \ No newline at end of file +} From 501faf820e403cb7aa318491de621ebec1537372 Mon Sep 17 00:00:00 2001 From: Andreas Kaiberger Date: Mon, 27 Apr 2026 14:44:53 +0200 Subject: [PATCH 4/4] Permit public access to the access-denied endpoint in SecurityConfig. --- src/main/java/org/example/untitled/config/SecurityConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/untitled/config/SecurityConfig.java b/src/main/java/org/example/untitled/config/SecurityConfig.java index 16720a4..19065f3 100644 --- a/src/main/java/org/example/untitled/config/SecurityConfig.java +++ b/src/main/java/org/example/untitled/config/SecurityConfig.java @@ -34,7 +34,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti http.authorizeHttpRequests( auth -> auth .requestMatchers("/auth/**", "/", "/home", "/images/**", "/style.css", - "/upload/**", "/login", "/register", "/favicon.ico") + "/upload/**", "/login", "/register", "/favicon.ico", "/access-denied") .permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") .requestMatchers("/handler/**").hasAnyRole("HANDLER", "SUPERVISOR", "ADMIN")