openApi实现 SDK 安全认证

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实例:

  1. http:://XXXX?数据+时间+secretId 返回sgin
  2. http:://XXXX?数据+时间+secretId+sgin 传入数据

实现步骤

  1. 将新建表结构,使用apply_id当做盐还生成secret_id
  2. 创建的每一条数据redis和数据库各存一份,刷新签名串也一样需要存两份。redis设置方式set(secretId,secretKey) ;
  3. 当第一个Url请求时(http:://XXXX?数据+时间+secretId) 使用secretId先从redis里查询是否存在,若不存在从数据库中查询。
  4. 查询到数据以后,取出secretKey 生成签名 签名串=数据+时间+secretId+secretKey 并返回http
  5. 再请求第二个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.
 */
@RestController
@RequestMapping("/api/v1")
@Api(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
     */
    @PostMapping("/add-open-api-users")
    @Timed
    @ApiOperation(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
     */
    @PutMapping("/open-api-users")
    @Timed
    @ApiOperation(value = "修改", notes = "修改")
    public ResponseEntity<OpenApiUserDTO> updateOpenApiUser(@RequestBody 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
     */
    @GetMapping("/open-api-users")
    @Timed
    @ApiOperation(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
     */
    @PutMapping("/refresh-secretKey")
    @Timed
    @ApiOperation(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)
     */
    @GetMapping("/open-api-users/{id}")
    @Timed
    @ApiOperation(value = "根据Id查询", notes = "根据Id查询")
    public ResponseEntity<OpenApiUserDTO> getOpenApiUser(@PathVariable 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)
     */
    @DeleteMapping("/open-api-users/{id}")
    @Timed
    @ApiOperation(value = "删除", notes = "删除")
    public ResponseEntity<Void> deleteOpenApiUser(@PathVariable 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.
 */
@RestController
@RequestMapping("/api/openapi/v1")
@Api(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";
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    public DataApiResource(OpenApiUserService openApiUserService) {
        this.openApiUserService = openApiUserService;
    }


    @Autowired
    ProducerChannel channel;


    @PostMapping(value = "/data-api")
    @ApiOperation(value = "工况数据发送到kafka", notes = "工况数据发送到kafka")
    @Timed
    public ResponseEntity<?> getDataApi(@RequestBody 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));
    }


    @GetMapping(value = "/sign-info")
    @ApiOperation(value = "签名生成", notes = "签名生成")
    @Timed
    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));
    }
    @PostMapping(value = "/sign-info")
    @ApiOperation(value = "签名生成", notes = "签名生成")
    @Timed
    public ResponseEntity<?> getDataApiSignPost(@RequestBody 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));
    }

    @PostMapping(value = "/send-data")
    @ApiOperation(value = "发送数据", notes = "发送数据")
    @Timed
    public ResponseEntity<?> sendDataPost(@RequestBody JSONObject jsonObject) {

        JSONObject jsonData=sendData(jsonObject);
        String deviceData = jsonData.toJSONString();
        channel.messageChannel().send(MessageBuilder.withPayload(deviceData.getBytes()).build());

        return ResponseUtil.wrapOrNotFound(Optional.ofNullable(deviceData));
    }

    @GetMapping(value = "/send-data")
    @ApiOperation(value = "发送数据", notes = "发送数据")
    @Timed
    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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值