Android—构建安全的Androidclient请求,避免非法请求
今天通过实例来介绍一下怎样构建安全的Android客户端请求。避免非法请求:
server端代码:
代码1—工具类:
package com.ghj.packageoftool; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date; /**
* 字符串SHA-1转换
*
* @author 高焕杰
*/
public class Sha1Util { public static String SHA(String paramString) {
MessageDigest localMessageDigest;
try {
localMessageDigest = MessageDigest.getInstance("SHA-1");
localMessageDigest.update(paramString.getBytes());
return toHexString(localMessageDigest.digest()).toUpperCase();
} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
localNoSuchAlgorithmException.printStackTrace();
return "";
}
} private static String toHexString(byte[] digestArray) {
if (digestArray == null || digestArray.length <= 0) {
return "";
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < digestArray.length; i++) {
String hexString = Integer.toHexString(digestArray[i] & 0xFF);
if (hexString.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hexString);
}
return stringBuilder.toString();
} public static void main(String[] paramArrayOfString) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String timeStamp = dateFormat.format(new Date());
String str = SHA("2014-12-16 10:19:30" + "miyue");
System.out.println(timeStamp + "signature:"+str.equals("927CFBFC8D0F049CEDB83FB10FBEC9AC784A9460"));
}
}
代码2—过滤器类:
package com.ghj.packageoffilter; import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.ghj.packageoftool.Sha1Util; /**
* 本过滤器用来校验请求是否合法
*
* @author 高焕杰
*/
public class CheckRequestFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String secretKey = "AndroidClient";
String timeStamp = request.getParameter("timeStamp");
String signature = request.getParameter("signature");
String dateDifference = getDateDifference(timeStamp); if(dateDifference == null){//系统时间和时间戳的差值为null,这说明该请求中的时间被觉得的进行了改动且时间格式不对。
sendErrorState(response, 0);
}
if(!Sha1Util.SHA(timeStamp + secretKey).equals(signature)){//假设时间戳被人为地进行了改动造成请求签名不一致。 sendErrorState(response, 1);
}else if(Integer.parseInt(dateDifference) > 1000*60*5){//假设请求从创建到到达server端的时间大于5分钟,则觉得请求超时——不给别实用心的人思考的时间
sendErrorState(response, 2);
}else{
chain.doFilter(request, response);
}
} private void sendErrorState(HttpServletResponse response, int errorState) {
PrintWriter out = null;
try {
out = response.getWriter();
out.println("errorState:" + errorState);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
out.close();
}
return;
} /**
* @see: 获取时间戳与当前系统时间的差值(以毫秒为单位)
*
* @author GaoHuanjie
*/
private String getDateDifference(String timeStamp){
try{
if(timeStamp != null){
return String.valueOf(new Date().getTime()- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timeStamp).getTime());//获取系统时间(毫秒)-时间戳时间(毫秒)
}
}catch(Exception e){
e.printStackTrace();
}
return null;
} public void destroy() { } public void init(FilterConfig filterConfig) throws ServletException { }
}
代码3—Servlet类:
package com.ghj.packageofservlet; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ServerServlet extends HttpServlet { private static final long serialVersionUID = -1052048925901833921L; public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain; charset=UTF-8");
request.setCharacterEncoding("UTF-8");
System.err.println(request.getParameter("clientData"));
PrintWriter printWriter = response.getWriter();
printWriter.print("您好Android客户端!");
printWriter.flush();
printWriter.close();
}
}
代码4—配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <filter>
<filter-name>checkRequestFilter</filter-name>
<filter-class>com.ghj.packageoffilter.CheckRequestFilter</filter-class>
</filter> <filter-mapping>
<filter-name>checkRequestFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping> <servlet>
<servlet-name>ServerServlet</servlet-name>
<servlet-class>com.ghj.packageofservlet.ServerServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ServerServlet</servlet-name>
<url-pattern>/ServerServlet.do</url-pattern>
</servlet-mapping>
</web-app>
客户端代码:
代码1—工具类:
与server端工具类全然一样!
代码1—Activity类:
package com.ghj.packageofactivity; import java.text.SimpleDateFormat;
import java.util.Date; import org.apache.http.Header; import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; import com.example.androidclient.R;
import com.ghj.packageoftool.Sha1Util;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams; public class AndroidClientActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.android_client); Button sendInfoButton = (Button) findViewById(R.id.sendInfoButton);
sendInfoButton.setOnClickListener(new OnClickListener(){
@Override
@SuppressLint("SimpleDateFormat")
public void onClick(View v) {
String secretKey = "AndroidClient";
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
RequestParams requestParams = new RequestParams();
requestParams.add("clientData", "您好server端!");
requestParams.add("timeStamp", timeStamp);
requestParams.add("signature", Sha1Util.SHA(timeStamp + secretKey));
new AsyncHttpClient().post("http://172.16.99.207:8080/CheckRequest/ServerServlet.do", requestParams, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if(statusCode == 200){
String responseData = new String(responseBody);
if(responseData.contains("errorState")){
Toast.makeText(AndroidClientActivity.this, "请求非法! ", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(AndroidClientActivity.this, new String(responseBody), Toast.LENGTH_LONG).show();
}
}
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Toast.makeText(AndroidClientActivity.this, "没有获取到Androidserver端的响应! ", Toast.LENGTH_LONG).show();
}
});
}
});
}
}
总结:
1、因为该Demo客户端须要依赖非常多文件和一些jar包,所以建议直接下载完整Demoproject——【0分下载Demo】
2、实现这个功能事实上非常easy:一句话,想尽一切方法让别实用心的人发出的请求失效!
!!
Android—构建安全的Androidclient请求,避免非法请求的更多相关文章
- android构建过程
参考: http://blog.csdn.net/shangmingchao/article/details/47375111 首先,需要了解一下构建APK的七大工具: ①aapt 全称是Androi ...
- Android系列之网络(二)----HTTP请求头与响应头
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- 关于Android 构建
在简书上面有系列关于Android 的文章,还不错,部分同学可以在开发过程中阅读和学习:www.jianshu.com/collection/3fde3b545a35 关于Android 构建,看到这 ...
- Docker+Jenkins持续集成环境(5): android构建与apk发布
项目组除了常规的java项目,还有不少android项目,如何使用jenkins来实现自动构建呢?本文会介绍安卓项目通过jenkins构建的方法,并设计开发一个类似蒲公英的app托管平台. andro ...
- Java代码手段防止非法请求——防盗链
Java代码手段防止非法请求,思路如下: 1. 获取到当前请求的域名,如www.a.com 2. 获取到请求资源的上一个地址 3. 判断上一个地址是否为空,如 ...
- 学习RxJava+Retrofit+OkHttp+MVP的网络请求使用
公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了. 我在网上找了很多文章,写的都很详细,比如 https://www.jianshu.com/u/5fd2523645da https://www. ...
- 七:Spring Security 前后端分离登录,非法请求直接返回 JSON
Spring Security 前后端分离登录,非法请求直接返回 JSON 解决方案 在 Spring Security 中未获认证的请求默认会重定向到登录页,但是在前后端分离的登录中,这个默认行为则 ...
- Android的HttpUrlConnection类的GET和POST请求
/** * get方法使用 */ private void httpGet() { new Thread() { @Override public void run() { //此处的LOGIN是请求 ...
- 解决springboot项目请求出现非法字符问题 java.lang.IllegalArgumentException:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
springboot版本: 2.1.5 最近使用springboot搭建了一个App后台服务的项目,开发接口的时候在本机使用postman工具做请求测试,请求返回一直很正常,但是在前端开发使用h5请求 ...
随机推荐
- php正则给图片提取/替换/添加alt标签的正则代码
有的时候我们需要对富文本编辑器的内容做一些处理,例如图片的alt标签.百度的富文本编辑器添加的图片就是没有的,那么我们要添加就必须使用正则了,下面一起来看看如何实现吧. $preg = "/ ...
- CentOS 6下搭建LAMP环境
第一步,使用Xshell管理工具连接远程服务器 第二步,输入服务器账号密码登录远程服务器 如果centos内置的yum源可用的软件偏少或者版本过低,请更新! 首先备份/etc/yum.repos.d/ ...
- IDA 显示函数名称技巧
http://blog.csdn.net/safedebug/article/details/17061735v
- 辛星跟您解析在CSS面包屑中三角形的定位问题
刚才看到有位网友非常纳闷第二个棕色三角形是怎么定位的,我当感觉在以下说不清楚,就特别开了一片博客.来说清楚它.首先,前面的代码我们先抄下来,至于前面这部分代码是怎么来的,读我的用CSS制作面包屑导航的 ...
- git和SVN的差别
1)GIT是分布式的.SVN不是: 这 是GIT和其它非分布式的版本号控制系统,比如SVN.CVS等.最核心的差别.优点是跟其它同事不会有太多的冲突.自己写的代码放在自己电脑上,一段时间后再提交.合并 ...
- GO -- 一个经验
加锁要在有用的的上下文再加锁, 不要加的范围多了, 否则被锁住.
- [翻译] JFDepthView 给view提供3D景深
JFDepthView 给view提供3D景深 https://github.com/atljeremy/JFDepthView This is an iOS project for presenti ...
- faked 一个用于 mock 后端 API 的轻量工具
一.简介 faked 是一个在前端开发中用于 mock 服务端接口的模块,轻量简单,无需要在本地启动 Server 也无需其它更多的资源,仅在浏览器中完成「请求拉截」,配合完整的「路由系统」轻而易举的 ...
- jquery empty()方法
empty() 方法从被选元素移除所有内容,包括所有文本和子节点. $(selector).empty() <html> <head> <script type=&quo ...
- CSS学习要点
目标 掌握CSS基本语法,了解如何应用CSS到Html元素上并能熟练使用CSS进行元素布局. 要点 CSS基本概念.存在的意义 CSS 指层叠样式表 (Cascading Style Sheets), ...