diff --git a/backend/src/main/java/com/alttd/altitudeweb/config/SecurityAuthFailureHandler.java b/backend/src/main/java/com/alttd/altitudeweb/config/SecurityAuthFailureHandler.java new file mode 100644 index 0000000..d9b5c66 --- /dev/null +++ b/backend/src/main/java/com/alttd/altitudeweb/config/SecurityAuthFailureHandler.java @@ -0,0 +1,36 @@ +package com.alttd.altitudeweb.config; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import java.io.IOException; + +@Slf4j +@Component +public class SecurityAuthFailureHandler implements AccessDeniedHandler, AuthenticationEntryPoint { + + @Override + public void handle(HttpServletRequest request, HttpServletResponse response, + AccessDeniedException accessDeniedException) throws IOException { + log.warn("Access denied: User '{}' attempted to access '{}' without proper permissions", + request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : "unknown", + request.getRequestURI()); + + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); + } + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + log.warn("Authentication failure: Unauthenticated user attempted to access secured endpoint '{}'", + request.getRequestURI()); + + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Required"); + } +} diff --git a/backend/src/main/java/com/alttd/altitudeweb/config/SecurityConfig.java b/backend/src/main/java/com/alttd/altitudeweb/config/SecurityConfig.java index d48f4e5..203f46e 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/config/SecurityConfig.java +++ b/backend/src/main/java/com/alttd/altitudeweb/config/SecurityConfig.java @@ -31,20 +31,34 @@ import java.security.interfaces.RSAPublicKey; public class SecurityConfig { private final KeyPairService keyPairService; + private final SecurityAuthFailureHandler securityAuthFailureHandler; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http - .authorizeHttpRequests(auth -> auth - .requestMatchers("/form/**").hasAuthority(PermissionClaimDto.USER.getValue()) - .requestMatchers("/head_mod/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) -// .requestMatchers("/particles/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) - .requestMatchers("/files/save/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) - .anyRequest().permitAll() - ) - .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())) - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - .build(); + .authorizeHttpRequests( + auth -> auth + .requestMatchers("/form/**").hasAuthority(PermissionClaimDto.USER.getValue()) + .requestMatchers("/head_mod/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) + .requestMatchers("/particles/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) + .requestMatchers("/files/save/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) + .anyRequest().permitAll() + ) + .oauth2ResourceServer( + oauth2 -> oauth2 + .jwt(Customizer.withDefaults()) + .authenticationEntryPoint(securityAuthFailureHandler) + .accessDeniedHandler(securityAuthFailureHandler) + ) + .exceptionHandling( + ex -> ex + .authenticationEntryPoint(securityAuthFailureHandler) + .accessDeniedHandler(securityAuthFailureHandler) + ) + .sessionManagement( + session -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .build(); } @Bean