From ef01124eb94f069b69c5df325c8daa3937ab296e Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Tue, 5 Oct 2021 10:06:08 -0300 Subject: [PATCH] Add reasons to AuthorizationDecisions Closes gh-9287 --- .../AuthorityAuthorizationDecision.java | 45 ++++++++++++++++++ .../AuthorityAuthorizationManager.java | 2 +- ...AuthorityReactiveAuthorizationManager.java | 4 +- .../authorization/AuthorizationDecision.java | 7 ++- .../method/ExpressionAttribute.java | 6 +++ ...ressionAttributeAuthorizationDecision.java | 46 +++++++++++++++++++ .../PostAuthorizeAuthorizationManager.java | 2 +- .../PreAuthorizeAuthorizationManager.java | 2 +- 8 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationDecision.java create mode 100644 core/src/main/java/org/springframework/security/authorization/method/ExpressionAttributeAuthorizationDecision.java diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationDecision.java b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationDecision.java new file mode 100644 index 0000000000..68f4303355 --- /dev/null +++ b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationDecision.java @@ -0,0 +1,45 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.authorization; + +import java.util.Collection; + +/** + * Represents an {@link AuthorizationDecision} based on a collection of authorities + * + * @author Marcus Da Coregio + * @since 5.6 + */ +class AuthorityAuthorizationDecision extends AuthorizationDecision { + + private final Collection authorities; + + AuthorityAuthorizationDecision(boolean granted, Collection authorities) { + super(granted); + this.authorities = authorities; + } + + Collection getAuthorities() { + return this.authorities; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [" + "granted=" + isGranted() + ", authorities=" + this.authorities + ']'; + } + +} diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java index 7d245aed6e..03d3d65e3f 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java @@ -124,7 +124,7 @@ public final class AuthorityAuthorizationManager implements AuthorizationMana @Override public AuthorizationDecision check(Supplier authentication, T object) { boolean granted = isGranted(authentication.get()); - return new AuthorizationDecision(granted); + return new AuthorityAuthorizationDecision(granted, this.authorities); } private boolean isGranted(Authentication authentication) { diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorityReactiveAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/AuthorityReactiveAuthorizationManager.java index 9a8940ff0a..27171923c3 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorityReactiveAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorityReactiveAuthorizationManager.java @@ -48,8 +48,8 @@ public class AuthorityReactiveAuthorizationManager implements ReactiveAuthori .flatMapIterable(Authentication::getAuthorities) .map(GrantedAuthority::getAuthority) .any(this.authorities::contains) - .map(AuthorizationDecision::new) - .defaultIfEmpty(new AuthorizationDecision(false)); + .map((granted) -> ((AuthorizationDecision) new AuthorityAuthorizationDecision(granted, this.authorities))) + .defaultIfEmpty(new AuthorityAuthorizationDecision(false, this.authorities)); // @formatter:on } diff --git a/core/src/main/java/org/springframework/security/authorization/AuthorizationDecision.java b/core/src/main/java/org/springframework/security/authorization/AuthorizationDecision.java index 026d5afdbc..7c9bdb79b2 100644 --- a/core/src/main/java/org/springframework/security/authorization/AuthorizationDecision.java +++ b/core/src/main/java/org/springframework/security/authorization/AuthorizationDecision.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,4 +32,9 @@ public class AuthorizationDecision { return this.granted; } + @Override + public String toString() { + return getClass().getSimpleName() + " [granted=" + this.granted + "]"; + } + } diff --git a/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttribute.java b/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttribute.java index 80e49360e9..e6cd6aa93f 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttribute.java +++ b/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttribute.java @@ -49,4 +49,10 @@ class ExpressionAttribute { return this.expression; } + @Override + public String toString() { + return getClass().getSimpleName() + " [Expression=" + + ((this.expression != null) ? this.expression.getExpressionString() : null) + "]"; + } + } diff --git a/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttributeAuthorizationDecision.java b/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttributeAuthorizationDecision.java new file mode 100644 index 0000000000..c958777fdb --- /dev/null +++ b/core/src/main/java/org/springframework/security/authorization/method/ExpressionAttributeAuthorizationDecision.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.authorization.method; + +import org.springframework.security.authorization.AuthorizationDecision; + +/** + * Represents an {@link AuthorizationDecision} based on a {@link ExpressionAttribute} + * + * @author Marcus Da Coregio + * @since 5.6 + */ +class ExpressionAttributeAuthorizationDecision extends AuthorizationDecision { + + private final ExpressionAttribute expressionAttribute; + + ExpressionAttributeAuthorizationDecision(boolean granted, ExpressionAttribute expressionAttribute) { + super(granted); + this.expressionAttribute = expressionAttribute; + } + + ExpressionAttribute getExpressionAttribute() { + return this.expressionAttribute; + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [" + "granted=" + isGranted() + ", expressionAttribute=" + + this.expressionAttribute + ']'; + } + +} diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java index 6988647631..7d594e3705 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManager.java @@ -76,7 +76,7 @@ public final class PostAuthorizeAuthorizationManager implements AuthorizationMan mi.getMethodInvocation()); this.expressionHandler.setReturnObject(mi.getResult(), ctx); boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx); - return new AuthorizationDecision(granted); + return new ExpressionAttributeAuthorizationDecision(granted, attribute); } private final class PostAuthorizeExpressionAttributeRegistry diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java index c7f0f9523d..b3d844cc75 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManager.java @@ -74,7 +74,7 @@ public final class PreAuthorizeAuthorizationManager implements AuthorizationMana } EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication.get(), mi); boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx); - return new AuthorizationDecision(granted); + return new ExpressionAttributeAuthorizationDecision(granted, attribute); } private final class PreAuthorizeExpressionAttributeRegistry