设备和程序绑定

Former-commit-id: 7b99ecd8268ec890e4016f4d2ab657fd7b010204
TangShanKaiPing
wanggang 6 years ago
parent c26a182578
commit 8a96097cbb

@ -0,0 +1,75 @@
using System.Collections.Generic;
using System.Text;
namespace Infrastructure.Extensions
{
public static class Base62Extensions
{
private static string characterSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static string Base62Encode(this string value)
{
var arr = Encoding.UTF8.GetBytes(value);
return Base62Encode(arr);
}
public static string Base62Decode(this string value)
{
var arr = new byte[value.Length];
for (var i = 0; i < arr.Length; i++)
{
arr[i] = (byte)characterSet.IndexOf(value[i]);
}
return Base62Decode(arr);
}
public static string Base62Encode(this byte[] value)
{
var converted = BaseConvert(value, 256, 62);
var builder = new StringBuilder();
for (var i = 0; i < converted.Length; i++)
{
builder.Append(characterSet[converted[i]]);
}
return builder.ToString();
}
public static string Base62Decode(this byte[] value)
{
var converted = BaseConvert(value, 62, 256);
return Encoding.UTF8.GetString(converted, 0, converted.Length);
}
private static byte[] BaseConvert(byte[] source, int sourceBase, int targetBase)
{
var result = new List<int>();
int count = 0;
while ((count = source.Length) > 0)
{
var quotient = new List<byte>();
int remainder = 0;
for (var i = 0; i != count; i++)
{
int accumulator = source[i] + remainder * sourceBase;
byte digit = System.Convert.ToByte((accumulator - (accumulator % targetBase)) / targetBase);
remainder = accumulator % targetBase;
if (quotient.Count > 0 || digit != 0)
{
quotient.Add(digit);
}
}
result.Insert(0, remainder);
source = quotient.ToArray();
}
var output = new byte[result.Count];
for (int i = 0; i < result.Count; i++)
output[i] = (byte)result[i];
return output;
}
}
}

