最近,我开始使用SecurityEntityFilteringFeature.放置在球衣环境下的代码下方.
environment.jersey().register(SecurityEntityFilteringFeature.class);
environment.jersey().register(JacksonFeature.class);
我所有返回自定义对象或映射的资源类,都开始抛出以下异常
com.fasterxml.jackson.databind.JsonMappingException: Can not resolve PropertyFilter with id 'uk.co.froot.demo.openid.resources.PublicOAuthResource$1'; no FilterProvider configured
at com.fasterxml.jackson.databind.ser.std.StdSerializer.findPropertyFilter(StdSerializer.java:285)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:459)
at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:29)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:851)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.writeTo(ProviderBase.java:648)
at org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider.writeTo(FilteringJacksonJaxbJsonProvider.java:135)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:664)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:421)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:411)
解决方法:
由于没有解决方案适合我,因此我必须创建自己的过滤器.
Java安全注释的用法.根据我的自定义要求,我必须为请求中的用户设置角色.并用于过滤器
package com.buzzy.jersey.provider;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.annotation.security.DenyAll;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import org.apache.commons.lang3.ClassUtils;
import uk.co.froot.demo.openid.model.security.Authority;
/**
* @author Sanjay Patel (sanjaypatel at ibm.com)
*/
@Provider
public class FilterResponseFilter implements ContainerResponseFilter {
@Context
private ResourceInfo resourceInfo;
@Context
private HttpServletRequest request;
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
if(responseContext.getEntity()!=null)
filterObject(((Authority)request.getAttribute("hasAuthority")),responseContext.getEntity());
}
private void filterObject(Authority auth, Object entity) {
if(entity instanceof List) {
for(Object obj: (List)entity)filterObject(auth,obj);
}
else if(entity instanceof Map) {
for(Object obj : ((Map)entity).values()) filterObject(auth,obj);
}
else if(entity instanceof Object[]){
for(Object obj: (Object[])entity)filterObject(auth,obj);
}
else if(!ClassUtils.isPrimitiveOrWrapper(entity.getClass()) && !(entity instanceof String)){
try{
for(Method method:entity.getClass().getMethods()){
if(method.getName().startsWith("get") && !method.getName().equals("getClass")){
String fieldName = method.getName().substring(3);
fieldName=fieldName.substring(0, 1).toLowerCase()+fieldName.substring(1, fieldName.length());
Field field = entity.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
if(method.getAnnotation(DenyAll.class)!=null ){
field.set(entity, null);
}
if(method.getAnnotation(RolesAllowed.class)!=null){
if(auth!=null && Arrays.asList(method.getAnnotation(RolesAllowed.class).value()).contains(auth.name())){
if(!ClassUtils.isPrimitiveOrWrapper(method.getReturnType()) && !(entity instanceof String)){
filterObject(auth, field.get(entity));
}
}
else{
field.set(entity, null);
}
}
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
并将其注册为dropwizard / jersey.
environment.jersey().register(FilterResponseFilter.class);