簡體   English   中英

澤西島2-ContainerRequestFilter獲取方法注釋

[英]Jersey 2 - ContainerRequestFilter get method annotation

我試圖在ContainerRequestFilter對象中獲取方法注釋。

的Controler:

@GET
@RolesAllowed("ADMIN")
public String message() {
    return "Hello, rest12!";
}

ContainerRequestFilter:

@Provider
public class SecurityInterceptor implements  javax.ws.rs.container.ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) {
//Here I need To get the @RolesAllowed("ADMIN") annotation value
}

應用范圍:

@ApplicationPath("/rest")
public class ExpertApp extends Application {
private final HashSet<Object> singletons = new LinkedHashSet<Object>();

public ExpertApp() {
    singletons.add(new SecurityInterceptor());
}   

@Override
public Set<Object> getSingletons() {
    return singletons;
}

public Set<Class<?>> getClasses() {
    return new HashSet<Class<?>>(Arrays.asList(UserControler.class, SearchController.class));

}

}

在web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<!-- Servlet declaration can be omitted in which case it would be automatically 
    added by Jersey -->
<servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>

<servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

如何設置@RolesAllowed(“ ADMIN”)值,

你可以 ...

注入到過濾器@Context ResourceInfo ,因為看到這里 ,並從一開始的注釋Method

RolesAllowed annot = resourceInfo.getResourceMethod().getAnnotation(RolesAllowed.class);

但是 ...

澤西島已經有一個RolesAllowedDynamicFeature ,它實現了對@RolesAllowed@PermitAll@DenyAll批注的訪問控制。 您只需要在應用程序中注冊功能

ResourceConfig

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        super(MyResource.class);
        register(RolesAllowedDynamicFeature.class);
    }
}

web.xml

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature
    </param-value>
</init-param>

或者在您的Application子類中,可以將其添加到getSingletons()getClasses()集。 哪一個沒有多大區別。 沒有注入發生,因此將其實例化並將其添加到單例中將是安全的。

注意:第一個選項可以在任何JAX-RS 2.0應用程序中完成,而第二個特定於Jersey。

您的ContainerRequestFilter被實現為匹配后過濾器。 這意味着僅在選擇了合適的資源方法以處理實際請求之后(即在發生請求匹配之后),才應用過濾器。

因此,@ RolesAllowed(“ ADMIN”)將阻止調用,並且永遠不會調用您的過濾器。

為了避免該問題,我創建了自定義批注; 例如:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyRoles {
    public enum MyRole {
        USER, OFFICER, COMPLIANCE, ADMIN
    }

    MyRole role() default MyRole.USER;

    Class<? extends Throwable> expected() default None.class;

    static class None extends Throwable {

        /**
             * 
             */
        private static final long serialVersionUID = 1L;
    }
}

在我的Web服務中,我可以注釋該方法:

@POST
@MyRoles
@Path("/secured")
@Produces("application/json")
@Consumes("application/json")
public String mySecuredMethod() {
    // This method is annotated with @MyRoles
    // The authentication filter will be executed before invoking this
    // method
    return "{message='secured'}";
}

然后在過濾器中,檢查自定義注釋:

private static final String AUTHORIZATION_PROPERTY = "Authorization";
private static final String AUTHENTICATION_SCHEME = "Basic";
private static final ServerResponse BAD_REQUEST = new ServerResponse("Token invalid or expired", 400, new Headers<Object>());;
private static final ServerResponse ACCESS_DENIED = new ServerResponse("Access denied for this resource", 401, new Headers<Object>());;
private static final ServerResponse ACCESS_FORBIDDEN = new ServerResponse("Nobody can access this resource", 403, new Headers<Object>());;
private static final ServerResponse SERVER_ERROR = new ServerResponse("INTERNAL SERVER ERROR", 500, new Headers<Object>());;

@Override
public void filter(ContainerRequestContext requestContext) {
    System.err.println("GFA Debug SecurityInterceptor ............ ");
    System.err.println(requestContext.getUriInfo().getRequestUri());

    Method method = resourceInfo.getResourceMethod();
    System.out.println("GFA DEbug method.getName() " + method.getName());

    System.out.println("GFA DEbug method.isAnnotationPresent(PermitAll.class) = " + method.isAnnotationPresent(PermitAll.class));

    // Access denied for all
    if (method.isAnnotationPresent(DenyAll.class)) {
        requestContext.abortWith(ACCESS_FORBIDDEN);
        return;
    }

    // Access allowed for all
    if (method.isAnnotationPresent(PermitAll.class)) {
        System.out.println("GFA debug permitAll ... bye");
        return;
    }

    // Custom roles
    System.out.println("GFA Debug method.isAnnotationPresent(MyRole.class) = " + method.isAnnotationPresent(MyRoles.class));
    if (!method.isAnnotationPresent(MyRoles.class)) {
        requestContext.abortWith(ACCESS_FORBIDDEN);
        return;
    }

    MyRoles myannotation = method.getAnnotation(MyRoles.class);
    System.out.println("GFA custom role ... " + myannotation.role());

    // Then I check for token and validity of role, etc.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM