openApi实现 SDK 安全认证
实现思路 采用MD5
签名串=数据+时间+secretId+secretKey(盐)
sign=data+timestamp+secretId+secretKey(盐)
sql表结构
1234567891011121314create table open_api_user
(
id bigint not null auto_increment
primary key,
apply_id varchar(255) null, --创建人
secret_id varchar(255) null,
secret_key varchar(255) null,
create_by varchar(255) null,
create_date timestamp null,
update_by varchar(255) null,
update_date timestamp null,
del_flag varchar(255) null
)
;
URL实例:
- http:://XXXX?数据+时间+secretId 返回sgin
- http:://XXXX?数据+时间+secretId+sgin 传入数据
实现步骤
- 将新建表结构,使用apply_id当做盐还生成secret_id
- 创建的每一条数据redis和数据库各存一份,刷新签名串也一样需要存两份。redis设置方式set(secretId,secretKey) ;
- 当第一个Url请求时(http:://XXXX?数据+时间+secretId) 使用secretId先从redis里查询是否存在,若不存在从数据库中查询。
- 查询到数据以后,取出secretKey 生成签名 签名串=数据+时间+secretId+secretKey 并返回http
- 再请求第二个URl进行上传数据 http:://XXXXData?data+timestamp+secretId+sgin 。 后台一样会根据secretId查询到secretKey 进行做MD5校验。
data+timestamp+secretId 三者如果任何一方发生改变都会导致验证失败
java创建open_api_user代码块
Controller代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
import com.codahale.metrics.annotation.Timed;
import io.github.jhipster.web.util.ResponseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;
/**
* REST controller for managing OpenApiUser.
*/
("/api/v1")
(value = "openApi接口服务",description = "openApi接口服务")
public class OpenApiUserResource {
private final Logger log = LoggerFactory.getLogger(OpenApiUserResource.class);
private static final String ENTITY_NAME = "openApiUser";
private final OpenApiUserService openApiUserService;
public OpenApiUserResource(OpenApiUserService openApiUserService) {
this.openApiUserService = openApiUserService;
}
/**
* POST /open-api-users : Create a new openApiUser.
*
* @param applyId the openApiUserDTO to create
* @return the ResponseEntity with status 201 (Created) and with body the new openApiUserDTO, or with status 400 (Bad Request) if the openApiUser has already an ID
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
("/add-open-api-users")
(value = "添加openApiInfo", notes = "添加openApiInfo")
public ResponseEntity<OpenApiUserDTO> createOpenApiUser(String applyId) throws URISyntaxException {
log.debug("REST request to save applyId : {}", applyId);
OpenApiUserDTO openApiUserDTO = new OpenApiUserDTO();
String secretId = MD5Util.MD5(applyId);
openApiUserDTO.setApplyId(applyId);
openApiUserDTO.setSecretId(secretId);
openApiUserDTO.setSecretKey(MD5Util.MD5(System.currentTimeMillis()+""));
openApiUserDTO.setCreateDate(ZonedDateTime.now());
String userName = SecurityUtils.getCurrentUserLogin().get();
openApiUserDTO.setCreateBy(userName);
openApiUserDTO.setDelFlag("0");
OpenApiUserDTO result = openApiUserService.save(openApiUserDTO);
return ResponseEntity.created(new URI("/api/open-api-users/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString()))
.body(result);
}
/**
* PUT /open-api-users : Updates an existing openApiUser.
*
* @param openApiUserDTO the openApiUserDTO to update
* @return the ResponseEntity with status 200 (OK) and with body the updated openApiUserDTO,
* or with status 400 (Bad Request) if the openApiUserDTO is not valid,
* or with status 500 (Internal Server Error) if the openApiUserDTO couldn't be updated
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
("/open-api-users")
(value = "修改", notes = "修改")
public ResponseEntity<OpenApiUserDTO> updateOpenApiUser( OpenApiUserDTO openApiUserDTO) throws URISyntaxException {
log.debug("REST request to update OpenApiUser : {}", openApiUserDTO);
OpenApiUserDTO result = openApiUserService.save(openApiUserDTO);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, openApiUserDTO.getId().toString()))
.body(result);
}
/**
* GET /open-api-users : get all the openApiUsers.
*
* @param pageable the pagination information
* @param openApiUserDTO the criterias which the requested entities should match
* @return the ResponseEntity with status 200 (OK) and the list of openApiUsers in body
*/
("/open-api-users")
(value = "查询", notes = "查新")
public ResponseEntity<List<OpenApiUserDTO>> getAllOpenApiUsers(OpenApiUserDTO openApiUserDTO, Pageable pageable) {
log.debug("REST request to get OpenApiUsers by openApiUserDTO: {}", openApiUserDTO);
Page<OpenApiUserDTO> page = openApiUserService.findAll(openApiUserDTO,pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/open-api-users");
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
/**
* 刷新key
* @param id
* @return
*/
("/refresh-secretKey")
(value = "刷新secretKey", notes = "刷新secretKey")
public ResponseEntity<?> refreshSecretKey(Long id) {
OpenApiUserDTO openApiUserDTO = openApiUserService.findOne(id);
String userName = SecurityUtils.getCurrentUserLogin().get();
openApiUserDTO.setUpdateBy(userName);
openApiUserDTO.setSecretKey(MD5Util.MD5(System.currentTimeMillis()+""));
openApiUserDTO.setUpdateDate(ZonedDateTime.now());
log.debug("REST request to get OpenApiUsers by openApiUserDTO: {}", openApiUserDTO);
openApiUserDTO = openApiUserService.save(openApiUserDTO);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert(ENTITY_NAME, openApiUserDTO.getId().toString()))
.body(openApiUserDTO);
}
/**
* GET /open-api-users/:id : get the "id" openApiUser.
*
* @param id the id of the openApiUserDTO to retrieve
* @return the ResponseEntity with status 200 (OK) and with body the openApiUserDTO, or with status 404 (Not Found)
*/
("/open-api-users/{id}")
(value = "根据Id查询", notes = "根据Id查询")
public ResponseEntity<OpenApiUserDTO> getOpenApiUser( Long id) {
log.debug("REST request to get OpenApiUser : {}", id);
OpenApiUserDTO openApiUserDTO = openApiUserService.findOne(id);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(openApiUserDTO));
}
/**
* DELETE /open-api-users/:id : delete the "id" openApiUser.
*
* @param id the id of the openApiUserDTO to delete
* @return the ResponseEntity with status 200 (OK)
*/
("/open-api-users/{id}")
(value = "删除", notes = "删除")
public ResponseEntity<Void> deleteOpenApiUser( Long id) {
log.debug("REST request to delete OpenApiUser : {}", id);
openApiUserService.delete(id);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(ENTITY_NAME, id.toString())).build();
}
}
MD5 代码
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
import liquibase.util.StringUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Created by qq on 2018/4/9.
*/
public class MD5Util {
public static String MD5(String s) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytes = md.digest(s.getBytes("utf-8"));
return toHex(bytes).toLowerCase();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String toHex(byte[] bytes) {
final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
StringBuilder ret = new StringBuilder(bytes.length * 2);
for (int i=0; i<bytes.length; i++) {
ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
}
return ret.toString();
}
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
String md5 = MD5Util.MD5("user");
String md51 = MD5Util.MD5(md5+"user");
Map<String, String> map = new HashMap();
map.put("user","123");
map.put("user1","1232");
map.put("dm5",md5);
MessageDigest md = MessageDigest.getInstance("MD5");
System.out.println(StringUtils.isEmpty(null));
}
}
sign串认证接口java代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
import com.alibaba.fastjson.JSONObject;
import io.github.jhipster.web.util.ResponseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import liquibase.util.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Created by howey on 2018/6/1.
*/
("/api/openapi/v1")
(value = "数据发送到kafka",description = "数据发送到kafka")
public class DataApiResource {
private static Logger logger = Logger.getLogger(DataApiResource.class);
private final OpenApiUserService openApiUserService;
private static final String ENTITY_NAME = "openApiUser";
private RedisTemplate<Object, Object> redisTemplate;
public DataApiResource(OpenApiUserService openApiUserService) {
this.openApiUserService = openApiUserService;
}
ProducerChannel channel;
(value = "/data-api")
(value = "工况数据发送到kafka", notes = "工况数据发送到kafka")
public ResponseEntity<?> getDataApi( JSONObject jsonObject) {
String deviceData = jsonObject.toString();
logger.debug("s end newDataJson to kafka :" + deviceData);
channel.messageChannel().send(MessageBuilder.withPayload(deviceData.getBytes()).build());
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(deviceData));
}
(value = "/sign-info")
(value = "签名生成", notes = "签名生成")
public ResponseEntity<?> getDataApiSign(HttpServletRequest request) {
Enumeration<String> pNames= request.getParameterNames();
Map<String,Object> map = new HashMap();
while(pNames.hasMoreElements()) {
String name = pNames.nextElement();
String value = request.getParameter(name);
map.put(name, value);
}
String timestamp = (String)map.get("timestamp");
String secretId = (String)map.get("secretId");
String data = (String)map.get("data");
if(StringUtils.isEmpty(timestamp)){
timestamp = System.currentTimeMillis()+"";
}
String secretKey = getSecretKey(secretId);
String sign = MD5Util.MD5(secretId+timestamp+data+secretKey);
map = new HashMap<>();
map.put("sign",sign);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(map));
}
(value = "/sign-info")
(value = "签名生成", notes = "签名生成")
public ResponseEntity<?> getDataApiSignPost( JSONObject jsonObject) {
String timestamp = (String)jsonObject.get("timestamp");
String secretId = (String)jsonObject.get("secretId");
String data = (String)jsonObject.get("data");
if(StringUtils.isEmpty(timestamp)){
timestamp = System.currentTimeMillis()+"";
}
String secretKey = getSecretKey(secretId);
String sign = MD5Util.MD5(secretId+timestamp+data+secretKey);
Map<String,Object> map = new HashMap<>();
map.put("sign",sign);
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(map));
}
(value = "/send-data")
(value = "发送数据", notes = "发送数据")
public ResponseEntity<?> sendDataPost( JSONObject jsonObject) {
JSONObject jsonData=sendData(jsonObject);
String deviceData = jsonData.toJSONString();
channel.messageChannel().send(MessageBuilder.withPayload(deviceData.getBytes()).build());
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(deviceData));
}
(value = "/send-data")
(value = "发送数据", notes = "发送数据")
public ResponseEntity<?> sendDataGet(HttpServletRequest request) {
Enumeration<String> pNames= request.getParameterNames();
Map<String,Object> map = new HashMap();
while(pNames.hasMoreElements()) {
String name = pNames.nextElement();
String value = request.getParameter(name);
map.put(name, value);
}
JSONObject jsonData1 = new JSONObject(map);
JSONObject jsonData=sendData(jsonData1);
String deviceData = jsonData.toJSONString();
channel.messageChannel().send(MessageBuilder.withPayload(deviceData.getBytes()).build());
return ResponseUtil.wrapOrNotFound(Optional.ofNullable(deviceData));
}
public JSONObject sendData(JSONObject jsonObject) {
/**验证字段是否正确**/
verificationField(jsonObject);
String timestamp = (String) jsonObject.get("timestamp");
String secretId = (String) jsonObject.get("secretId");
String signReq = (String) jsonObject.get("sign");
JSONObject data = jsonObject.getJSONObject("data");
String secretKey = getSecretKey(secretId);
String sign = MD5Util.MD5(secretId + timestamp + data + secretKey);
String deviceData = jsonObject.toString();
logger.debug("s end newDataJson to kafka :" + deviceData);
if (sign.equals(signReq)) {
return data;
} else {
throw new RequestAlertException(JsonResultStatus.SIGN_ERROR, ENTITY_NAME);
}
}
public boolean verificationField(JSONObject jsonObject){
String timestamp = (String)jsonObject.get("timestamp");
String secretId = (String)jsonObject.get("secretId");
String sign = (String)jsonObject.get("sign");
JSONObject status = jsonObject.getJSONObject("data").getJSONObject("status");
if(StringUtils.isEmpty(timestamp)){
throw new RequestAlertException("timestamp 不能为空",ENTITY_NAME,"timestamp");
}else if(StringUtils.isEmpty(secretId)){
throw new RequestAlertException("secretId 不能为空",ENTITY_NAME,"secretId");
}else if(StringUtils.isEmpty(sign)){
throw new RequestAlertException("sign 不能为空",ENTITY_NAME,"sign");
}else if(StringUtils.isEmpty((String)status.get("_LOCATION_"))){
throw new RequestAlertException("LOCATION 不能为空",ENTITY_NAME,"location");
}else{
return true;
}
}
public String getSecretKey(String secretId){
String secretKey = (String) redisTemplate.opsForValue().get(secretId);
if (StringUtils.isEmpty(secretKey)) {
OpenApiUserDTO openApiUserDTO = openApiUserService.findBySecretId(secretId);
if (openApiUserDTO != null) {
secretKey = openApiUserDTO.getSecretKey();
} else {
throw new RequestAlertException(JsonResultStatus.SECRETID_NOT_EXIST, ENTITY_NAME);
}
}
return secretKey;
}
}
以上代码仅供参考如有问题请加QQ 295644825 微信:wx_hewei