From b53726a63d6f5a9b14d1eff887dfc8f5f3a1f406 Mon Sep 17 00:00:00 2001 From: jreynard Date: Tue, 16 May 2023 10:34:30 +0200 Subject: [PATCH 1/2] Fix JwtAuthenticationToken cannot be cast to class BearerTokenAuthentication error --- .../com/cosmotech/api/utils/SecurityUtils.kt | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/cosmotech/api/utils/SecurityUtils.kt b/src/main/kotlin/com/cosmotech/api/utils/SecurityUtils.kt index 29d9ece7..7a9123a0 100644 --- a/src/main/kotlin/com/cosmotech/api/utils/SecurityUtils.kt +++ b/src/main/kotlin/com/cosmotech/api/utils/SecurityUtils.kt @@ -9,6 +9,7 @@ import com.nimbusds.jwt.JWTParser import org.springframework.security.core.Authentication import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken fun getCurrentAuthentication(): Authentication? = SecurityContextHolder.getContext().authentication @@ -23,8 +24,15 @@ fun getCurrentAuthenticatedIssuer(): String { throw IllegalStateException("User Authentication not found in Security Context") } - val authentication = getCurrentAuthentication() as BearerTokenAuthentication - return authentication.token.tokenValue.let { JWTParser.parse(it).jwtClaimsSet.issuer } + val authentication = getCurrentAuthentication() + + if (authentication is JwtAuthenticationToken) { + return authentication.token.tokenValue.let { JWTParser.parse(it).jwtClaimsSet.issuer } + } + + return (authentication as BearerTokenAuthentication).token.tokenValue.let { + JWTParser.parse(it).jwtClaimsSet.issuer + } } fun getCurrentAuthenticatedMail(configuration: CsmPlatformProperties): String { @@ -32,8 +40,15 @@ fun getCurrentAuthenticatedMail(configuration: CsmPlatformProperties): String { throw IllegalStateException("User Authentication not found in Security Context") } - val authentication = getCurrentAuthentication() as BearerTokenAuthentication - return authentication.token.tokenValue.let { + val authentication = getCurrentAuthentication() + + if (authentication is JwtAuthenticationToken) { + return authentication.token.tokenValue.let { + JWTParser.parse(it).jwtClaimsSet.getStringClaim(configuration.authorization.mailJwtClaim) + } + } + + return (authentication as BearerTokenAuthentication).token.tokenValue.let { JWTParser.parse(it).jwtClaimsSet.getStringClaim(configuration.authorization.mailJwtClaim) } } @@ -43,8 +58,15 @@ fun getCurrentAuthenticatedRoles(configuration: CsmPlatformProperties): List Date: Tue, 16 May 2023 11:49:44 +0200 Subject: [PATCH 2/2] Add csmPlatformProperties.identity.adminGroup in CsmAdmin.verifyRolesAdmin --- .../kotlin/com/cosmotech/api/rbac/CsmAdmin.kt | 6 +++- .../com/cosmotech/api/rbac/CsmRbacTests.kt | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/cosmotech/api/rbac/CsmAdmin.kt b/src/main/kotlin/com/cosmotech/api/rbac/CsmAdmin.kt index c4f09c4a..eed4ee32 100644 --- a/src/main/kotlin/com/cosmotech/api/rbac/CsmAdmin.kt +++ b/src/main/kotlin/com/cosmotech/api/rbac/CsmAdmin.kt @@ -15,7 +15,11 @@ class CsmAdmin(val csmPlatformProperties: CsmPlatformProperties) { fun verifyRolesAdmin(roles: List): Boolean { logger.debug("Verifying if token roles contains Platform Admin") - return roles.contains(ROLE_PLATFORM_ADMIN) + val customAdminGroup = csmPlatformProperties.identityProvider?.adminGroup + if (customAdminGroup.isNullOrBlank()) { + return roles.contains(ROLE_PLATFORM_ADMIN) + } + return roles.any { it == ROLE_PLATFORM_ADMIN || it == customAdminGroup } } fun verifyCurrentRolesAdmin(): Boolean { diff --git a/src/test/kotlin/com/cosmotech/api/rbac/CsmRbacTests.kt b/src/test/kotlin/com/cosmotech/api/rbac/CsmRbacTests.kt index c106b90a..e6eda66b 100644 --- a/src/test/kotlin/com/cosmotech/api/rbac/CsmRbacTests.kt +++ b/src/test/kotlin/com/cosmotech/api/rbac/CsmRbacTests.kt @@ -56,11 +56,15 @@ const val OWNER_ID = "3a869905-e9f5-4851-a7a9-3079aad49dfa" const val USER_ID = "2a869905-e9f5-4851-a7a9-3079aad49dfb" const val COMPONENT_ID = "component_id" +@Suppress("LargeClass") class CsmRbacTests { private val ROLE_NONE_PERMS: List = listOf() private val ROLE_READER_PERMS = listOf(PERM_READ) private val ROLE_WRITER_PERMS = listOf(PERM_READ, PERM_WRITE) private val ROLE_ADMIN_PERMS = listOf(PERM_ADMIN) + val CUSTOM_ADMIN_GROUP = "MyCustomAdminGroup" + val CUSTOM_USER_GROUP = "MyCustomUserGroup" + val CUSTOM_VIEWER_GROUP = "MyCustomViewerGroup" private val USER_READER_ROLE = ROLE_READER private val USER_WRITER_ROLE = ROLE_WRITER @@ -82,6 +86,15 @@ class CsmRbacTests { lateinit var parentRbacSecurity: RbacSecurity lateinit var rbacSecurity: RbacSecurity + private val DEFAULT_IDENTITY_PROVIDER = + CsmPlatformProperties.CsmIdentityProvider( + "identityProviderCode", + authorizationUrl = "http://my-fake-authorization.url/autorize", + tokenUrl = "http://my-fake-token.url/token", + adminGroup = CUSTOM_ADMIN_GROUP, + userGroup = CUSTOM_USER_GROUP, + viewerGroup = CUSTOM_VIEWER_GROUP) + @BeforeTest fun beforeEachTest() { logger.trace("Begin test") @@ -89,6 +102,7 @@ class CsmRbacTests { every { csmPlatformProperties.rbac.enabled } answers { true } every { csmPlatformProperties.authorization.rolesJwtClaim } answers { "roles" } every { csmPlatformProperties.authorization.mailJwtClaim } answers { "upn" } + every { csmPlatformProperties.identityProvider } answers { DEFAULT_IDENTITY_PROVIDER } rolesDefinition = RolesDefinition( adminRole = ROLE_ADMIN, @@ -161,6 +175,24 @@ class CsmRbacTests { assertTrue(admin.verifyRolesAdmin(userRoles)) } + @Test + fun `Custom role Platform Admin OK`() { + val userRoles = listOf(CUSTOM_ADMIN_GROUP) + assertTrue(admin.verifyRolesAdmin(userRoles)) + } + + @Test + fun `Custom role and regular Platform Admin OK`() { + val userRoles = listOf(CUSTOM_ADMIN_GROUP, ROLE_PLATFORM_ADMIN) + assertTrue(admin.verifyRolesAdmin(userRoles)) + } + + @Test + fun `Custom role Platform Admin NOK`() { + val userRoles = listOf(CUSTOM_USER_GROUP, CUSTOM_VIEWER_GROUP) + assertFalse(admin.verifyRolesAdmin(userRoles)) + } + @Test fun `roles with Platform Admin OK`() { val userRoles = listOf(ROLE_PLATFORM_ADMIN, ROLE_ORGANIZATION_USER)