From cf99ae6102d77e7c71b76eb99696df9d4bcfde3c Mon Sep 17 00:00:00 2001 From: Nariman Abdullin Date: Thu, 20 Jul 2023 16:00:16 +0300 Subject: [PATCH] reverted changes in ConvertingAuthenticationManager and CustomAuthenticationBasicConverter --- .../ConvertingAuthenticationManager.kt | 50 +++++++++++++------ .../CustomAuthenticationBasicConverter.kt | 39 ++++++--------- .../com/saveourtool/save/utils/Constants.kt | 5 -- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/ConvertingAuthenticationManager.kt b/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/ConvertingAuthenticationManager.kt index c0ebd21999..212d7fdc5b 100644 --- a/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/ConvertingAuthenticationManager.kt +++ b/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/ConvertingAuthenticationManager.kt @@ -1,6 +1,9 @@ package com.saveourtool.save.authservice.security +import com.saveourtool.save.authservice.service.AuthenticationUserDetailsService import com.saveourtool.save.authservice.utils.AuthenticationDetails +import com.saveourtool.save.authservice.utils.IdentitySourceAwareUserDetails +import com.saveourtool.save.authservice.utils.extractUserNameAndIdentitySource import com.saveourtool.save.authservice.utils.username import org.springframework.security.authentication.BadCredentialsException @@ -9,7 +12,8 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.Authentication import org.springframework.stereotype.Component import reactor.core.publisher.Mono -import reactor.kotlin.core.publisher.toMono +import reactor.kotlin.core.publisher.cast +import reactor.kotlin.core.publisher.switchIfEmpty /** * Implementation of `ReactiveAuthenticationManager` that doesn't check user credentials @@ -17,7 +21,9 @@ import reactor.kotlin.core.publisher.toMono * where user identity is already guaranteed. */ @Component -class ConvertingAuthenticationManager : ReactiveAuthenticationManager { +class ConvertingAuthenticationManager( + private val authenticationUserDetailsService: AuthenticationUserDetailsService +) : ReactiveAuthenticationManager { /** * Authenticate user, by checking the received data, which converted into UsernamePasswordAuthenticationToken * by [CustomAuthenticationBasicConverter] with record in DB @@ -26,20 +32,34 @@ class ConvertingAuthenticationManager : ReactiveAuthenticationManager { * @throws BadCredentialsException in case of bad credentials */ override fun authenticate(authentication: Authentication): Mono = if (authentication is UsernamePasswordAuthenticationToken) { - val username = authentication.username() - if (authentication.details != null && authentication.details is AuthenticationDetails) { - val authenticationDetails = authentication.details as AuthenticationDetails - UsernamePasswordAuthenticationToken( - "${authenticationDetails.identitySource}:$username", - authentication.credentials, - authentication.authorities, - ) - authentication.apply { details = authenticationDetails } - .toMono() - } else { - Mono.error { BadCredentialsException(authentication.username()) } - } + val (name, identitySource) = authentication.extractUserNameAndIdentitySource() + authenticationUserDetailsService.findByUsername(name) + .cast() + .filter { + it.identitySource == identitySource + } + .switchIfEmpty { + Mono.error { BadCredentialsException(name) } + } + .onErrorMap { + BadCredentialsException(name) + } + .map { + it.toAuthenticationWithDetails(authentication) + } } else { Mono.error { BadCredentialsException("Unsupported authentication type ${authentication::class}") } } + + private fun IdentitySourceAwareUserDetails.toAuthenticationWithDetails(authentication: Authentication) = + UsernamePasswordAuthenticationToken( + "$identitySource:$username", + authentication.credentials, + authorities + ).apply { + details = AuthenticationDetails( + id = id, + identitySource = identitySource, + ) + } } diff --git a/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/CustomAuthenticationBasicConverter.kt b/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/CustomAuthenticationBasicConverter.kt index 47df97ba06..e3c44594b1 100644 --- a/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/CustomAuthenticationBasicConverter.kt +++ b/authentication-service/src/main/kotlin/com/saveourtool/save/authservice/security/CustomAuthenticationBasicConverter.kt @@ -1,8 +1,6 @@ package com.saveourtool.save.authservice.security -import com.saveourtool.save.authservice.service.AuthenticationUserDetailsService import com.saveourtool.save.authservice.utils.AuthenticationDetails -import com.saveourtool.save.authservice.utils.IdentitySourceAwareUserDetails import com.saveourtool.save.utils.AUTHORIZATION_SOURCE import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.security.core.Authentication @@ -11,38 +9,29 @@ import org.springframework.security.web.server.authentication.ServerHttpBasicAut import org.springframework.stereotype.Component import org.springframework.web.server.ServerWebExchange import reactor.core.publisher.Mono -import reactor.kotlin.core.publisher.cast /** * Implementation of [ServerAuthenticationConverter] that embeds user identity source into [UsernamePasswordAuthenticationToken] */ @Component -class CustomAuthenticationBasicConverter( - private val authenticationUserDetailsService: AuthenticationUserDetailsService -) : ServerHttpBasicAuthenticationConverter(), ServerAuthenticationConverter { +class CustomAuthenticationBasicConverter : ServerHttpBasicAuthenticationConverter(), +ServerAuthenticationConverter { /** * Convert exchange, received from gateway into UsernamePasswordAuthenticationToken, specify source identity, laid * by gateway into X-Authorization-Source header */ @Suppress("TOO_MANY_LINES_IN_LAMBDA") - override fun convert(exchange: ServerWebExchange): Mono = super.convert(exchange) - .cast() - .flatMap { authentication -> - val username = authentication.principal as String - val source = exchange.request.headers[AUTHORIZATION_SOURCE]?.firstOrNull() - authenticationUserDetailsService.findByUsername(username) - .cast() - .map { userDetails -> - UsernamePasswordAuthenticationToken( - "$source:$username", - authentication.credentials, - userDetails.authorities - ).apply { - details = AuthenticationDetails( - id = userDetails.id, - identitySource = source, - ) - } - } + override fun convert(exchange: ServerWebExchange): Mono = super.convert(exchange).map { authentication -> + val name = (authentication as UsernamePasswordAuthenticationToken).principal as String + val source = exchange.request.headers[AUTHORIZATION_SOURCE]?.firstOrNull() + UsernamePasswordAuthenticationToken( + "$source:$name", + authentication.credentials as String + ).apply { + details = AuthenticationDetails( + id = -1L, + identitySource = source, + ) } + } } diff --git a/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/utils/Constants.kt b/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/utils/Constants.kt index cf0bfcd3e0..0f4d766227 100644 --- a/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/utils/Constants.kt +++ b/save-cloud-common/src/commonMain/kotlin/com/saveourtool/save/utils/Constants.kt @@ -64,8 +64,3 @@ const val AUTHORIZATION_SOURCE = "X-Authorization-Source" */ @Suppress("NON_EXPORTABLE_TYPE") const val DEFAULT_SETUP_SH_TIMEOUT_MILLIS: Long = 60_000L - -/** - * Separator for name and source of user - */ -const val AUTH_SEPARATOR = "@SAVE@"