105 lines
4.6 KiB
Kotlin
105 lines
4.6 KiB
Kotlin
package com.auth.config
|
|
|
|
import org.springframework.context.annotation.Bean
|
|
import org.springframework.context.annotation.Configuration
|
|
import org.springframework.security.config.Customizer
|
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity
|
|
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.CsrfConfigurer
|
|
import org.springframework.security.config.annotation.web.configurers.SessionManagementConfigurer
|
|
import org.springframework.security.config.http.SessionCreationPolicy
|
|
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
|
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter
|
|
import org.springframework.security.web.SecurityFilterChain
|
|
|
|
@Configuration
|
|
@EnableWebSecurity
|
|
@EnableMethodSecurity(
|
|
prePostEnabled = true, // ← явно включаем
|
|
securedEnabled = true // ← опционально
|
|
)
|
|
class WebSecurityConfig () {
|
|
|
|
private val logger = org.slf4j.LoggerFactory.getLogger(WebSecurityConfig::class.java)
|
|
|
|
@Bean
|
|
@Throws(Exception::class)
|
|
fun filterChain(http: HttpSecurity): SecurityFilterChain? {
|
|
http.authorizeHttpRequests(Customizer { auth ->
|
|
|
|
auth.requestMatchers("/public/**", "/health", "/info").permitAll()
|
|
//auth.anyRequest().permitAll()
|
|
auth.anyRequest().authenticated()
|
|
|
|
})
|
|
.oauth2ResourceServer(Customizer { oauth2 ->
|
|
// oauth2!!.jwt(Customizer.withDefaults())
|
|
// добавляем конвертер для извлечения ролей
|
|
oauth2.jwt { jwt ->
|
|
jwt.jwtAuthenticationConverter(jwtAuthenticationConverter())
|
|
}
|
|
}) // проверка JWT токен
|
|
.sessionManagement(Customizer { session: SessionManagementConfigurer<HttpSecurity?>? ->
|
|
session!!.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
}) // без сессий
|
|
.csrf(Customizer { csrf: CsrfConfigurer<HttpSecurity?>? -> csrf!!.disable() }) // отключаем CSRF для API
|
|
|
|
return http.build()
|
|
}
|
|
|
|
private fun jwtAuthenticationConverter(): JwtAuthenticationConverter {
|
|
val converter = JwtAuthenticationConverter()
|
|
|
|
converter.setJwtGrantedAuthoritiesConverter { jwt ->
|
|
val roles = mutableSetOf<SimpleGrantedAuthority>()
|
|
|
|
// Извлекаем роли из resource_access.test_client.roles
|
|
val resourceAccess = jwt.claims["resource_access"] as? Map<*, *>
|
|
logger.info("Roles! "+resourceAccess)
|
|
val clientAccess = resourceAccess?.get("test_client") as? Map<*, *>
|
|
val clientRoles = clientAccess?.get("roles") as? List<*>
|
|
|
|
clientRoles?.forEach { role ->
|
|
roles.add(SimpleGrantedAuthority("ROLE_$role"))
|
|
}
|
|
|
|
// Альтернативно: можно также читать из realm_access.roles
|
|
val realmAccess = jwt.claims["realm_access"] as? Map<*, *>
|
|
val realmRoles = realmAccess?.get("roles") as? List<*>
|
|
|
|
realmRoles?.forEach { role ->
|
|
roles.add(SimpleGrantedAuthority("ROLE_$role"))
|
|
}
|
|
|
|
roles.toList()
|
|
}
|
|
|
|
return converter
|
|
}
|
|
|
|
|
|
// // Конвертер JWT Authentication (извлекает роли из токена)
|
|
// private fun jwtAuthenticationConverter(): JwtAuthenticationConverter {
|
|
// val converter = JwtAuthenticationConverter()
|
|
//
|
|
// // Извлекаем роли из поля resource_access.test_client.roles
|
|
// val authoritiesExtractor = JwtGrantedAuthoritiesConverter()
|
|
// authoritiesExtractor.setAuthoritiesClaimName("resource_access.test_client.roles") // где лежат роли
|
|
// authoritiesExtractor.setAuthorityPrefix("ROLE_") // добавляем префикс ROLE_
|
|
//
|
|
// converter.setJwtGrantedAuthoritiesConverter(authoritiesExtractor)
|
|
//
|
|
//// // Дополнительно: проверяем, что роли не пустые
|
|
//// converter.setJwtGrantedAuthoritiesConverter { jwt ->
|
|
//// val authorities = authoritiesExtractor.convert(jwt)
|
|
//// if (authorities.isEmpty()) {
|
|
//// throw IllegalArgumentException("User has no roles assigned in token")
|
|
//// }
|
|
//// authorities
|
|
//// }
|
|
//
|
|
// return converter
|
|
// }
|
|
|
|
} |