新增POST_GET方法,对应安全schema;AcceessVerifier新增verifyUserId方法

This commit is contained in:
TommyLemon 2017-02-19 18:34:07 +08:00
parent 68703899a3
commit d566e8aa29
8 changed files with 180 additions and 59 deletions

View File

@ -0,0 +1,23 @@
/*Copyright ©2016 TommyLemon(https://github.com/TommyLemon/APIJSON)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/
package zuo.biao.apijson;
/**请求方法对应org.springframework.web.bind.annotation.RequestMethod多出一个POST_GET方法
* @author Lemon
*/
public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE, POST_GET
}

View File

@ -3,6 +3,7 @@ package zuo.biao.apijson;
public class Table {
public static final String ID = "id";
public static final String USER_ID = "userId";
public static final String NAME = "name";
public static final String SEX = "sex";
public static final String PHONE = "phone";

View File

@ -14,7 +14,7 @@ limitations under the License.*/
package zuo.biao.apijson.server;
import org.springframework.web.bind.annotation.RequestMethod;
import zuo.biao.apijson.RequestMethod;
/**mock test of client
* @author Lemon

View File

@ -29,12 +29,12 @@ public class Controller {
@RequestMapping("get/{request}")
public String get(@PathVariable String request) {
return new RequestParser(RequestMethod.GET).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.GET).parse(request);
}
@RequestMapping(value="post", method = RequestMethod.POST)
public String post(@RequestBody String request) {
return new RequestParser(RequestMethod.POST).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.POST).parse(request);
}
/**用POST方法GET数据request和response都非明文浏览器看不到用于对安全性要求高的GET请求
@ -43,7 +43,6 @@ public class Controller {
*/
@RequestMapping(value="post_get", method = RequestMethod.POST)
public String post_get(@RequestBody String request) {
return new RequestParser(RequestMethod.GET).parse(request);
}
/**以下接口继续用POST接口是为了客户端方便只需要做getpost请求也可以改用实际对应的方法
@ -51,12 +50,12 @@ public class Controller {
*/
@RequestMapping(value="delete", method = RequestMethod.POST)
public String delete(@RequestBody String request) {
return new RequestParser(RequestMethod.DELETE).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.DELETE).parse(request);
}
@RequestMapping(value="put", method = RequestMethod.POST)
public String put(@RequestBody String request) {
return new RequestParser(RequestMethod.PUT).parse(request);
return new RequestParser(zuo.biao.apijson.RequestMethod.PUT).parse(request);
}
}

View File

@ -19,11 +19,10 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.web.bind.annotation.RequestMethod;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.JSON;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;

View File

