-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
changed authentication from UserDetailsService to custom JwtClaims (#54)
* changed authentication from UserDetailsService to custom JwtClaims
- Loading branch information
Showing
30 changed files
with
448 additions
and
778 deletions.
There are no files selected for viewing
18 changes: 12 additions & 6 deletions
18
backend/src/main/kotlin/com/tul/backend/auth/base/config/JwtAuthenticationFilter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,32 @@ | ||
package com.tul.backend.auth.base.config | ||
|
||
import com.tul.backend.auth.base.service.TokenFilterService | ||
import com.tul.backend.auth.base.service.TokenFilter | ||
import jakarta.servlet.FilterChain | ||
import jakarta.servlet.http.HttpServletRequest | ||
import jakarta.servlet.http.HttpServletResponse | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken | ||
import org.springframework.security.core.context.SecurityContextHolder | ||
import org.springframework.stereotype.Component | ||
import org.springframework.web.filter.OncePerRequestFilter | ||
|
||
|
||
@Component | ||
class JwtAuthenticationFilter( | ||
private val tokenFilterService: TokenFilterService | ||
|
||
private val tokenFilter: TokenFilter | ||
) : OncePerRequestFilter() { | ||
|
||
override fun doFilterInternal( | ||
request: HttpServletRequest, | ||
response: HttpServletResponse, | ||
filterChain: FilterChain | ||
) { | ||
val userDetails = tokenFilterService.validateRequest(request, response) | ||
if (userDetails != null) { | ||
tokenFilterService.updateContext(userDetails, request, response) | ||
val validClaims = tokenFilter.validateRequest(request) | ||
|
||
if (validClaims != null) { | ||
val authToken = UsernamePasswordAuthenticationToken(validClaims, null, listOf(validClaims.authUserRole)) | ||
SecurityContextHolder.getContext().authentication = authToken | ||
} | ||
|
||
filterChain.doFilter(request, response) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
backend/src/main/kotlin/com/tul/backend/auth/base/dto/AccessTokenClaims.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.tul.backend.auth.base.dto | ||
|
||
import com.tul.backend.auth.base.valueobject.AuthUserRole | ||
import com.tul.backend.auth.base.valueobject.EmailAddress | ||
import com.tul.backend.auth.entity.AuthUser | ||
import org.springframework.security.core.AuthenticatedPrincipal | ||
|
||
data class AccessTokenClaims( | ||
val authUserId: Long, | ||
val authUserRole: AuthUserRole, | ||
val email: EmailAddress | ||
) : AuthenticatedPrincipal { | ||
|
||
constructor(authUser: AuthUser) : this( | ||
authUserId = authUser.id, | ||
authUserRole = authUser.role, | ||
email = authUser.email | ||
) | ||
|
||
override fun getName(): String = email.value | ||
} |
24 changes: 24 additions & 0 deletions
24
backend/src/main/kotlin/com/tul/backend/auth/base/dto/JwtClaims.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.tul.backend.auth.base.dto | ||
|
||
import java.util.Date | ||
import kotlin.time.Duration | ||
|
||
class JwtClaims( | ||
val claims: Map<String, *>, | ||
val issuedAt: Date, | ||
val expiration: Date | ||
) { | ||
|
||
companion object { | ||
fun from(claims: Map<String, *>, duration: Duration): JwtClaims { | ||
val now = Date() | ||
val expiration = Date(now.time + duration.inWholeSeconds) | ||
|
||
return JwtClaims( | ||
claims = claims, | ||
issuedAt = now, | ||
expiration = expiration | ||
) | ||
} | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
backend/src/main/kotlin/com/tul/backend/auth/base/service/AccessTokenService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.tul.backend.auth.base.service | ||
|
||
import com.fasterxml.jackson.core.type.TypeReference | ||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.tul.backend.auth.base.dto.AccessTokenClaims | ||
import com.tul.backend.auth.base.dto.JwtClaims | ||
import com.tul.backend.auth.entity.AuthUser | ||
import org.springframework.beans.factory.annotation.Value | ||
import org.springframework.http.ResponseCookie | ||
import org.springframework.stereotype.Service | ||
import kotlin.time.Duration.Companion.milliseconds | ||
|
||
@Service | ||
class AccessTokenService( | ||
private val objectMapper: ObjectMapper, | ||
@Value("\${spring.jwt.secure}") private val secure: Boolean, | ||
@Value("\${spring.jwt.sameSite}") private val sameSite: String, | ||
@Value("\${spring.jwt.duration}") private val duration: Long, | ||
@Value("\${spring.jwt.secret}") private val secret: String | ||
) { | ||
|
||
val COOKIE_NAME = "access_token" | ||
|
||
private val maxAge = duration.milliseconds | ||
|
||
private val jwtService = JwtService(secret) | ||
|
||
fun createCookie(accessTokenClaims: AccessTokenClaims): ResponseCookie { | ||
val claims = objectMapper.convertValue(accessTokenClaims, object : TypeReference<Map<String, *>>() {}) | ||
val jwtToken = jwtService.generateToken(JwtClaims.from(claims, maxAge)) | ||
return ResponseCookie.from(COOKIE_NAME, jwtToken) | ||
.httpOnly(true) | ||
.path("/") | ||
.secure(secure) | ||
.sameSite(sameSite) | ||
.maxAge(maxAge.inWholeSeconds) | ||
.build() | ||
} | ||
|
||
fun extractClaims(token: String): AccessTokenClaims? { | ||
return jwtService.extractToken(token)?.let { | ||
objectMapper.convertValue(it, object : TypeReference<AccessTokenClaims>() {}) | ||
} | ||
} | ||
|
||
fun createClaims(authUser: AuthUser): AccessTokenClaims { | ||
return AccessTokenClaims(authUser) | ||
} | ||
} |
29 changes: 0 additions & 29 deletions
29
backend/src/main/kotlin/com/tul/backend/auth/base/service/CustomUserDetailsService.kt
This file was deleted.
Oops, something went wrong.
39 changes: 39 additions & 0 deletions
39
backend/src/main/kotlin/com/tul/backend/auth/base/service/JwtService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.tul.backend.auth.base.service | ||
|
||
import com.tul.backend.auth.base.dto.JwtClaims | ||
import io.jsonwebtoken.Claims | ||
import io.jsonwebtoken.Jwts | ||
import io.jsonwebtoken.io.Decoders | ||
import io.jsonwebtoken.security.Keys | ||
|
||
class JwtService( | ||
secret: String | ||
) { | ||
|
||
private val secretKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret)) | ||
|
||
fun generateToken(claims: JwtClaims): String { | ||
return Jwts | ||
.builder() | ||
.claims() | ||
.add(claims.claims) | ||
.issuedAt(claims.issuedAt) | ||
.expiration(claims.expiration) | ||
.and() | ||
.signWith(secretKey) | ||
.compact() | ||
} | ||
|
||
fun extractToken(token: String): Claims? { | ||
return try { | ||
Jwts | ||
.parser() | ||
.verifyWith(secretKey) | ||
.build() | ||
.parseSignedClaims(token) | ||
.payload | ||
} catch (e: Exception) { | ||
null | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
backend/src/main/kotlin/com/tul/backend/auth/base/service/TokenFilter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.tul.backend.auth.base.service | ||
|
||
import com.tul.backend.auth.base.dto.AccessTokenClaims | ||
import jakarta.servlet.http.HttpServletRequest | ||
import org.springframework.stereotype.Component | ||
import org.springframework.web.util.WebUtils | ||
|
||
@Component | ||
class TokenFilter( | ||
private val accessTokenService: AccessTokenService | ||
) { | ||
|
||
fun validateRequest(request: HttpServletRequest): AccessTokenClaims? { | ||
val token = WebUtils.getCookie(request, accessTokenService.COOKIE_NAME) | ||
|
||
if (token != null) { | ||
return accessTokenService.extractClaims(token.value) | ||
} | ||
return null | ||
} | ||
} |
61 changes: 0 additions & 61 deletions
61
backend/src/main/kotlin/com/tul/backend/auth/base/service/TokenFilterService.kt
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.