Java - doFilter

解决问题:

1. 在认证之前做个过滤InternalServerTokenFilter。如没有带内部token, 就不继续认证controller的处理了
2. 过滤拿走request 的body后,controller不可再次消费,此时需要重新生成一个InternalServerTokenRequestWrapper, 可永久保存request body
3. 过滤器需要捕捉异常,进行特殊处理返回给前端 InternalServerTokenFilter::exceptionHandle

 
public class InternalServerTokenFilter extends GenericFilterBean {
	private static final Logger logger = LoggerFactory
			.getLogger(InternalServerTokenFilter.class);
	private InternalServerUiConf internalServerUiConf;
	private InternalTokenService internalTokenService;

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws ServletException, IOException {

		if (false == internalServerUiConf.getEnable()) {
			// Disable: do nothing
			chain.doFilter(request, response);
			return;
		}

		// Enable: validate it.
		// Consume input stream of request and wrap a new request for control
		// consumption.
		// Because input stream can be consumed only once.
		InternalServerTokenRequestWrapper requestWrapper = new InternalServerTokenRequestWrapper(
				(HttpServletRequest) request);
		String body = requestWrapper.getBody();
		try {
			internalTokenService.validate(body);
		} catch (InvalidInternalTokenException e) {
			exceptionHandle((HttpServletRequest) request,
					(HttpServletResponse) response, e);
			return;
		} catch (Exception e) {
			logger.error("internal token filter exception. ", e.getMessage());
			throw new ServletException(e);
		}

		// Pass through
		chain.doFilter((ServletRequest) requestWrapper, response);
	}

	private void exceptionHandle(HttpServletRequest request,
			HttpServletResponse response, InvalidInternalTokenException e)
			throws IOException {

		response.setStatus(HttpStatus.FORBIDDEN.value());

		InternalTokenResponse internalTokenResponse = new InternalTokenResponse(
				e.getCode(), e.getMessage());
		JSONObject objResponse = JSONObject.fromObject(internalTokenResponse);
		String strResponse = objResponse.toString();
		PrintWriter outBody = response.getWriter();
		outBody.println(strResponse);
		outBody.flush();
		outBody.close();
	}

	public InternalTokenService getInternalTokenService() {
		return internalTokenService;
	}
	public void setInternalTokenService(
			InternalTokenService internalTokenService) {
		this.internalTokenService = internalTokenService;
	}

	public InternalServerUiConf getInternalServerUiConf() {
		return internalServerUiConf;
	}

	public void setInternalServerUiConf(
			InternalServerUiConf internalServerUiConf) {
		this.internalServerUiConf = internalServerUiConf;
	}
}

package com.hp.ccue.identity.utilities;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class InternalServerTokenRequestWrapper
		extends
			HttpServletRequestWrapper {

	private final String body;
	public InternalServerTokenRequestWrapper(HttpServletRequest request)
			throws IOException {
		super(request);
		StringBuilder stringBuilder = new StringBuilder();
		BufferedReader bufferedReader = null;
		try {
			InputStream inputStream = request.getInputStream();
			if (inputStream != null) {
				bufferedReader = new BufferedReader(
						new InputStreamReader(inputStream));
				char[] charBuffer = new char[1024];
				int bytesRead = -1;
				while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
					stringBuilder.append(charBuffer, 0, bytesRead);
				}
			} else {
				stringBuilder.append("");
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					throw e;
				}
			}
		}
		body = stringBuilder.toString();
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
				body.getBytes());
		ServletInputStream servletInputStream = new ServletInputStream() {
			public int read() throws IOException {
				return byteArrayInputStream.read();
			}
		};
		return servletInputStream;
	}

	@Override
	public BufferedReader getReader() throws IOException {
		return new BufferedReader(new InputStreamReader(this.getInputStream()));
	}

	public String getBody() {
		return this.body;
	}
}


    <bean id="internalServerTokenFilter" class="com.hp.ccue.identity.filter.InternalServerTokenFilter">
        <property name="internalServerUiConf" ref="internalServerUiConf"/>
        <property name="internalTokenService" ref="internalTokenService"/>
    </bean>
   <security:http pattern="/../v0/.." use-expressions="true" auto-config="false">
        <security:csrf disabled="true" />
        <security:custom-filter ref="internalServerTokenFilter" />
        <security:http-basic />
    </security:http>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值