Skip to content

Commit

Permalink
feat:Oauth token刷新保留原token #2822
Browse files Browse the repository at this point in the history
  • Loading branch information
yaoxuwan committed Dec 5, 2024
1 parent e732b14 commit 3409d1b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.tencent.bkrepo.auth.pojo.oauth.JsonWebKey
import com.tencent.bkrepo.auth.pojo.oauth.JsonWebKeySet
import com.tencent.bkrepo.auth.pojo.oauth.OauthToken
import com.tencent.bkrepo.auth.dao.repository.OauthTokenRepository
import com.tencent.bkrepo.auth.pojo.enums.ResourceType
import com.tencent.bkrepo.auth.pojo.oauth.OidcConfiguration
import com.tencent.bkrepo.auth.pojo.oauth.UserInfo
import com.tencent.bkrepo.auth.service.OauthAuthorizationService
Expand Down Expand Up @@ -146,17 +147,16 @@ class OauthAuthorizationServiceImpl(
with(generateTokenRequest) {
Preconditions.checkNotNull(clientId, this::clientId.name)
Preconditions.checkNotNull(refreshToken, this::refreshToken.name)
val token = oauthTokenRepository.findFirstByAccountIdAndRefreshToken(clientId!!, refreshToken!!)
var token = oauthTokenRepository.findFirstByAccountIdAndRefreshToken(clientId!!, refreshToken!!)
?: throw ErrorCodeException(CommonMessageCode.RESOURCE_NOT_FOUND, refreshToken!!)
val idToken = generateOpenIdToken(
clientId = clientId!!,
val client = accountDao.findById(clientId!!)
?: throw ErrorCodeException(CommonMessageCode.RESOURCE_NOT_FOUND, clientId!!)
token = buildOauthToken(
userId = token.userId,
nonce = OauthUtils.generateRandomString(10)
nonce = OauthUtils.generateRandomString(10),
client = client,
openId = token.idToken != null
)
token.accessToken = idToken.toJwtToken()
token.issuedAt = Instant.now(Clock.systemDefaultZone())
token.idToken?.let { token.idToken = idToken }
oauthTokenRepository.save(token)
responseToken(transfer(token))
}
}
Expand Down Expand Up @@ -201,7 +201,7 @@ class OauthAuthorizationServiceImpl(
): TOauthToken {
val idToken = generateOpenIdToken(client.id!!, userId, nonce)
val tOauthToken = TOauthToken(
accessToken = idToken.toJwtToken(),
accessToken = idToken.toJwtToken(client.scope),
refreshToken = OauthUtils.generateRefreshToken(),
expireSeconds = oauthProperties.expiredDuration.seconds,
type = "Bearer",
Expand Down Expand Up @@ -300,7 +300,7 @@ class OauthAuthorizationServiceImpl(
accessToken = tOauthToken.accessToken,
tokenType = tOauthToken.type,
scope = if (tOauthToken.scope == null) "" else tOauthToken.scope!!.joinToString(StringPool.COMMA),
idToken = tOauthToken.idToken?.toJwtToken(),
idToken = tOauthToken.idToken?.toJwtToken(tOauthToken.scope),
refreshToken = tOauthToken.refreshToken,
expiresIn = if (tOauthToken.expireSeconds == null) {
null
Expand All @@ -310,12 +310,15 @@ class OauthAuthorizationServiceImpl(
}
)

private fun IdToken.toJwtToken(): String {
private fun IdToken.toJwtToken(scope: Set<ResourceType>?): String {
val claims = mutableMapOf<String, Any>()
claims["scope"] = scope.orEmpty()
claims.putAll(JsonUtils.objectMapper.convertValue(this, jacksonTypeRef()))
return JwtUtils.generateToken(
signingKey = RsaUtils.stringToPrivateKey(cryptoProperties.privateKeyStr2048PKCS8),
expireDuration = oauthProperties.expiredDuration,
subject = sub,
claims = JsonUtils.objectMapper.convertValue(this, jacksonTypeRef()),
claims = claims,
header = mapOf(KEY_ID_NAME to KEY_ID_VALUE),
algorithm = SignatureAlgorithm.RS256
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class HttpAuthSecurityConfiguration(
)
}
if (httpAuthSecurity.oauthEnabled) {
httpAuthSecurity.addHttpAuthHandler(OauthAuthHandler(authenticationManager))
httpAuthSecurity.addHttpAuthHandler(OauthAuthHandler(authenticationManager, cryptoProperties))
}
if (httpAuthSecurity.temporaryTokenEnabled) {
httpAuthSecurity.addHttpAuthHandler(TemporaryTokenAuthHandler(authenticationManager))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ package com.tencent.bkrepo.common.security.http.oauth
import com.tencent.bkrepo.common.api.constant.AUTHORITIES_KEY
import com.tencent.bkrepo.common.api.constant.HttpHeaders
import com.tencent.bkrepo.common.api.constant.OAUTH_AUTH_PREFIX
import com.tencent.bkrepo.common.security.crypto.CryptoProperties
import com.tencent.bkrepo.common.security.exception.AuthenticationException
import com.tencent.bkrepo.common.security.http.core.HttpAuthHandler
import com.tencent.bkrepo.common.security.http.credentials.AnonymousCredentials
import com.tencent.bkrepo.common.security.http.credentials.HttpAuthCredentials
import com.tencent.bkrepo.common.security.manager.AuthenticationManager
import com.tencent.bkrepo.common.security.util.JwtUtils
import com.tencent.bkrepo.common.security.util.RsaUtils
import org.slf4j.LoggerFactory
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

open class OauthAuthHandler(val authenticationManager: AuthenticationManager) : HttpAuthHandler {
open class OauthAuthHandler(
val authenticationManager: AuthenticationManager,
val cryptoProperties: CryptoProperties
) : HttpAuthHandler {
override fun extractAuthCredentials(request: HttpServletRequest): HttpAuthCredentials {
val authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION).orEmpty()
return if (authorizationHeader.startsWith(OAUTH_AUTH_PREFIX)) {
Expand All @@ -53,14 +59,24 @@ open class OauthAuthHandler(val authenticationManager: AuthenticationManager) :

override fun onAuthenticate(request: HttpServletRequest, authCredentials: HttpAuthCredentials): String {
require(authCredentials is OauthAuthCredentials)
return authenticationManager.checkOauthToken(authCredentials.token)
return try {
val claims = JwtUtils.validateToken(
signingKey = RsaUtils.stringToPrivateKey(cryptoProperties.privateKeyStr2048PKCS8),
token = authCredentials.token
)
val scopeList = claims.body["scope"] as? List<*>
val scope = scopeList?.joinToString(",")
?: authenticationManager.findOauthToken(authCredentials.token)?.scope
?: throw AuthenticationException("Invalid access token: $authCredentials.token")
request.setAttribute(AUTHORITIES_KEY, scope)
claims.body.subject
} catch (e: Exception) {
logger.info("invalid oauth token[${authCredentials.token}]: ${e.message}")
throw AuthenticationException("Invalid token")
}
}

override fun onAuthenticateSuccess(request: HttpServletRequest, response: HttpServletResponse, userId: String) {
val authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION).orEmpty()
val accessToken = authorizationHeader.removePrefix(OAUTH_AUTH_PREFIX).trim()
val oauthToken = authenticationManager.findOauthToken(accessToken)
?: throw AuthenticationException("Invalid access token")
request.setAttribute(AUTHORITIES_KEY, oauthToken.scope)
companion object {
private val logger = LoggerFactory.getLogger(OauthAuthHandler::class.java)
}
}

0 comments on commit 3409d1b

Please sign in to comment.