feature/#30-group-authentication #31

Merged
william merged 10 commits from feature/#30-group-authentication into develop 2022-08-03 08:04:11 -04:00
4 changed files with 29 additions and 13 deletions
Showing only changes of commit 6b2d7dfa03 - Show all commits

View File

@ -88,7 +88,7 @@ abstract class BaseSecurityConfig(
.and()
.csrf().disable()
.addFilterBefore(
GroupTokenAuthenticationFilter(jwtLogic, securityProperties, authManager),
GroupTokenAuthenticationFilter(jwtLogic, securityProperties, groupTokenLogic, authManager),
BasicAuthenticationFilter::class.java
)
.addFilterBefore(

View File

@ -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)
}
}

View File

@ -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,

View File

@ -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))