移动端接口加密

   最近公司写的android接口需要加密,防止被恶意攻击。

 

2加密规则想了个简单的办法,传两个参数,一个是string类型的另一种是MD5加密的密文,在服务端写个拦截器/或者过滤器去拦截他,然后做自己相应的逻辑处理,把string类型的字段拿过来加上其他一些东西,用MD5加密和传过来的密文做相应的比较。

3 下面就是重点了,最开始的时候我想到的使用拦截器对url进行拦截,然后做处理,但是我们的服务端不只是对android提供服务接口,还有一些内部的请求,可有时我们的接口是rest风格的,使用resteasy写的,他的请求方式和springmvc又不太一样,

  @Component
  @Path("services")
  @Produces({ "application/json"})
  @Consumes({ "application/json" })

这种风格的,但是spring的请求是这种风格的

    @Controller

  @RequestMapping(value = "/../..")

拦截器配置

 <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/services/**"/>
            <bean class="*.MyInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
但是这样配置com.zk.interceptors.MyInterceptor 实现了 HandlerInterceptor接口,可以拦截@RequestMapping注解的类和方法
这样无法拦截,最后想的办法是
      <mvc:interceptors>
            <bean class="*.MyInterceptor"></bean>
           </mvc:interceptors>
这样把所有的url进行拦截,然后在拦截器自己手动过滤掉不需要拦截的url,对拦截的进行处理,但是最后一想这样是对所有url进行拦截,肯定对系统的效率有所影响,

4然后想到的是利用切面,自己写个切面,配置切入点,利用切面的 @Before("execution(* *.*(..))") 通知进行处理。配置切面。具体可以看一些这个
http://www.cnblogs.com/friends-wf/p/3832876.html

5最后完美主义的人不能容忍这样的事,感觉切面不是很完美,最后想到去拦截器拦截url,过滤器也可以做到这样的是,可以先看一下两者的区别
http://www.blogjava.net/hello-yun/archive/2011/11/21/364469.html

在写过滤器的时候,需要获取request的参数,get请求servletRequest.getParameter(""),直接这样写就可以获取到,但是最麻烦的是post请求
因为post请求有一些数据会写入到流中,你需要去流中获取数据,

/**
* 获取request流中的数据
* @param request
* @return
* @throws Exception
*/
public String getDate(HttpServletRequest request) throws Exception{
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}

这样数据也可以获取到了,做到这我以为可以了,但是一测数据得到了,但是在执行不下去,因为你在filter获取到流中的数据,流中数据只能读取一次,

你读完了,业务处理中读取不到,你需要回写流中的数据。

package com.imxiaomai.cb.wms.web.filter;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

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

/**
* User: liqiang
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

private final byte[] body;

public BodyReaderHttpServletRequestWrapper(HttpServletRequest request,String data) throws IOException {
super(request);
body = data.getBytes(Charset.forName("UTF-8"));
}

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

@Override
public ServletInputStream getInputStream() throws IOException {

final ByteArrayInputStream bais = new ByteArrayInputStream(body);

return new ServletInputStream() {

@Override
public int read() throws IOException {
return bais.read();
}

public boolean isFinished() {
return false;
}

public boolean isReady() {
return false;
}
};
}
}

 

posted on 2015-09-09 12:03  Frozen丶love  阅读(626)  评论(0编辑  收藏  举报