@ -6,7 +6,7 @@ namespace Infrastructure.Extensions
{
public static long ToUnixTimeMilliseconds(this DateTime dateTime)
{
return new DateTimeOffset().ToUnixTimeMilliseconds();
return new DateTimeOffset(dateTime).ToUnixTimeMilliseconds();
}
public static DateTime FromUnixTimeMilliseconds(this string timestrap)

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -6,6 +7,8 @@ using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace Infrastructure.Extensions

@ -18,7 +18,9 @@ namespace Infrastructure.Extensions
{
var hex = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
}

@ -1,7 +1,8 @@
using HtmlAgilityPack;
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using HtmlAgilityPack;
namespace Infrastructure.Extensions
{
@ -58,5 +59,53 @@ namespace Infrastructure.Extensions
{
return Enumerable.Range(0, hex.Length / 2).Select(x => Convert.ToByte(hex.Substring(x * 2, 2), 16)).ToArray();
}
public static string DESEncrypt(this string value, string key)
{
using (var des = new DESCryptoServiceProvider())
{
var inputByteArray = Encoding.Default.GetBytes(value);
var md5Key = key.Md5().Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(md5Key);
des.IV = ASCIIEncoding.ASCII.GetBytes(md5Key);
using (var ms = new System.IO.MemoryStream())
{
using (var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
var ret = new StringBuilder();
foreach (var item in ms.ToArray())
{
ret.AppendFormat("{0:X2}", item);
}
return ret.ToString();
}
}
}
}
public static string DESDecrypt(this string value, string key)
{
using (var des = new DESCryptoServiceProvider())
{
var len = value.Length / 2;
byte[] inputByteArray = new byte[len];
for (int i = 0; i < len; i++)
{
inputByteArray[i] = (byte)Convert.ToInt32(value.Substring(i * 2, 2), 16);
}
var md5Key = key.Md5().Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(md5Key);
des.IV = ASCIIEncoding.ASCII.GetBytes(md5Key);
using (var ms = new System.IO.MemoryStream())
{
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
}
}
}
}

@ -1,22 +1,19 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Infrastructure.Extensions;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Security.Cryptography;
using System.Text;
namespace Infrastructure.Security
{
public class EncryptionService : IEncryptionService
{
private readonly string _key;
private readonly string _iv;
private readonly IConfiguration _configuration;
public EncryptionService(IConfiguration configuration)
{
this._key = configuration.GetSection("security").GetValue<string>("key");
this._iv = configuration.GetSection("security").GetValue<string>("iv");
this._configuration = configuration;
}
public string CreatePasswordHash(string password, string saltkey)
@ -52,35 +49,12 @@ namespace Infrastructure.Security
public string EncryptObject(object obj)
{
var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(obj));
var key = Encoding.UTF8.GetBytes(this._key);
var iv = Encoding.UTF8.GetBytes(this._iv);
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, TripleDES.Create().CreateEncryptor(key, iv), CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
}
return ms.ToArray().BytesToHex();
}
return JsonConvert.SerializeObject(obj).DESEncrypt(this._configuration.GetSection("security").GetValue<string>("key"));
}
public T DecryptObject<T>(string value)
{
var data = value.HexToBytes();
var key = Encoding.UTF8.GetBytes(this._key);
var iv = Encoding.UTF8.GetBytes(this._iv);
using (var ms = new MemoryStream(data))
{
using (var cs = new CryptoStream(ms, TripleDES.Create().CreateDecryptor(key, iv), CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs, Encoding.UTF8))
{
return JsonConvert.DeserializeObject<T>(sr.ReadToEnd());
}
}
}
return JsonConvert.DeserializeObject<T>(value.DESDecrypt(this._configuration.GetSection("security").GetValue<string>("key")));
}
}
}

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Infrastructure.Web
{
@ -17,18 +18,60 @@ namespace Infrastructure.Web
public override void OnResultExecuting(ResultExecutingContext context)
{
var config = context.HttpContext.RequestServices.GetService<IConfiguration>();
if (config["id"] != DeviceId.Md5().Base64UrlEncode().Md5())
var result = true;
var message = "";
var sn = DeviceId;
try
{
if (!context.HttpContext.Request.Path.Value.StartsWith("/App/"))
var config = context.HttpContext.RequestServices.GetService<IConfiguration>();
var hashCode = config["code"];
var code = hashCode.DESDecrypt(sn);
var values = code.Split('-');
if (sn != values[0])
{
context.Result = new RedirectResult("/Admin/Configuration");
message = $"授权码不匹配当前设备{sn}";
result = false;
}
else
{
context.Result = new JsonResult($"设备{DeviceId}的授权码\"{config["id"]}\"异常");
var timeSeconds = Convert.ToInt64(values[1]);
if (timeSeconds != 0)
{
var endTime = DateTimeOffset.FromUnixTimeSeconds(timeSeconds);
if (endTime < DateTimeOffset.UtcNow)
{
message = $"当前设备{sn}的授权码已过期";
result = false;
}
}
}
}
catch (Exception ex)
{
ex.PrintStack();
message = $"当前设备{sn}的授权码无效";
result = false;
}
if (!result)
{
if (context.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
context.Result = new JsonResult(new { code = 1, message = message });
}
else
{
var queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);
queryString["message"] = message;
queryString["returnUrl"] = "/Admin/Configuration";
var url = $"/Admin/Configuration/RedirectTo?{queryString.ToString()}";
context.Result = new RedirectResult(url);
}
}
}
private string GetCode(string deviceId)
{
return DeviceId.Base64UrlEncode().Md5();
}
}
}

@ -11,7 +11,7 @@ namespace Infrastructure.Web
public IActionResult RedirectTo(string action = "Index", string controller = null, string message = "操作成功,正在为您跳转", object routeValues = null, string returnUrl = null)
{
ViewBag.Message = message;
ViewBag.Url = string.IsNullOrEmpty(returnUrl) ? Url.Action(action, controller, routeValues) : returnUrl;
ViewBag.Url = string.IsNullOrEmpty(returnUrl) ? Url.Action("Index", controller, routeValues) : returnUrl;
return View("Redirect");
}

