Commit f40088ce authored by zengtianlai3's avatar zengtianlai3

对接鉴权,修改已知bug

parent 1f2285d5
package iot.sixiang.license.auth;
import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.entity.Apply;
import iot.sixiang.license.entity.Device;
import iot.sixiang.license.entity.License;
import iot.sixiang.license.entity.User;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.vo.AppVo;
import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.service.ApplyService;
import iot.sixiang.license.service.DeviceService;
import iot.sixiang.license.service.LicenseService;
import iot.sixiang.license.service.UserService;
import iot.sixiang.license.util.HmacUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......@@ -19,55 +28,50 @@ public class AuthManager {
@Autowired
private UserService userService;
@Autowired
private LicenseService licenseService;
private ApplyService applyService;
@Autowired
private DeviceManager deviceManager;
private Map<String, User> allUsers = null;
private Map<String, License> allLicense = null;
private Map<String, Apply> allApply = null;
public AuthManager() {
allUsers = new HashMap<String, User>();
allLicense = new HashMap<String, License>();
allApply = new HashMap<String, Apply>();
}
@PostConstruct
public void init() {
initUsers();
initLicense();
}
private void initUsers() {
// List<User> users = userService.getUserList(0, 20);
// for (User user : users) {
// String userId = user.getUserId();
// allUsers.put(userId, user);
// }
initApps();
}
private void initLicense() {
List<License> licenses = licenseService.getLicenseList(0, 20);
for (License license : licenses) {
String appId = license.getAppId();
allLicense.put(appId, license);
public void initApps() {
allApply = new HashMap<>();
PageInfoModel<AppVo> records = applyService.getAppList(1, 10000, "");
List<AppVo> appList = records.getResult();
for (Apply apply : appList) {
String appId = apply.getAppId().toString();
allApply.put(appId, apply);
}
}
public boolean auth(String userId, String password, String appId, String appKey) {
if (!allUsers.containsKey(userId)) {
return false;
} else {
User user = allUsers.get(userId);
if (user.getPassword() != password) {
public boolean auth(String appId, String sn, String sign) {
if (!allApply.containsKey(appId)) {
return false;
}
}
if (!allLicense.containsKey(appId)) {
if (!deviceManager.getContainSn(sn)) {
return false;
}
Apply apply = allApply.get(appId);
String appKey = apply.getAppKey();
String input = "app_id=" + appId + "&sn=" + sn;
String valSHA1 = HmacUtil.encrypt(input, appKey, HmacUtil.HMAC_SHA1).toUpperCase();
if (sign.equals(valSHA1)) {
return true;
} else {
License license = allLicense.get(appId);
if (license.getAppKey() != appKey) {
return false;
}
}
return true;
}
}
package iot.sixiang.license.device;
import iot.sixiang.license.forward.ForwardManager;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.SessionContext;
import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.net.TcpServer;
import lombok.Getter;
import lombok.Setter;
import iot.sixiang.license.service.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
......@@ -11,6 +13,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -23,18 +26,22 @@ public class DeviceManager {
private DeviceChannelInitializer channelInitializer;
private TcpServer server = null;
private int port = 18889;
private Map<String, DeviceVo> allDevice = null;
@Autowired
private DeviceService deviceService;
@Autowired
private DeviceServerHandler handler;
public DeviceManager() {
sessionContexts = new HashMap<String, SessionContext>();
allDevice = new HashMap<String, DeviceVo>();
}
@PostConstruct
public void init() {
startTcpService();
initDevices();
}
private void startTcpService() {
......@@ -45,6 +52,23 @@ public class DeviceManager {
server.start();
}
public void initDevices() {
allDevice = new HashMap<>();
PageInfoModel<DeviceVo> records = deviceService.getDeviceList(1, 10000, "", "");
List<DeviceVo> deviceList = records.getResult();
for (DeviceVo deviceVo : deviceList) {
String sn = deviceVo.getSn();
allDevice.put(sn, deviceVo);
}
}
public boolean getContainSn(String sn) {
if (!allDevice.containsKey(sn)) {
return false;
}
return true;
}
public synchronized void putSession(String appId, SessionContext session) {
sessionContexts.put(appId, session);
......
......@@ -12,8 +12,8 @@ import iot.sixiang.license.event.CreateForwarClientEvent;
import iot.sixiang.license.event.DeviceClientInactiveEvent;
import iot.sixiang.license.event.EventPublisher;
import iot.sixiang.license.event.ForwardClientRequestEvent;
import iot.sixiang.license.idreader.Safety;
import iot.sixiang.license.model.SessionContext;
import iot.sixiang.license.util.CommonUtil;
import iot.sixiang.license.util.HexUtil;
import iot.sixiang.license.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
......@@ -29,8 +29,8 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
@Autowired
EventPublisher eventPublisher;
private byte[] obj = new byte[0]; // 特殊的instance变量
@Autowired
Safety safety;
public DeviceServerHandler() {
super();
......@@ -55,11 +55,9 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
*/
byte cmd = protocol.getCmd();
int cmdInt = cmd & 0xFF;
log.debug("real cmd:" + cmdInt);
log.debug("收到的消息:" + HexUtil.bytes2hex(protocol.getContent()));
log.debug("recev msg " + HexUtil.bytes2hex(protocol.getContent()));
boolean license = false;
// cmdInt = Consts.CMD_LICENSE;
if (cmdInt == Consts.CMD_LICENSE) {
license = handlerLicense(channel, remoteIp, remotePort, protocol);
......@@ -156,32 +154,28 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
}
private boolean handlerLicense(SocketChannel channel, String remoteIp, int remotePort, DeviceProtocol protocol) {
// String jsonLicense = new String(protocol.getContent(), 0, protocol.getContent().length);
// JSONObject jsonObject = JSON.parseObject(jsonLicense);
// String userId = jsonObject.getString("userId");
// String password = jsonObject.getString("password");
// String appId = jsonObject.getString("appId");
// String appKey = jsonObject.getString("appKey");
String userId = "123456";
String password = "123456";
String appId = CommonUtil.getStrUUID();
String appKey = "123456";
String token = "123456";
byte[] bytes = safety.decodeExtendedPayload(protocol.getContent(), 0, protocol.getContent().length);
if(bytes==null){
return false;
}
AuthManager authManager = SpringUtil.getBean(AuthManager.class);
// boolean license = authManager.auth(userId, password, appId, appKey);
boolean license = true;
String decodeInfo = new String(bytes, 0, bytes.length);
JSONObject jsonObject = JSON.parseObject(decodeInfo);
String appId = jsonObject.getString("app_id");
String sn = jsonObject.getString("sn");
String sign = jsonObject.getString("sign");
AuthManager authManager = SpringUtil.getBean(AuthManager.class);
boolean license = authManager.auth(appId, sn, sign);
log.debug("auth result " + license + "," + appId + "," + sn + "," + sign);
String channelId = channel.id().asLongText();
if (license) {
SessionContext session = new SessionContext();
session.setRemoteIp(remoteIp);
session.setRemotePort(remotePort);
session.setAppId(appId);
session.setAppKey(appKey);
session.setToken(token);
session.setChannelId(channelId);
session.setClientChannel(channel);
......@@ -210,12 +204,6 @@ public class DeviceServerHandler extends SimpleChannelInboundHandler<Object> {
}
private void handlerForward(SocketChannel channel, String remoteIp, int remotePort, DeviceProtocol protocol) {
// ForwardManager forwardManager = SpringUtil.getBean(ForwardManager.class);
//
// forwardManager.getSessionContexts().getClientChannel().writeAndFlush(protocol);
// Thread.sleep(1000);
String channelId = channel.id().asLongText();
ForwardClientRequestEvent forwardClientRequestEvent = new ForwardClientRequestEvent();
forwardClientRequestEvent.setDeviceChannelId(channelId);
......
......@@ -16,9 +16,6 @@ public class ForwardClient {
@Autowired
ForwardClientHandler handler;
// @Autowired
// ForwardConnectionListener listener;
public ForwardClient() {
log.debug("ProxyNodeClient ProxyNodeClientHandler*****" + handler);
}
......@@ -28,6 +25,8 @@ public class ForwardClient {
ForwardConnectionListener listener = new ForwardConnectionListener();
listener.setAppId(appId);
listener.setHost(host);
listener.setPort(port);
channelInitializer = new ForwardChannelInitializer(handler);
client = new TcpClient(host, port, channelInitializer, listener);
......
......@@ -27,9 +27,6 @@ public class ForwardClientHandler extends SimpleChannelInboundHandler<Object> {
@Autowired
EventPublisher eventPublisher;
private byte[] obj = new byte[0]; // 特殊的instance变量
private String nodeType = "rsretail";
public ForwardClientHandler() {
super();
log.debug("ProxyNodeClientHandler ****");
......@@ -46,8 +43,7 @@ public class ForwardClientHandler extends SimpleChannelInboundHandler<Object> {
int serverPort = socketAddr.getPort();
log.debug("channelRead0...");
DeviceProtocol protocol = (DeviceProtocol) msg;
log.info("桥接服务器响应1"+protocol.toString());
log.info("桥接服务器响应2:"+ HexUtil.bytes2hex(protocol.getContent()));
log.info("桥接服务器响应:"+ HexUtil.bytes2hex(protocol.getContent()));
String channelId = channel.id().asLongText();
......@@ -80,19 +76,6 @@ public class ForwardClientHandler extends SimpleChannelInboundHandler<Object> {
try {
SocketChannel channel = (SocketChannel) ctx.channel();
log.debug("channelActive********"+ctx.channel().id().asLongText());
// InetSocketAddress socketAddr = (InetSocketAddress) ctx.channel().remoteAddress();
// String clientIp = socketAddr.getHostString();
// int port = socketAddr.getPort();
//
// SessionContext session = new SessionContext();
// session.setRemoteIp(clientIp);
// session.setRemotePort(port);
// session.setClientChannel(channel);
//
// ForwardManager forwardManager = SpringUtil.getBean(ForwardManager.class);
// log.debug("channelActive.getClientChannel:" + channel);
// forwardManager.setSessionContexts(session);
} catch (Exception e) {
// TODO Auto-generated catch block
......
......@@ -12,42 +12,38 @@ import iot.sixiang.license.operate.OperateManager;
import iot.sixiang.license.service.AlarmService;
import iot.sixiang.license.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.net.InetSocketAddress;
@Slf4j
public class ForwardConnectionListener extends BaseConnectionListener {
@Autowired
private AlarmService alarmService;
@Autowired
private OperateManager operateManager;
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
AlarmService alarmService = SpringUtil.getBean(AlarmService.class);
if (!channelFuture.isSuccess()) {
//TODO 失败进行告警
InetSocketAddress socketAddress = (InetSocketAddress)channelFuture.channel().remoteAddress();
String remoteIp = socketAddress.getHostString();
String remotePort = String.valueOf(socketAddress.getPort());
String remoteIp = this.host;
String remotePort = String.valueOf(this.port);
int typeId = 1;
String title = "连接服器失败";
String content = "连接服务器:" + remoteIp + ":"+ remotePort +"失败";
alarmService.addAlarm(typeId,title,content);
//TODO forward client连接失败,则强制踢掉设备客户端
DeviceClientBeForcedOfflineEvent deviceClientBeForcedOfflineEvent = new DeviceClientBeForcedOfflineEvent();
deviceClientBeForcedOfflineEvent.setAppId(appId);
deviceClientBeForcedOfflineEvent.setAppId(this.appId);
EventPublisher eventPublisher = SpringUtil.getBean(EventPublisher.class);
eventPublisher.publishEvent(deviceClientBeForcedOfflineEvent);
} else {
OperateManager operateManager = SpringUtil.getBean(OperateManager.class);
operateManager.autoIncrement();
SocketChannel channel = (SocketChannel) channelFuture.channel();
String channelId = channel.id().asLongText();
ForwardClientConnectEvent forwardClientConnectEvent = new ForwardClientConnectEvent();
forwardClientConnectEvent.setAppId(appId);
forwardClientConnectEvent.setAppId(this.appId);
forwardClientConnectEvent.setChannelId(channelId);
forwardClientConnectEvent.setChannel(channel);
......
package iot.sixiang.license.idreader;
import lombok.Data;
import org.springframework.stereotype.Component;
@Component
public class Safety {
static {
System.loadLibrary("IdReaderSafetyLib");
}
public native byte[] decodeExtendedPayload(byte[] data, int offset, int length);
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ import lombok.Data;
public class BaseConnectionListener implements ChannelFutureListener {
public String appId;
public String host;
public int port;
@Override
public void operationComplete(ChannelFuture future) throws Exception {
// TODO Auto-generated method stub
......
package iot.sixiang.license.operate;
import iot.sixiang.license.forward.ForwardChannelInitializer;
import iot.sixiang.license.forward.ForwardConnectionListener;
import iot.sixiang.license.net.TcpClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -26,7 +24,8 @@ public class OperateClient {
public void startTcp(String host, int port) {
OperateConnectionListener listener = new OperateConnectionListener();
listener.setHost(host);
listener.setPort(port);
channelInitializer = new OperateChannelInitializer(handler);
client = new TcpClient(host, port, channelInitializer, listener);
client.start();
......
......@@ -9,23 +9,17 @@ import iot.sixiang.license.net.BaseConnectionListener;
import iot.sixiang.license.service.AlarmService;
import iot.sixiang.license.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import java.net.InetSocketAddress;
@Slf4j
public class OperateConnectionListener extends BaseConnectionListener {
@Autowired
private AlarmService alarmService;
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (!channelFuture.isSuccess()) {
//TODO 失败进行告警
InetSocketAddress socketAddress = (InetSocketAddress)channelFuture.channel().remoteAddress();
String remoteIp = socketAddress.getHostString();
String remotePort = String.valueOf(socketAddress.getPort());
AlarmService alarmService = SpringUtil.getBean(AlarmService.class);
String remoteIp = this.host;
String remotePort = String.valueOf(this.port);
int typeId = 1;
String title = "连接服器失败";
String content = "连接服务器:" + remoteIp + ":"+ remotePort +"失败";
......
package iot.sixiang.license.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import iot.sixiang.license.auth.AuthManager;
import iot.sixiang.license.entity.Apply;
import iot.sixiang.license.handler.IotLicenseException;
import iot.sixiang.license.mapper.ApplyMapper;
import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.vo.AppVo;
import iot.sixiang.license.service.ApplyService;
import iot.sixiang.license.util.SpringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
......@@ -29,7 +31,6 @@ public class ApplyServiceImpl extends ServiceImpl<ApplyMapper, Apply> implements
@Resource
ApplyMapper applyMapper;
@Override
public boolean addApply(String appName, String appKey, int userId) {
if(StringUtils.isEmpty(appName)) {
......@@ -45,7 +46,13 @@ public class ApplyServiceImpl extends ServiceImpl<ApplyMapper, Apply> implements
if (res != null) {
throw new IotLicenseException(400,"应用名已存在");
}
return applyMapper.addApply(appName,appKey,userId);
boolean re = applyMapper.addApply(appName, appKey, userId);
if (!re) {
return false;
}
AuthManager authManager = SpringUtil.getBean(AuthManager.class);
authManager.initApps();
return true;
}
@Override
......
package iot.sixiang.license.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import iot.sixiang.license.device.DeviceManager;
import iot.sixiang.license.entity.Device;
import iot.sixiang.license.handler.IotLicenseException;
import iot.sixiang.license.mapper.DeviceMapper;
......@@ -8,6 +9,7 @@ import iot.sixiang.license.model.PageInfoModel;
import iot.sixiang.license.model.vo.DeviceVo;
import iot.sixiang.license.service.DeviceService;
import iot.sixiang.license.util.CommonUtil;
import iot.sixiang.license.util.SpringUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
......@@ -61,11 +63,13 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
}
for (int i = 0; i < count; i++) {
String sn = CommonUtil.genRandomNum(18);
boolean res = deviceMapper.addDevice(sn,appId);
boolean res = deviceMapper.addDevice(sn, appId);
if (!res) {
return false;
}
}
DeviceManager deviceManager = SpringUtil.getBean(DeviceManager.class);
deviceManager.initDevices();
return true;
}
}
package iot.sixiang.license.util;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HmacUtil {
//加密算法
public static final String HMAC_SHA1 = "HmacSHA1";
public static final String HMAC_MD5 = "HmacMD5";
public static final String HMAC_SHA256 = "HmacSHA256";
public static final String HMAC_SHA512 = "HmacSHA512";
/**
* 实现Hmac系列的加密算法HmacSHA1、HmacMD5等
*
* @param input 需要加密的输入参数
* @param key 密钥
* @param algorithm 选择加密算法
* @return 加密后的值
**/
public static String encrypt(String input, String key, String algorithm) {
String cipher = "";
try {
byte[] data = key.getBytes(StandardCharsets.UTF_8);
//根据给定的字节数组构造一个密钥,第二个参数指定一个密钥的算法名称,生成HmacSHA1专属密钥
SecretKey secretKey = new SecretKeySpec(data, algorithm);
//生成一个指定Mac算法的Mac对象
Mac mac = Mac.getInstance(algorithm);
//用给定密钥初始化Mac对象
mac.init(secretKey);
byte[] text = input.getBytes(StandardCharsets.UTF_8);
byte[] encryptByte = mac.doFinal(text);
cipher = bytesToHexStr(encryptByte);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
return cipher;
}
public static String getSha1(String str) {
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f'};
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char buf[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
buf[k++] = hexDigits[byte0 & 0xf];
}
return new String(buf);
} catch (Exception e) {
return null;
}
}
/**
* byte数组转16进制字符串
*
* @param bytes byte数组
* @return hex字符串
*/
public static String bytesToHexStr(byte[] bytes) {
StringBuilder hexStr = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
hexStr.append(hex);
}
return hexStr.toString();
}
public static String getSha1_1(String input) {
String mySignature;
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
md.update(input.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
mySignature = hexstr.toString();
} catch (NoSuchAlgorithmException e) {
return "签名验证错误";
}
return mySignature;
}
}
\ No newline at end of file
spring:
profiles:
active: dev
active: test
application:
name: iot_license #当前服务的名称
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment