Implement enhanced login functionality with JWT, role-based permissions, and frontend integration

Added JWT-based login dialog with form validation and secure token handling on the frontend. Updated backend with role-based access control, privilege management, and refined security configurations. Extended database schema for user privileges and permissions.
This commit is contained in:
2025-05-30 23:41:13 +02:00
parent 20dcebbab9
commit 07646e8c42
26 changed files with 572 additions and 59 deletions
@@ -0,0 +1,16 @@
package com.alttd.altitudeweb.config;
public enum PermissionClaim {
USER("SCOPE_user"),
HEAD_MOD("SCOPE_head_mod");
private String claim;
PermissionClaim(String claim) {
this.claim = claim;
}
public String getClaim() {
return this.claim;
}
}
@@ -0,0 +1,65 @@
package com.alttd.altitudeweb.config;
import com.alttd.altitudeweb.controllers.login.KeyPairService;
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.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;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/login/userLogin/**", "/login/requestNewUserLogin/**").permitAll()
.requestMatchers("/team/**", "/history/**").permitAll()
.requestMatchers("/form/**").hasAuthority(PermissionClaim.USER.getClaim())
.requestMatchers("/head_mod/**").hasAuthority(PermissionClaim.HEAD_MOD.getClaim())
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.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<SecurityContext> 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();
}
}