-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix HTTP permission checks used with @Tenant annotation
- Loading branch information
1 parent
9ace5ba
commit 81386fd
Showing
23 changed files
with
1,011 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
...ic/resteasy/runtime/src/main/java/io/quarkus/resteasy/runtime/JaxRsPermissionChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package io.quarkus.resteasy.runtime; | ||
|
||
import static io.quarkus.vertx.http.runtime.PolicyMappingConfig.AppliesTo.JAXRS; | ||
|
||
import java.util.Map; | ||
|
||
import jakarta.enterprise.context.ApplicationScoped; | ||
import jakarta.enterprise.inject.Instance; | ||
import jakarta.inject.Inject; | ||
|
||
import io.quarkus.security.ForbiddenException; | ||
import io.quarkus.security.UnauthorizedException; | ||
import io.quarkus.security.identity.CurrentIdentityAssociation; | ||
import io.quarkus.security.identity.SecurityIdentity; | ||
import io.quarkus.security.spi.runtime.AuthorizationFailureEvent; | ||
import io.quarkus.security.spi.runtime.AuthorizationSuccessEvent; | ||
import io.quarkus.security.spi.runtime.BlockingSecurityExecutor; | ||
import io.quarkus.security.spi.runtime.SecurityEventHelper; | ||
import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; | ||
import io.quarkus.vertx.http.runtime.HttpConfiguration; | ||
import io.quarkus.vertx.http.runtime.security.AbstractPathMatchingHttpSecurityPolicy; | ||
import io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy; | ||
import io.quarkus.vertx.http.runtime.security.HttpSecurityPolicy.DefaultAuthorizationRequestContext; | ||
import io.quarkus.vertx.http.runtime.security.QuarkusHttpUser; | ||
import io.vertx.ext.web.RoutingContext; | ||
|
||
/** | ||
* Checks HTTP permissions specific for Jakarta REST. | ||
* | ||
* @see io.quarkus.vertx.http.runtime.PolicyMappingConfig.AppliesTo#JAXRS | ||
*/ | ||
@ApplicationScoped | ||
public class JaxRsPermissionChecker { | ||
private final AbstractPathMatchingHttpSecurityPolicy jaxRsPathMatchingPolicy; | ||
private final HttpSecurityPolicy.AuthorizationRequestContext authorizationRequestContext; | ||
|
||
@Inject | ||
RoutingContext routingContext; | ||
|
||
@Inject | ||
CurrentIdentityAssociation identityAssociation; | ||
|
||
JaxRsPermissionChecker(HttpConfiguration httpConfig, Instance<HttpSecurityPolicy> installedPolicies, | ||
HttpBuildTimeConfig httpBuildTimeConfig, BlockingSecurityExecutor blockingSecurityExecutor) { | ||
var jaxRsPathMatchingPolicy = new AbstractPathMatchingHttpSecurityPolicy(httpConfig.auth.permissions, | ||
httpConfig.auth.rolePolicy, httpBuildTimeConfig.rootPath, installedPolicies, JAXRS); | ||
if (jaxRsPathMatchingPolicy.hasNoPermissions()) { | ||
this.jaxRsPathMatchingPolicy = null; | ||
this.authorizationRequestContext = null; | ||
} else { | ||
this.jaxRsPathMatchingPolicy = jaxRsPathMatchingPolicy; | ||
this.authorizationRequestContext = new DefaultAuthorizationRequestContext(blockingSecurityExecutor); | ||
} | ||
} | ||
|
||
boolean shouldRunPermissionChecks() { | ||
return jaxRsPathMatchingPolicy != null; | ||
} | ||
|
||
void applyPermissionChecks(SecurityEventHelper<AuthorizationSuccessEvent, AuthorizationFailureEvent> eventHelper) { | ||
HttpSecurityPolicy.CheckResult checkResult = jaxRsPathMatchingPolicy | ||
.checkPermission(routingContext, identityAssociation.getDeferredIdentity(), authorizationRequestContext) | ||
.await().indefinitely(); | ||
final SecurityIdentity newIdentity; | ||
if (checkResult.getAugmentedIdentity() == null) { | ||
if (checkResult.isPermitted()) { | ||
// do not require authentication when permission checks didn't require it | ||
newIdentity = null; | ||
} else { | ||
newIdentity = identityAssociation.getIdentity(); | ||
} | ||
} else if (checkResult.getAugmentedIdentity() != identityAssociation.getIdentity()) { | ||
newIdentity = checkResult.getAugmentedIdentity(); | ||
routingContext.setUser(new QuarkusHttpUser(newIdentity)); | ||
identityAssociation.setIdentity(newIdentity); | ||
} else { | ||
newIdentity = checkResult.getAugmentedIdentity(); | ||
} | ||
|
||
if (checkResult.isPermitted()) { | ||
if (eventHelper.fireEventOnSuccess()) { | ||
eventHelper.fireSuccessEvent(new AuthorizationSuccessEvent(newIdentity, | ||
AbstractPathMatchingHttpSecurityPolicy.class.getName(), | ||
Map.of(RoutingContext.class.getName(), routingContext))); | ||
} | ||
return; | ||
} | ||
|
||
// access denied | ||
final RuntimeException exception; | ||
if (newIdentity.isAnonymous()) { | ||
exception = new UnauthorizedException(); | ||
} else { | ||
exception = new ForbiddenException(); | ||
} | ||
if (eventHelper.fireEventOnFailure()) { | ||
eventHelper.fireFailureEvent(new AuthorizationFailureEvent(newIdentity, exception, | ||
AbstractPathMatchingHttpSecurityPolicy.class.getName(), | ||
Map.of(RoutingContext.class.getName(), routingContext))); | ||
} | ||
throw exception; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.