@ -7,20 +7,28 @@ namespace IdGen
{
private static void Main(string[] args)
{
if (args.Length > 0)
{
Console.WriteLine(args[0].Md5().Base64UrlEncode().Md5());
}
Console.WriteLine("物联网设备程序授权码生成工具:");
var message = "请输入以空格分隔的设备编号、有效天数有效天数为0则不限制使用期限";
Console.WriteLine(message);
while (true)
{
var input = Console.ReadLine();
if (input == "q")
try
{
break;
if (input == "q")
{
break;
}
var values = input.Split(' ');
var sn = values[0];
var days = Convert.ToInt32(values[1]);
var endTime = days == 0 ? 0 : new DateTimeOffset(DateTime.UtcNow.Date.AddDays(days + 1).AddSeconds(-1)).ToUnixTimeMilliseconds();
Console.WriteLine($"{sn}-{endTime}".DESEncrypt(sn));
}
else
catch (Exception ex)
{
Console.WriteLine(input.Md5().Base64UrlEncode().Md5());
Console.WriteLine(ex.Message);
Console.WriteLine(message);
}
}
}

@ -176,7 +176,7 @@ namespace IoT.Shared.DeviceServices.FBee
ProductId = product.Id,
NodeId = node.Id,
};
device.ConnectId = this._configuration["connectId"];
device.ConnectId = this._configuration["sn"];
deviceRepo.Add(device);
}
device.Ip = ip;
@ -546,7 +546,7 @@ namespace IoT.Shared.DeviceServices.FBee
}
}
device.IsOnline = isOnline != 0x00;
device.ConnectId = this._configuration["connectId"];
device.ConnectId = this._configuration["sn"];
device.AddorUpdateData(device.CreateData(Keys.DeviceId, deviceId, DeviceDataType.Int, Keys.DeviceId, hidden: true));
device.AddorUpdateData(device.CreateData(Keys.Address, address, DeviceDataType.String, Keys.Address, hidden: true));

@ -142,7 +142,7 @@ namespace IoT.Shared.DeviceServices.Onvif
device.AddorUpdateData(device.CreateData("subrtmp", $"rtmp://{this._configuration["stream.rtmp"]}/live/sub{ipCamera.Id}", DeviceDataType.String, "子码流rtmp"));
device.AddorUpdateData(device.CreateData("subflv", $"http://{this._configuration["stream.flv"]}/live/sub{ipCamera.Id}.flv", DeviceDataType.String, "子码流flv"));
device.AddorUpdateData(device.CreateData("subhls", $"http://{this._configuration["stream.hls"]}/live/sub{ipCamera.Id}.m3u8", DeviceDataType.String, "子码流hls"));
device.ConnectId = this._configuration["connectId"];
device.ConnectId = this._configuration["sn"];
deviceRepo.Add(device);
deviceRepo.SaveChanges();
}

