package com.alttd.altitudeweb.config; import com.alttd.altitudeweb.controllers.login.KeyPairService; import com.alttd.altitudeweb.model.PermissionClaimDto; import com.nimbusds.jose.jwk.JWK; import com.nimbusds.jose.jwk.JWKSet; import com.nimbusds.jose.jwk.RSAKey; import com.nimbusds.jose.jwk.source.ImmutableJWKSet; import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.jwt.JwtDecoder; import org.springframework.security.oauth2.jwt.JwtEncoder; import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; import org.springframework.security.oauth2.jwt.NimbusJwtEncoder; import org.springframework.security.web.SecurityFilterChain; import java.security.KeyPair; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; @Configuration @EnableWebSecurity @RequiredArgsConstructor 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(HttpMethod.OPTIONS, "/**").permitAll() .requestMatchers("/api/form/**").authenticated() .requestMatchers("/api/login/getUsername").authenticated() .requestMatchers("/api/mail/**").authenticated() .requestMatchers("/api/head_mod/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) .requestMatchers("/api/particles/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) .requestMatchers("/api/files/save/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) .requestMatchers("/api/history/admin/**").hasAuthority(PermissionClaimDto.HEAD_MOD.getValue()) .requestMatchers("/api/login/userLogin/**").permitAll() .anyRequest().permitAll() ) .csrf(AbstractHttpConfigurer::disable) .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 public JwtEncoder jwtEncoder() { KeyPair keyPair = keyPairService.getJwtSigningKeyPair(); JWK jwk = new RSAKey.Builder((RSAPublicKey) keyPair.getPublic()) .privateKey((RSAPrivateKey) keyPair.getPrivate()) .build(); JWKSource jwkSource = new ImmutableJWKSet<>(new JWKSet(jwk)); return new NimbusJwtEncoder(jwkSource); } @Bean public JwtDecoder jwtDecoder() { KeyPair keyPair = keyPairService.getJwtSigningKeyPair(); return NimbusJwtDecoder.withPublicKey((RSAPublicKey) keyPair.getPublic()).build(); } }