今天寫一個簡單的攔截器,以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和項目調用的類型;