Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace deprecated methods and classes in Quarkus Security and tiny bit of refactoring #44306

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
package io.quarkus.security.deployment;

import static io.quarkus.security.deployment.SecurityProcessor.createMethodDescription;
import static io.quarkus.security.spi.SecurityTransformerUtils.DENY_ALL;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.jboss.jandex.AnnotationTarget;
import jakarta.annotation.security.DenyAll;

import org.jboss.jandex.AnnotationTransformation;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.security.spi.runtime.MethodDescription;

public class AdditionalDenyingUnannotatedTransformer implements AnnotationsTransformer {
final class AdditionalDenyingUnannotatedTransformer
implements Predicate<MethodInfo>, Consumer<AnnotationTransformation.TransformationContext> {

private final Set<MethodDescription> methods;

public AdditionalDenyingUnannotatedTransformer(Collection<MethodDescription> methods) {
this.methods = new HashSet<>(methods);
AdditionalDenyingUnannotatedTransformer(Collection<MethodDescription> methods) {
this.methods = Set.copyOf(methods);
}

@Override
public boolean appliesTo(AnnotationTarget.Kind kind) {
return kind == AnnotationTarget.Kind.METHOD;
public void accept(AnnotationTransformation.TransformationContext ctx) {
ctx.add(DenyAll.class);
}

@Override
public void transform(TransformationContext context) {
MethodDescription methodDescription = createMethodDescription(context.getTarget().asMethod());
if (methods.contains(methodDescription)) {
context.transform().add(DENY_ALL).done();
}
public boolean test(MethodInfo methodInfo) {
MethodDescription methodDescription = createMethodDescription(methodInfo);
return methods.contains(methodDescription);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,44 @@
import static io.quarkus.security.deployment.SecurityProcessor.createMethodDescription;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;

import jakarta.annotation.security.RolesAllowed;

import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTransformation;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.processor.AnnotationsTransformer;
import io.quarkus.security.spi.runtime.MethodDescription;

public class AdditionalRolesAllowedTransformer implements AnnotationsTransformer {
final class AdditionalRolesAllowedTransformer
implements Predicate<MethodInfo>, Consumer<AnnotationTransformation.TransformationContext> {

private static final DotName ROLES_ALLOWED = DotName.createSimple(RolesAllowed.class.getName());
private final Set<MethodDescription> methods;
private final AnnotationValue[] rolesAllowed;

public AdditionalRolesAllowedTransformer(Collection<MethodDescription> methods, List<String> rolesAllowed) {
this.methods = new HashSet<>(methods);
AdditionalRolesAllowedTransformer(Collection<MethodDescription> methods, List<String> rolesAllowed) {
this.methods = Set.copyOf(methods);
this.rolesAllowed = rolesAllowed.stream().map(s -> AnnotationValue.createStringValue("", s))
.toArray(AnnotationValue[]::new);
}

@Override
public boolean appliesTo(AnnotationTarget.Kind kind) {
return kind == AnnotationTarget.Kind.METHOD;
public boolean test(MethodInfo methodInfo) {
MethodDescription method = createMethodDescription(methodInfo);
return methods.contains(method);
}

@Override
public void transform(TransformationContext context) {
MethodDescription method = createMethodDescription(context.getTarget().asMethod());
if (methods.contains(method)) {
context.transform().add(ROLES_ALLOWED, AnnotationValue.createArrayValue("value", rolesAllowed)).done();
}
public void accept(AnnotationTransformation.TransformationContext ctx) {
AnnotationInstance rolesAllowedInstance = AnnotationInstance.create(ROLES_ALLOWED, ctx.declaration().asMethod(),
new AnnotationValue[] { AnnotationValue.createArrayValue("value", rolesAllowed) });
ctx.add(rolesAllowedInstance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.quarkus.security.deployment;

import java.util.List;
import java.util.function.Predicate;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.MethodInfo;

import io.quarkus.security.spi.SecurityTransformerUtils;

final class DenyUnannotatedPredicate implements Predicate<ClassInfo> {

@Override
public boolean test(ClassInfo classInfo) {
List<MethodInfo> methods = classInfo.methods();
return !SecurityTransformerUtils.hasSecurityAnnotation(classInfo)
&& methods.stream().anyMatch(SecurityTransformerUtils::hasSecurityAnnotation);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import jakarta.annotation.security.DenyAll;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Singleton;
Expand Down Expand Up @@ -90,8 +91,8 @@
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.execannotations.ExecutionModelAnnotationsAllowedBuildItem;
import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.gizmo.CatchBlockCreator;
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.ClassOutput;
Expand Down Expand Up @@ -313,16 +314,18 @@ void recordBouncyCastleProviders(SecurityProviderRecorder recorder,
}
}

@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
NativeImageFeatureBuildItem bouncyCastleFeature(
@BuildStep
NativeImageFeatureBuildItem bouncyCastleFeature(NativeConfig nativeConfig,
List<BouncyCastleProviderBuildItem> bouncyCastleProviders,
List<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProviders) {

Optional<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders);
Optional<BouncyCastleProviderBuildItem> bouncyCastleProvider = getOne(bouncyCastleProviders);
if (nativeConfig.enabled()) {
Optional<BouncyCastleJsseProviderBuildItem> bouncyCastleJsseProvider = getOne(bouncyCastleJsseProviders);
Optional<BouncyCastleProviderBuildItem> bouncyCastleProvider = getOne(bouncyCastleProviders);

if (bouncyCastleJsseProvider.isPresent() || bouncyCastleProvider.isPresent()) {
return new NativeImageFeatureBuildItem("io.quarkus.security.BouncyCastleFeature");
if (bouncyCastleJsseProvider.isPresent() || bouncyCastleProvider.isPresent()) {
return new NativeImageFeatureBuildItem("io.quarkus.security.BouncyCastleFeature");
}
}
return null;
}
Expand Down Expand Up @@ -549,7 +552,10 @@ void transformSecurityAnnotations(BuildProducer<AnnotationsTransformerBuildItem>
List<AdditionalSecuredMethodsBuildItem> additionalSecuredMethods,
SecurityBuildTimeConfig config) {
if (config.denyUnannotated()) {
transformers.produce(new AnnotationsTransformerBuildItem(new DenyingUnannotatedTransformer()));
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forClasses()
.whenClass(new DenyUnannotatedPredicate())
.transform(ctx -> ctx.add(DenyAll.class))));
}
if (!additionalSecuredMethods.isEmpty()) {
for (AdditionalSecuredMethodsBuildItem securedMethods : additionalSecuredMethods) {
Expand All @@ -558,13 +564,19 @@ void transformSecurityAnnotations(BuildProducer<AnnotationsTransformerBuildItem>
additionalSecured.add(createMethodDescription(additionalSecuredMethod));
}
if (securedMethods.rolesAllowed.isPresent()) {
transformers.produce(
new AnnotationsTransformerBuildItem(new AdditionalRolesAllowedTransformer(additionalSecured,
securedMethods.rolesAllowed.get())));
var additionalRolesAllowedTransformer = new AdditionalRolesAllowedTransformer(additionalSecured,
securedMethods.rolesAllowed.get());
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forMethods()
.whenMethod(additionalRolesAllowedTransformer)
.transform(additionalRolesAllowedTransformer)));
} else {
transformers.produce(
new AnnotationsTransformerBuildItem(
new AdditionalDenyingUnannotatedTransformer(additionalSecured)));
var additionalDenyingUnannotatedTransformer = new AdditionalDenyingUnannotatedTransformer(
additionalSecured);
transformers.produce(new AnnotationsTransformerBuildItem(AnnotationTransformation
.forMethods()
.whenMethod(additionalDenyingUnannotatedTransformer)
.transform(additionalDenyingUnannotatedTransformer)));
}
}
}
Expand Down Expand Up @@ -799,17 +811,12 @@ void createSecurityCheckStorage(BuildProducer<SyntheticBeanBuildItem> syntheticB
recorder.registerDefaultSecurityCheck(builder, recorder.rolesAllowed(roles.toArray(new String[0])));
}
}
recorder.create(builder);

syntheticBeans.produce(
SyntheticBeanBuildItem.configure(SecurityCheckStorage.class)
.scope(ApplicationScoped.class)
.unremovable()
.creator(creator -> {
ResultHandle ret = creator.invokeStaticMethod(MethodDescriptor.ofMethod(SecurityCheckRecorder.class,
"getStorage", SecurityCheckStorage.class));
creator.returnValue(ret);
}).done());
.runtimeProxy(recorder.create(builder))
.done());
}

@Consume(RuntimeConfigSetupCompleteBuildItem.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@

public class AnonymousIdentityProvider implements IdentityProvider<AnonymousAuthenticationRequest> {

private static final Principal principal = new Principal() {
private static final Principal PRINCIPAL = new Principal() {
@Override
public String getName() {
return "";
}
};

private static final SecurityIdentity instance = new SecurityIdentity() {
private static final SecurityIdentity INSTANCE = new SecurityIdentity() {
@Override
public Principal getPrincipal() {
return principal;
return PRINCIPAL;
}

@Override
Expand Down Expand Up @@ -77,6 +77,6 @@ public Class<AnonymousAuthenticationRequest> getRequestType() {
@Override
public Uni<SecurityIdentity> authenticate(AnonymousAuthenticationRequest request,
AuthenticationRequestContext context) {
return Uni.createFrom().item(instance);
return Uni.createFrom().item(INSTANCE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public Executor get() {
public IdentityProviderManager ipm() {
boolean customAnon = false;
QuarkusIdentityProviderManagerImpl.Builder builder = QuarkusIdentityProviderManagerImpl.builder();
for (IdentityProvider i : identityProviders) {
for (var i : identityProviders) {
builder.addProvider(i);
if (i.getRequestType() == AnonymousAuthenticationRequest.class) {
customAnon = true;
Expand Down
Loading
Loading