From bece7075ae4b72d98d5d2ac54ca4bc8954e09d74 Mon Sep 17 00:00:00 2001 From: Ahoo Wang Date: Thu, 5 Jan 2023 23:58:32 +0800 Subject: [PATCH] Refactor: Enhance `SimpleAuthorization` Log (#55) --- .../authorization/SimpleAuthorization.kt | 22 ++++++++++++++++++- .../cosec/context/SimpleSecurityContext.kt | 4 ++++ .../authorization/SimpleAuthorizationTest.kt | 6 +++++ .../me/ahoo/cosec/webflux/ReactiveRequest.kt | 4 ++++ .../ahoo/cosec/servlet/CoSecServletRequest.kt | 4 ++++ gradle.properties | 2 +- 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/authorization/SimpleAuthorization.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/authorization/SimpleAuthorization.kt index 4077a0a1..1eaae72d 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/authorization/SimpleAuthorization.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/authorization/SimpleAuthorization.kt @@ -21,6 +21,7 @@ import me.ahoo.cosec.api.policy.Policy import me.ahoo.cosec.api.policy.Statement import me.ahoo.cosec.api.policy.VerifyResult import me.ahoo.cosec.api.principal.CoSecPrincipal.Companion.isRoot +import org.slf4j.LoggerFactory import reactor.core.publisher.Mono import reactor.kotlin.core.publisher.toMono @@ -30,6 +31,9 @@ import reactor.kotlin.core.publisher.toMono * @author ahoo wang */ class SimpleAuthorization(private val policyRepository: PolicyRepository) : Authorization { + companion object { + private val log = LoggerFactory.getLogger(SimpleAuthorization::class.java) + } private fun verifyPolicies(policies: Set, request: Request, context: SecurityContext): VerifyResult { policies.forEach { policy: Policy -> @@ -38,6 +42,9 @@ class SimpleAuthorization(private val policyRepository: PolicyRepository) : Auth }.forEach { statement: Statement -> val verifyResult = statement.verify(request, context) if (verifyResult == VerifyResult.EXPLICIT_DENY) { + if (log.isDebugEnabled) { + log.debug("Verify [$request] [$context] matched Policy[${policy.id}] - [Explicit Deny].") + } return VerifyResult.EXPLICIT_DENY } } @@ -49,6 +56,9 @@ class SimpleAuthorization(private val policyRepository: PolicyRepository) : Auth }.forEach { statement: Statement -> val verifyResult = statement.verify(request, context) if (verifyResult == VerifyResult.ALLOW) { + if (log.isDebugEnabled) { + log.debug("Verify [$request] [$context] matched Policy[${policy.id}] - [Allow].") + } return VerifyResult.ALLOW } } @@ -59,6 +69,9 @@ class SimpleAuthorization(private val policyRepository: PolicyRepository) : Auth private fun verifyRoot(context: SecurityContext): VerifyResult { return if (context.principal.isRoot()) { + if (log.isDebugEnabled) { + log.debug("Verify [$context] matched Root - [Allow].") + } VerifyResult.ALLOW } else { VerifyResult.IMPLICIT_DENY @@ -118,7 +131,14 @@ class SimpleAuthorization(private val policyRepository: PolicyRepository) : Auth when (roleVerifyResult) { VerifyResult.ALLOW -> AuthorizeResult.ALLOW VerifyResult.EXPLICIT_DENY -> AuthorizeResult.EXPLICIT_DENY - VerifyResult.IMPLICIT_DENY -> AuthorizeResult.IMPLICIT_DENY + VerifyResult.IMPLICIT_DENY -> { + if (log.isDebugEnabled) { + log.debug( + "Verify [$request] [$context] No policies matched - [Implicit Deny]." + ) + } + AuthorizeResult.IMPLICIT_DENY + } } } } diff --git a/cosec-core/src/main/kotlin/me/ahoo/cosec/context/SimpleSecurityContext.kt b/cosec-core/src/main/kotlin/me/ahoo/cosec/context/SimpleSecurityContext.kt index 0cb34f19..e7de2f98 100644 --- a/cosec-core/src/main/kotlin/me/ahoo/cosec/context/SimpleSecurityContext.kt +++ b/cosec-core/src/main/kotlin/me/ahoo/cosec/context/SimpleSecurityContext.kt @@ -47,6 +47,10 @@ class SimpleSecurityContext( @Suppress("UNCHECKED_CAST") return attributes[key] as T? } + + override fun toString(): String { + return "SimpleSecurityContext(principal.id=${principal.id}, tenantId=${tenant.tenantId})" + } } val CoSecPrincipal.tenant: Tenant diff --git a/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt b/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt index 33b704a3..e579d531 100644 --- a/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt +++ b/cosec-core/src/test/kotlin/me/ahoo/cosec/authorization/SimpleAuthorizationTest.kt @@ -64,6 +64,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalPolicyIsAllowAll() { val globalPolicy = mockk() { + every { id } returns "globalPolicy" every { statements } returns setOf( StatementData( effect = Effect.ALLOW, @@ -89,6 +90,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalPolicyIsDenyAll() { val globalPolicy = mockk() { + every { id } returns "globalPolicy" every { statements } returns setOf( StatementData( effect = Effect.DENY, @@ -113,6 +115,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalPolicyIsEmptyAndPrincipalIsAllowAll() { val principalPolicy = mockk() { + every { id } returns "policyId" every { statements } returns setOf( StatementData( effect = Effect.ALLOW, @@ -143,6 +146,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalPolicyIsEmptyAndPrincipalIsDenyAll() { val principalPolicy = mockk() { + every { id } returns "policyId" every { statements } returns setOf( StatementData( effect = Effect.DENY, @@ -173,6 +177,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalAndPrincipalPolicyIsEmptyAndRoleIsAllowAll() { val rolePolicy = mockk() { + every { id } returns "policyId" every { statements } returns setOf( StatementData( effect = Effect.ALLOW, @@ -204,6 +209,7 @@ internal class SimpleAuthorizationTest { @Test fun authorizeWhenGlobalAndPrincipalPolicyIsEmptyAndRoleIsDenyAll() { val rolePolicy = mockk() { + every { id } returns "policyId" every { statements } returns setOf( StatementData( effect = Effect.DENY, diff --git a/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveRequest.kt b/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveRequest.kt index 43f67758..98b836fd 100644 --- a/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveRequest.kt +++ b/cosec-webflux/src/main/kotlin/me/ahoo/cosec/webflux/ReactiveRequest.kt @@ -29,4 +29,8 @@ data class ReactiveRequest( override fun getHeader(key: String): String { return delegate.request.headers.getFirst(key).orEmpty() } + + override fun toString(): String { + return "ReactiveRequest(path='$path', method='$method', remoteIp='$remoteIp', origin='$origin', referer='$referer')" + } } diff --git a/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/CoSecServletRequest.kt b/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/CoSecServletRequest.kt index d049574f..3e93e982 100644 --- a/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/CoSecServletRequest.kt +++ b/cosec-webmvc/src/main/kotlin/me/ahoo/cosec/servlet/CoSecServletRequest.kt @@ -28,4 +28,8 @@ data class CoSecServletRequest( override fun getHeader(key: String): String { return delegate.getHeader(key).orEmpty() } + + override fun toString(): String { + return "CoSecServletRequest(path='$path', method='$method', remoteIp='$remoteIp', origin='$origin', referer='$referer')" + } } diff --git a/gradle.properties b/gradle.properties index acd735a4..4e447a5c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ # limitations under the License. # group=me.ahoo.cosec -version=1.8.7 +version=1.8.8 description=RBAC-based And Policy-based Multi-Tenant Reactive Security Framework website=https://github.com/Ahoo-Wang/CoSec issues=https://github.com/Ahoo-Wang/CoSec/issues