@ -24,11 +24,10 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import org.springframework.web.bind.annotation.RequestMethod;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.JSON;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;
import zuo.biao.apijson.server.sql.AccessVerifier;
@ -106,7 +105,7 @@ public class RequestParser {
requestObject = AccessVerifier.removeAccessInfo(requestObject);
if (isGetMethod(requestMethod)) {
if (isGetMethod(requestMethod) || requestMethod == RequestMethod.POST_GET) {
requestObject = error == null ? extendSuccessResult(requestObject)
: extendResult(requestObject, 206, "未完成全部请求:\n" + error.getMessage());
}
@ -706,7 +705,7 @@ public class RequestParser {
*/
private synchronized JSONObject getSQLObject(QueryConfig config) throws Exception {
System.out.println("getSQLObject config = " + JSON.toJSONString(config));
AccessVerifier.verify(requestMethod, requestObject, config == null ? null : config.getTable());
AccessVerifier.verify(requestObject, config);
return QueryHelper.getInstance().select(config);//QueryHelper2.getInstance().select(config);//
}
@ -721,12 +720,12 @@ public class RequestParser {
private static final Pattern bigAlphaPattern = Pattern.compile("[A-Z]");
private static final Pattern namePattern = Pattern.compile("^[0-9a-zA-Z_]+$");//已用55个中英字符测试通过
public static boolean isTableKey(String key) {
key = StringUtil.getString(key);
return StringUtil.isNotEmpty(key, false) && isArrayKey(key) == false
&& bigAlphaPattern.matcher(key.substring(0, 1)).matches();
return StringUtil.isNotEmpty(key, false)
&& bigAlphaPattern.matcher(key.substring(0, 1)).matches()
&& namePattern.matcher(key.substring(1)).matches();
}
public static boolean isArrayKey(String key) {
return key != null && key.endsWith("[]");

View File

@ -2,11 +2,11 @@ package zuo.biao.apijson.server.sql;
import java.rmi.AccessException;
import org.springframework.web.bind.annotation.RequestMethod;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.server.QueryConfig;
/**权限验证类
* @author Lemon
@ -21,39 +21,65 @@ public class AccessVerifier {
public static final String KEY_LOGIN_PASSWORD = "loginPassword";
public static final String KEY_PAY_PASSWORD = "payPassword";
// public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Work", "Comment"};
public static final String[] PAY_ACCESS_TABLE_NAMES = {"Wallet"};
public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Wallet"};
public static final String[] PAY_ACCESS_TABLE_NAMES = {};
/**验证权限是否通过
* @param method
* @param request
* @param tableName
* @param config
* @return
* @throws Exception
*/
public static boolean verify(RequestMethod method, JSONObject request, String tableName) throws AccessException {
return verify(method, request, getAccessId(tableName));
public static boolean verify(JSONObject request, QueryConfig config) throws Exception {
String table = config == null ? null : config.getTable();
if (table == null) {
return true;
}
if (request == null) {
return false;
}
long currentUserId = request.getLongValue(KEY_CURRENT_USER_ID);
/**验证权限是否通过
* @param method
switch (config.getMethod()) {
case GET:
case POST_GET:
if ("Wallet".equals(table) || "Password".equals(table)) {
verifyUserId(currentUserId, config);
}
break;
case POST:
case PUT:
case PATCH:
case DELETE:
verifyUserId(currentUserId, config);
break;
default:
break;
}
return verifyAccess(request, table, config.getMethod(), currentUserId);
}
/**
* @param request
* @param accessId 可以直接在代码里写ACCESS_LOGIN等或者建一个Access表包括id和需要改权限的table的tableName列表
* @param table
* @param method
* @param currentUserId
* @return
* @throws AccessException
*/
public static boolean verify(RequestMethod method, JSONObject request, int accessId) throws AccessException {
if (accessId < 0 || request == null) {
private static boolean verifyAccess(JSONObject request, String table, RequestMethod method, long currentUserId) throws AccessException {
int accessId = getAccessId(method, table);
if (accessId < 0) {
return true;
}
long currentUserId = request.getLongValue(KEY_CURRENT_USER_ID);
if (currentUserId <= 0) {
System.out.println(TAG + "verify accessId = " + accessId
+ " >> currentUserId <= 0, currentUserId = " + currentUserId);
throw new AccessException("请设置"+ KEY_CURRENT_USER_ID + "和对应的password");
}
String password;
switch (accessId) {
case ACCESS_LOGIN:
password = StringUtil.getString(request.getString(KEY_LOGIN_PASSWORD));
@ -63,6 +89,7 @@ public class AccessVerifier {
+ " currentUserId = " + currentUserId + ", loginPassword = " + password);
throw new AccessException(KEY_CURRENT_USER_ID + "" + KEY_LOGIN_PASSWORD + "错误!");
}
break;
case ACCESS_PAY:
password = StringUtil.getString(request.getString(KEY_PAY_PASSWORD));
if (password.equals(StringUtil.getString(getPayPassword(currentUserId))) == false) {
@ -71,9 +98,36 @@ public class AccessVerifier {
+ " currentUserId = " + currentUserId + ", payPassword = " + password);
throw new AccessException(KEY_CURRENT_USER_ID + "" + KEY_PAY_PASSWORD + "错误!");
}
default:
break;
}
return true;
}
/**
* @param currentUserId
* @param config
* @return
* @throws Exception
*/
private static boolean verifyUserId(long currentUserId, QueryConfig config) throws Exception {
// if (currentUserId <= 0 || config == null) {
// return true;
// }
// Map<String, Object> where = config.getWhere();
// long userId = 0;
// String table = StringUtil.getString(config.getTable());
// if (where != null) {
// try {
// String key = "User".equals(table) ? Table.ID : Table.USER_ID;
// userId = (long) where.get(key);
// } catch (Exception e) {
// // TODO: handle exception
// }
// }
// if (userId != currentUserId) {
// throw new IllegalArgumentException(table + "的userId和currentUserId不一致");
// }
return true;
}
@ -82,17 +136,17 @@ public class AccessVerifier {
* @param tableName
* @return
*/
public static int getAccessId(String tableName) {
if (StringUtil.isNotEmpty(tableName, true) == false) {
public static int getAccessId(RequestMethod method, String table) {
if (StringUtil.isNotEmpty(table, true) == false) {
return -1;
}
// for (int i = 0; i < LOGIN_ACCESS_TABLE_NAMES.length; i++) {
// if (tableName.equals(LOGIN_ACCESS_TABLE_NAMES[i])) {
// return ACCESS_LOGIN;
// }
// }
for (int i = 0; i < LOGIN_ACCESS_TABLE_NAMES.length; i++) {
if (table.equals(LOGIN_ACCESS_TABLE_NAMES[i])) {
return ACCESS_LOGIN;
}
}
for (int i = 0; i < PAY_ACCESS_TABLE_NAMES.length; i++) {
if (tableName.equals(PAY_ACCESS_TABLE_NAMES[i])) {
if (table.equals(PAY_ACCESS_TABLE_NAMES[i])) {
return ACCESS_PAY;
}
}
@ -105,7 +159,7 @@ public class AccessVerifier {
*/
public static String getLoginPassword(long userId) {
// TODO 查询并返回对应userId的登录密码
return "123456";//仅测试用
return "apijson123";//仅测试用
}
/**获取支付密码
@ -130,4 +184,11 @@ public class AccessVerifier {
return requestObject;
}
// public static class Access {
// public static class Get {
// public static final String[] LOGIN_ACCESS_TABLE_NAMES = {"Wallet"};
// }
// }
}

View File

@ -25,6 +25,7 @@ import java.util.List;
import com.alibaba.fastjson.JSONObject;
import zuo.biao.apijson.RequestMethod;
import zuo.biao.apijson.StringUtil;
import zuo.biao.apijson.Table;
import zuo.biao.apijson.server.QueryConfig;
@ -38,6 +39,7 @@ public class QueryHelper {
private static final String YOUR_MYSQL_URL = "jdbc:mysql://localhost:3306/";//TODO edit to an available one
private static final String YOUR_MYSQL_SCHEMA = "sys";//TODO edit to an available one
private static final String YOUR_MYSQL_SCHEMA_SECURITY = "security";//TODO edit to an available one
private static final String YOUR_MYSQL_ACCOUNT = "root";//TODO edit to an available one
private static final String YOUR_MYSQL_PASSWORD = "apijson";//TODO edit to an available one
@ -54,10 +56,16 @@ public class QueryHelper {
}
public Connection getConnection() throws Exception {
return getConnection(null);
}
public Connection getConnection(String schema) throws Exception {
if (schema == null) {
schema = YOUR_MYSQL_SCHEMA;
}
//调用Class.forName()方法加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
System.out.println(TAG + "成功加载MySQL驱动");
return DriverManager.getConnection(YOUR_MYSQL_URL + YOUR_MYSQL_SCHEMA, YOUR_MYSQL_ACCOUNT, YOUR_MYSQL_PASSWORD);
return DriverManager.getConnection(YOUR_MYSQL_URL + schema, YOUR_MYSQL_ACCOUNT, YOUR_MYSQL_PASSWORD);
}
@ -90,7 +98,7 @@ public class QueryHelper {
if (connection == null || connection.isClosed()) {
System.out.println(TAG + "select connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
connection = getConnection();
connection = getConnection(getSchema(config.getMethod()));
statement = connection.createStatement(); //创建Statement对象
metaData = connection.getMetaData();
}
@ -105,18 +113,23 @@ public class QueryHelper {
JSONObject object = null;//new JSONObject(true);
ResultSet rs = null;
switch (config.getMethod()) {
case GET:
case POST_GET:
rs = statement.executeQuery(sql);
break;
case POST:
case PUT:
case PATCH:
case DELETE:
int updateCount = statement.executeUpdate(sql);//创建数据对象
int updateCount = statement.executeUpdate(sql);
JSONObject result = RequestParser.newResult(updateCount > 0 ? 200 : 404
, updateCount > 0 ? "success" : "可能对象不存在!");
result.put(Table.ID, config.getId());
return result;
default:
rs = statement.executeQuery(sql);//创建数据对象
break;
default://HEAD, OPTIONS, TRACE等
System.out.println(TAG + "select sql = " + sql + " ; method = " + config.getMethod() + " >> return null;");
return null;
}
@ -169,15 +182,41 @@ public class QueryHelper {
return list.toArray(new String[]{});
}
/**
* @param method
* @return
*/
public static String getSchema(RequestMethod method) {
return method == RequestMethod.POST_GET ? YOUR_MYSQL_SCHEMA_SECURITY : YOUR_MYSQL_SCHEMA;
}
/**
* @param table
* @return
* @throws Exception
*/
public int getCount(String table) throws Exception {
return getCount(table, RequestMethod.GET);
}
/**
* @param table
* @param method
* @return
* @throws Exception
*/
public int getCount(String table, RequestMethod method) throws Exception {
return getCount(table, getSchema(method));
}
/**
* @param table
* @param schema
* @return
* @throws Exception
*/
public int getCount(String table, String schema) throws Exception {
if (connection == null || connection.isClosed()) {
System.out.println(TAG + "getCount connection " + (connection == null ? " = null" : ("isClosed = " + connection.isClosed()))) ;
connection = getConnection();
connection = getConnection(schema);
statement = connection.createStatement(); //创建Statement对象
metaData = connection.getMetaData();
}