Add reasons to AuthorizationDecisions

Closes gh-9287
This commit is contained in:
Marcus Da Coregio 2021-10-05 10:06:08 -03:00 committed by Marcus Hert Da Coregio
parent 570092c467
commit ef01124eb9
8 changed files with 108 additions and 6 deletions

View File

@ -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<String> authorities;
AuthorityAuthorizationDecision(boolean granted, Collection<String> authorities) {
super(granted);
this.authorities = authorities;
}
Collection<String> getAuthorities() {
return this.authorities;
}
@Override
public String toString() {
return getClass().getSimpleName() + " [" + "granted=" + isGranted() + ", authorities=" + this.authorities + ']';
}
}

View File

@ -124,7 +124,7 @@ public final class AuthorityAuthorizationManager<T> implements AuthorizationMana
@Override @Override
public AuthorizationDecision check(Supplier<Authentication> authentication, T object) { public AuthorizationDecision check(Supplier<Authentication> authentication, T object) {
boolean granted = isGranted(authentication.get()); boolean granted = isGranted(authentication.get());
return new AuthorizationDecision(granted); return new AuthorityAuthorizationDecision(granted, this.authorities);
} }
private boolean isGranted(Authentication authentication) { private boolean isGranted(Authentication authentication) {

View File

@ -48,8 +48,8 @@ public class AuthorityReactiveAuthorizationManager<T> implements ReactiveAuthori
.flatMapIterable(Authentication::getAuthorities) .flatMapIterable(Authentication::getAuthorities)
.map(GrantedAuthority::getAuthority) .map(GrantedAuthority::getAuthority)
.any(this.authorities::contains) .any(this.authorities::contains)
.map(AuthorizationDecision::new) .map((granted) -> ((AuthorizationDecision) new AuthorityAuthorizationDecision(granted, this.authorities)))
.defaultIfEmpty(new AuthorizationDecision(false)); .defaultIfEmpty(new AuthorityAuthorizationDecision(false, this.authorities));
// @formatter:on // @formatter:on
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -32,4 +32,9 @@ public class AuthorizationDecision {
return this.granted; return this.granted;
} }
@Override
public String toString() {
return getClass().getSimpleName() + " [granted=" + this.granted + "]";
}
} }

View File

@ -49,4 +49,10 @@ class ExpressionAttribute {
return this.expression; return this.expression;
} }
@Override
public String toString() {
return getClass().getSimpleName() + " [Expression="
+ ((this.expression != null) ? this.expression.getExpressionString() : null) + "]";
}
} }

View File

@ -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 + ']';
}
}

View File

@ -76,7 +76,7 @@ public final class PostAuthorizeAuthorizationManager implements AuthorizationMan
mi.getMethodInvocation()); mi.getMethodInvocation());
this.expressionHandler.setReturnObject(mi.getResult(), ctx); this.expressionHandler.setReturnObject(mi.getResult(), ctx);
boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx); boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx);
return new AuthorizationDecision(granted); return new ExpressionAttributeAuthorizationDecision(granted, attribute);
} }
private final class PostAuthorizeExpressionAttributeRegistry private final class PostAuthorizeExpressionAttributeRegistry

View File

@ -74,7 +74,7 @@ public final class PreAuthorizeAuthorizationManager implements AuthorizationMana
} }
EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication.get(), mi); EvaluationContext ctx = this.expressionHandler.createEvaluationContext(authentication.get(), mi);
boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx); boolean granted = ExpressionUtils.evaluateAsBoolean(attribute.getExpression(), ctx);
return new AuthorizationDecision(granted); return new ExpressionAttributeAuthorizationDecision(granted, attribute);
} }
private final class PreAuthorizeExpressionAttributeRegistry private final class PreAuthorizeExpressionAttributeRegistry