feature/#30-group-authentication #31
|
@ -88,7 +88,7 @@ abstract class BaseSecurityConfig(
|
|||
.and()
|
||||
.csrf().disable()
|
||||
.addFilterBefore(
|
||||
GroupTokenAuthenticationFilter(jwtLogic, securityProperties, authManager),
|
||||
GroupTokenAuthenticationFilter(jwtLogic, securityProperties, groupTokenLogic, authManager),
|
||||
BasicAuthenticationFilter::class.java
|
||||
)
|
||||
.addFilterBefore(
|
||||
|
|
|
@ -4,27 +4,24 @@ import dev.fyloz.colorrecipesexplorer.Constants
|
|||
import dev.fyloz.colorrecipesexplorer.config.properties.CreSecurityProperties
|
||||
import dev.fyloz.colorrecipesexplorer.config.security.GroupAuthenticationToken
|
||||
import dev.fyloz.colorrecipesexplorer.dtos.account.UserDetails
|
||||
import dev.fyloz.colorrecipesexplorer.logic.account.GroupTokenLogic
|
||||
import dev.fyloz.colorrecipesexplorer.logic.account.JwtLogic
|
||||
import dev.fyloz.colorrecipesexplorer.utils.parseBearer
|
||||
import org.springframework.security.authentication.AuthenticationManager
|
||||
import org.springframework.security.authentication.BadCredentialsException
|
||||
import org.springframework.security.core.Authentication
|
||||
import org.springframework.web.util.WebUtils
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
class GroupTokenAuthenticationFilter(
|
||||
jwtLogic: JwtLogic,
|
||||
securityProperties: CreSecurityProperties,
|
||||
private val groupTokenLogic: GroupTokenLogic,
|
||||
private val authManager: AuthenticationManager
|
||||
) : JwtAuthenticationFilter(Constants.ControllerPaths.GROUP_LOGIN, securityProperties, jwtLogic) {
|
||||
override fun attemptAuthentication(request: HttpServletRequest, response: HttpServletResponse): Authentication {
|
||||
val groupTokenCookie = getGroupTokenCookie(request)
|
||||
val groupTokenId = groupTokenLogic.getIdForRequest(request)
|
||||
?: throw BadCredentialsException("Required group token cookie was not present")
|
||||
|
||||
val jwt = parseBearer(groupTokenCookie.value)
|
||||
val groupTokenId = jwtLogic.parseGroupTokenIdJwt(jwt)
|
||||
|
||||
logger.debug("Login attempt for group token $groupTokenId")
|
||||
return authManager.authenticate(GroupAuthenticationToken(groupTokenId))
|
||||
}
|
||||
|
@ -32,7 +29,4 @@ class GroupTokenAuthenticationFilter(
|
|||
override fun afterSuccessfulAuthentication(userDetails: UserDetails) {
|
||||
logger.info("Successful login for group id '${userDetails.group!!.id}' using token '${userDetails.id}' (${userDetails.username})")
|
||||
}
|
||||
|
||||
private fun getGroupTokenCookie(request: HttpServletRequest) =
|
||||
WebUtils.getCookie(request, Constants.CookieNames.GROUP_TOKEN)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,18 @@ import dev.fyloz.colorrecipesexplorer.exception.AlreadyExistsException
|
|||
import dev.fyloz.colorrecipesexplorer.exception.NotFoundException
|
||||
import dev.fyloz.colorrecipesexplorer.logic.BaseLogic
|
||||
import dev.fyloz.colorrecipesexplorer.service.account.GroupTokenService
|
||||
import dev.fyloz.colorrecipesexplorer.utils.parseBearer
|
||||
import org.springframework.web.util.WebUtils
|
||||
import java.util.*
|
||||
import javax.annotation.PostConstruct
|
||||
import kotlin.collections.HashSet
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
|
||||
interface GroupTokenLogic {
|
||||
fun isDisabled(id: String): Boolean
|
||||
fun getAll(): Collection<GroupTokenDto>
|
||||
fun getById(id: String): GroupTokenDto
|
||||
fun getById(id: UUID): GroupTokenDto
|
||||
fun getIdForRequest(request: HttpServletRequest): UUID?
|
||||
fun save(dto: GroupTokenSaveDto): GroupTokenDto
|
||||
fun enable(id: String): GroupTokenDto
|
||||
fun disable(id: String): GroupTokenDto
|
||||
|
@ -27,6 +30,7 @@ interface GroupTokenLogic {
|
|||
class DefaultGroupTokenLogic(
|
||||
private val service: GroupTokenService,
|
||||
private val groupLogic: GroupLogic,
|
||||
private val jwtLogic: JwtLogic,
|
||||
private val enabledTokensCache: HashSet<String> = hashSetOf() // In constructor for unit testing
|
||||
) :
|
||||
GroupTokenLogic {
|
||||
|
@ -42,9 +46,16 @@ class DefaultGroupTokenLogic(
|
|||
override fun isDisabled(id: String) = !enabledTokensCache.contains(id)
|
||||
override fun getAll() = service.getAll()
|
||||
override fun getById(id: String) = getById(UUID.fromString(id))
|
||||
|
||||
override fun getById(id: UUID) = service.getById(id) ?: throw notFoundException(value = id)
|
||||
|
||||
override fun getIdForRequest(request: HttpServletRequest): UUID? {
|
||||
val groupTokenCookie = getGroupTokenCookie(request)
|
||||
?: return null
|
||||
|
||||
val jwt = parseBearer(groupTokenCookie.value)
|
||||
return jwtLogic.parseGroupTokenIdJwt(jwt)
|
||||
}
|
||||
|
||||
override fun save(dto: GroupTokenSaveDto): GroupTokenDto {
|
||||
throwIfNameAlreadyExists(dto.name)
|
||||
|
||||
|
@ -89,6 +100,9 @@ class DefaultGroupTokenLogic(
|
|||
}
|
||||
}
|
||||
|
||||
private fun getGroupTokenCookie(request: HttpServletRequest) =
|
||||
WebUtils.getCookie(request, Constants.CookieNames.GROUP_TOKEN)
|
||||
|
||||
private fun notFoundException(identifierName: String = BaseLogic.ID_IDENTIFIER_NAME, value: Any) =
|
||||
NotFoundException(
|
||||
typeNameLowerCase,
|
||||
|
|
|
@ -11,7 +11,9 @@ import dev.fyloz.colorrecipesexplorer.rest.noContent
|
|||
import dev.fyloz.colorrecipesexplorer.rest.ok
|
||||
import dev.fyloz.colorrecipesexplorer.utils.addCookie
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import javax.servlet.http.HttpServletRequest
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
import javax.validation.Valid
|
||||
|
||||
|
@ -25,6 +27,12 @@ class GroupTokenController(
|
|||
@GetMapping
|
||||
fun getAll() = ok(groupTokenLogic.getAll())
|
||||
|
||||
@GetMapping("current")
|
||||
fun getCurrent(request: HttpServletRequest): ResponseEntity<GroupTokenDto?> {
|
||||
val id = groupTokenLogic.getIdForRequest(request) ?: return ok(null)
|
||||
return ok(groupTokenLogic.getById(id))
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
fun getById(@PathVariable id: String) = ok(groupTokenLogic.getById(id))
|
||||
|
||||
|
|
Loading…
Reference in New Issue