@ -114,7 +114,7 @@ namespace IoT.Shared.Infrastructure
private void InitConnection()
{
this._notifyHost = this._cfg["notify:host"];
var url = $"http://{this._notifyHost}/hub?group={this._cfg["connectId"]}";
var url = $"http://{this._notifyHost}/hub?group={this._cfg["sn"]}";
if (this.Connection != null)
{
this.Connection.DisposeAsync();

@ -81,7 +81,7 @@ namespace IoT.Shared.Infrastructure
{
if (method == Methods.HealthCheckRequest)
{
this.ClientToServer(Methods.HealthCheckResponse, this._cfg["node.number"]);
this.ClientToServer(Methods.HealthCheckResponse, this._cfg["sn"]);
}
else if (method == Methods.GetProductRequest)
{
@ -103,7 +103,7 @@ namespace IoT.Shared.Infrastructure
var url = $"http://localhost:{port}{message}";
var httpClient = scope.ServiceProvider.GetService<IHttpClientFactory>().CreateClient();
var result = httpClient.GetStringAsync(url).Result;
this.Connection.SendAsync(Methods.ClientToServer, Methods.ApiCallback, result, cfg["connectId"]);
this.Connection.SendAsync(Methods.ClientToServer, Methods.ApiCallback, result, cfg["sn"]);
}
else if (method == Methods.CallScene)
{

@ -15,14 +15,15 @@ namespace IoTNode
Console.OutputEncoding = System.Text.Encoding.UTF8;
var host = "localhost";
var stream = "192.168.3.124";
var cpuNumber = Helper.Instance.GetCPUNumber();
WebHost.CreateDefaultBuilder(args)
.Run<Startup>(new List<EFConfigurationValue> {
new EFConfigurationValue { Id = "id", Value= "根据设备编号生成的授权码" },
new EFConfigurationValue { Id = "sn", Value= cpuNumber },
new EFConfigurationValue { Id = "code", Value= "根据设备编号生成的授权码" },
new EFConfigurationValue { Id = "openapi.name", Value= "v1" },
new EFConfigurationValue { Id = "openapi.title", Value= "fbee api" },
new EFConfigurationValue { Id = "openapi.version", Value= "1.0" },
new EFConfigurationValue { Id = "security:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "security:iv", Value= "11111111"},
new EFConfigurationValue { Id = "jwt:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "email:host", Value= "nbaxp.com"},
new EFConfigurationValue { Id = "email:port", Value= "25"},
@ -33,8 +34,6 @@ namespace IoTNode
new EFConfigurationValue { Id = "notify:enabled", Value= "true"},
new EFConfigurationValue { Id = "notify:host", Value= $"{host}:8001"},
new EFConfigurationValue { Id = "timer.seconds", Value="60"},
new EFConfigurationValue { Id = "connectId", Value= Helper.Instance.GetCPUNumber() },
new EFConfigurationValue { Id = "node.number", Value= Helper.Instance.GetCPUNumber() },
new EFConfigurationValue { Id = "influxdb:url", Value= "http://localhost:8086"},
new EFConfigurationValue { Id = "influxdb:usr", Value= "admin"},
new EFConfigurationValue { Id = "influxdb:pwd", Value= "admin"},

@ -2,6 +2,7 @@ using Application.Domain.Entities;
using Infrastructure.Data;
using Infrastructure.Domain;
using Infrastructure.Extensions;
using Infrastructure.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
@ -42,7 +43,7 @@ namespace IoTCenter.Controllers
this._eventPublisher = eventPublisher;
}
[Authorize]
[Authorize, Device]
public IActionResult Index()
{
//this._eventPublisher.Publish(new EntityInsertedEvent<Node>(new Node()));

@ -1,5 +1,6 @@
using Infrastructure.Application;
using Infrastructure.Configuration;
using Infrastructure.Extensions;
using Infrastructure.Web.Hosting;
using Microsoft.AspNetCore;
using System;
@ -13,14 +14,16 @@ namespace IoTCenter
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
var host = "localhost";
var cpuNumber = Helper.Instance.GetCPUNumber();
WebHost.CreateDefaultBuilder(args)
.Run<Startup>(new List<EFConfigurationValue> {
new EFConfigurationValue { Id = "sn", Value= cpuNumber },
new EFConfigurationValue { Id = "code", Value= "根据设备编号生成的授权码" },
new EFConfigurationValue { Id = "openapi.name", Value= "v1" },
new EFConfigurationValue { Id = "openapi.title", Value= "web api" },
new EFConfigurationValue { Id = "openapi.version", Value= "1.0" },
new EFConfigurationValue { Id = "server.urls", Value= "http://*:8001" },
new EFConfigurationValue { Id = "security:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "security:iv", Value= "11111111"},
new EFConfigurationValue { Id = "jwt:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "usercenter:key", Value= "123456"},
new EFConfigurationValue { Id = "usercenter:login", Value= $"http://{host}:8000/Account/Login"},

@ -17,7 +17,6 @@ namespace UserCenter
new EFConfigurationValue { Id = "openapi.version", Value= "1.0" },
new EFConfigurationValue { Id = "server.urls", Value= "http://*:8000" },
new EFConfigurationValue { Id = "security:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "security:iv", Value= "11111111"},
new EFConfigurationValue { Id = "jwt:key", Value= "111111111111111111111111"},
new EFConfigurationValue { Id = "email:host", Value= "nbaxp.com"},
new EFConfigurationValue { Id = "email:port", Value= "25"},

Loading…
Cancel
Save