今天写一个简单的拦截器,以webService接口为例:
背景:H5的一个项目,只要调用H5webService 接口下面的方法都会触发一个AuthorityInterceptor去验证是否调用类型是H5,session是否失效.
1.需要自己定义一个Interceptor,我定义的Interceptor去验证调用类型moduleType和session:
package com.lcc.h5.ws; import com.lcc.api.dto.session.SessionInfo; import com.lcc.api.exception.AccessDeniedException; import com.lcc.api.web.common.ModuleType; import com.lcc.logger.Logger; import com.lcc.logger.LoggerFactory; import com.lcc.service.BaseAuthorityService; import org.apache.commons.lang3.StringUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.transport.http.AbstractHTTPDestination; import javax.servlet.http.HttpServletRequest; public class AuthorityInterceptor extends AbstractPhaseInterceptor<Message> { private static final Logger LOGGER = LoggerFactory.getLogger(AuthorityInterceptor.class); private BaseAuthorityService authorityService; public AuthorityInterceptor(String phase) { super(phase); } public AuthorityInterceptor() { this("post-stream"); } @Override public void handleMessage(Message message) throws Fault { Fault fault = new Fault(new AccessDeniedException("illeagl moduleType access")); fault.setStatusCode(421); HttpServletRequest httpRequest = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST); String sessionId = httpRequest.getHeader("Token"); if (StringUtils.isBlank(sessionId)) { LOGGER.info("blank session"); throw fault; } LOGGER.info("session authority, session id {}", sessionId); String moduleKey = httpRequest.getHeader("moduleType"); if (StringUtils.isEmpty(moduleKey)) { LOGGER.info("moduleType is empty"); throw fault; } ModuleType module = ModuleType.fromKey(moduleKey); SessionInfo sessionInfo = null; if (ModuleType.H5.equals(module)) { sessionInfo = authorityService.getSessionInfo(sessionId); if (sessionInfo == null) { throw fault; } } else { throw fault; } } public void setAuthorityService(BaseAuthorityService authorityService) { this.authorityService = authorityService; } }
上面Interceptor用到的java bean:
public abstract class SessionInfo implements Serializable { private static final long serialVersionUID = 6544973626519192604L; private String key; // timestamp private Long createdAt; // unit: second private Long expiryTime; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Long getCreatedAt() { return createdAt; } public void setCreatedAt(Long createdAt) { this.createdAt = createdAt; } public Long getExpiryTime() { return expiryTime; } public void setExpiryTime(Long expiryTime) { this.expiryTime = expiryTime; } @Override public String toString() { return new StringBuilder().append("{key: ").append(key).append(", createdAt: ").append(createdAt) .append(", expiryTime: ").append(expiryTime).append("}").toString(); } }
=====================
为了防止别人恶意访问接口,我们可以给调用类型加密,内部调用直接传入加密后的String,在后台去转换验证即可.
public enum ModuleType { H5("md5加密码"); private String key; ModuleType(String key) { this.key = key; } public String getKey() { return key; } }
BaseAuthorityService及其实现类 请参考http://www.cnblogs.com/cc-java/p/6625998.html
2.Interceptor写好了,接下来就看下怎么在xml配置文件里面为webService配置Interceptor
<bean id="authorityInterceptor" class="com.lcc.ws.AuthorityInterceptor" > <property name="authorityService" ref="authorityService" /> </bean> <bean id="authorityService" class="com.lcc.authority.AuthorityService" > <property name="sessionTemplate" ref="redisSessionSerializationTemplate" /> </bean> <bean id="h5WebService" class="com.lcc.ws.impl.H5WebService"> </bean> <jaxrs:server id="h5WebServiceContainer" address="/h5"> <jaxrs:serviceBeans> <ref bean="h5WebService" /> </jaxrs:serviceBeans> <jaxrs:providers> <ref bean="wadlGenerator" /> <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"> <constructor-arg ref="handshakeJacksonMapper" /> </bean> </jaxrs:providers> <jaxrs:inInterceptors> <ref bean="fileSizeInterceptor" /> <ref bean="authorityInterceptor" /> </jaxrs:inInterceptors> <jaxrs:outInterceptors> <ref bean="outInterceptor" /> </jaxrs:outInterceptors> </jaxrs:server>
到这里就已经为h5WebService接口配置好AuthorityInterceptor拦截器了;只要访问这个接口都会先进入拦截器里面去验证session和项目调用的类型;