我试图在ContainerRequestFilter对象中获取Method注释。
的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”)值
答案 0 :(得分:2)
注入过滤器@Context ResourceInfo
,如here所示,并从Method
RolesAllowed annot = resourceInfo.getResourceMethod().getAnnotation(RolesAllowed.class);
Jersey已经有一个RolesAllowedDynamicFeature
,可以对注释@RolesAllowed
,@PermitAll
和@DenyAll
实施访问控制。您只需要register the feature with your application
在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。
答案 1 :(得分:0)
您的ContainerRequestFilter实现为匹配后过滤器。这意味着只有在选择了合适的资源方法来处理实际请求之后,即在请求匹配发生之后,才会应用过滤器。
所以,@ RolesAllowed(&#34; ADMIN&#34;)将阻止调用,永远不会调用你的过滤器。
为了避免这个问题,我创建了自定义注释;例如:
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;
}
}
在我的网络服务中,我可以注释方法:
@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.
}