bval-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Romain Manni-Bucau (Jira)" <j...@apache.org>
Subject [jira] [Commented] (BVAL-174) Return Parameter Validation Ignore void methods
Date Mon, 09 Sep 2019 05:54:00 GMT

    [ https://issues.apache.org/jira/browse/BVAL-174?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16925382#comment-16925382
] 

Romain Manni-Bucau commented on BVAL-174:
-----------------------------------------

If ambiguous David, I agree there is space in microprofile-jwt-auth to have a built in interceptor
not javax.security based.
The API you propose is a good start too.
Now, in terms of impl, I dislike it would depend on bval in terms of stack + I fail to see
the benefit. Did you do the CDI based impl? It is quite trivial since jwt is injected.

For example for a jaxrs flavor, here is an impl:


{code}
@Provider
@Dependent
public class EnforceEndpointSecurity implements DynamicFeature {
    @Inject
    private JsonWebToken token;

    @Inject
    private AuditConfiguration configuration;

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
        final String className = resourceInfo.getResourceClass().getName();
        if (className.startsWith("org.microprofileext.openapi.swaggerui.")) { // no security
            return;
        }
        if (!className.startsWith("org.talend.")) {
            context.register(new CheckStaticTokenPresence(configuration::monitoringToken));
        } else if (!resourceInfo.getResourceMethod().isAnnotationPresent(EnableAnonymous.class))
{
            context.register(new CheckJwtPresence(token));
        }
    }

    private static class CheckPresence implements ContainerRequestFilter {
        private final Function<ContainerRequestContext, Boolean> check;

        private CheckPresence(final Function<ContainerRequestContext, Boolean> check)
{
            this.check = check;
        }

        @Override
        public void filter(final ContainerRequestContext requestContext) {
            try {
                if (!check.apply(requestContext)) {
                    unauthenticated(requestContext);
                }
            } catch (final RuntimeException re) {
                unauthenticated(requestContext);
            }
        }

        private void unauthenticated(final ContainerRequestContext requestContext) {
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED)
                    .entity(new ErrorMessage("Forbidden request"))
                    .build());
        }
    }

    private static class CheckJwtPresence extends CheckPresence {
        private CheckJwtPresence(final JsonWebToken token) {
            super(ignored -> token.getRawToken() != null);
        }
    }

    private static class CheckStaticTokenPresence extends CheckPresence {
        private CheckStaticTokenPresence(final Supplier<String> token) {
            super(context -> token.get().equals(context.getHeaderString(HttpHeaders.AUTHORIZATION)));
        }
    }
}
{code}

> Return Parameter Validation Ignore void methods
> -----------------------------------------------
>
>                 Key: BVAL-174
>                 URL: https://issues.apache.org/jira/browse/BVAL-174
>             Project: BVal
>          Issue Type: Improvement
>    Affects Versions: 2.0.0
>            Reporter: David Blevins
>            Priority: Major
>             Fix For: 2.0.3
>
>         Attachments: BVAL-174.patch
>
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> Given the following annotation:
> {code:java}
> import javax.validation.ConstraintValidator;
> import javax.validation.ConstraintValidatorContext;
> import javax.validation.Payload;
> import java.lang.annotation.Documented;
> import java.lang.annotation.Retention;
> import java.lang.annotation.Target;
> import java.util.Set;
> import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
> import static java.lang.annotation.ElementType.METHOD;
> import static java.lang.annotation.RetentionPolicy.RUNTIME;
> @Documented
> @javax.validation.Constraint(validatedBy = {Audience.Constraint.class})
> @Target({METHOD, ANNOTATION_TYPE})
> @Retention(RUNTIME)
> public @interface Audience {
>     String value();
>     Class<?>[] groups() default {};
>     String message() default "The 'aud' claim must contain '{value}'";
>     Class<? extends Payload>[] payload() default {};
>     class Constraint implements ConstraintValidator<Audience, JsonWebToken> {
>         private Audience audience;
>         @Override
>         public void initialize(final Audience constraint) {
>             this.audience = constraint;
>         }
>         @Override
>         public boolean isValid(final JsonWebToken value, final ConstraintValidatorContext
context) {
>             final Set<String> audience = value.getAudience();
>             return audience != null && audience.contains(this.audience.value());
>         }
>     }
> }
> {code}
> BVal wil successfully avoid throwing errors when placed on a method like the following:
> {code:java}
>     @GET
>     @Path("foo")
>     @Audience("movies")
>     @RolesAllowed({"manager", "user"})
>     public Movie getMovie() {
>         return new Movie(1, "The Matrix", "Lana Wachowski");
>     }
> {code}
> However on a method that returns void an exception will be throwing stating BVal cannot
find a ConstraintValidator for return type void.
> {code:java}
>     @POST
>     @Audience("movies")
>     @RolesAllowed("manager")
>     public void addMovie(Movie newMovie) {
>         store.put(newMovie.getId(), newMovie);
>     }
> {code}
> If the BValInterceptor is updated to ignore checking return values of void methods, it
appears to pass the Bean Validation TCK and solves the issue.



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Mime
View raw message