提交 e5b90f21 编写于 作者: 麦壳饼's avatar 麦壳饼

加入 全局授权Key

上级 36688a88
......@@ -55,8 +55,7 @@ namespace IoTSharp.Controllers
{
var user = await _userManager.GetUserAsync(User);
var rooles = await _userManager.GetRolesAsync(user);
string custid = User.FindFirstValue(IoTSharpClaimTypes.Customer);
var Customer = _context.Customer.Include(c=>c.Tenant).FirstOrDefault(c => c.Id.ToString() == custid);
var Customer = _context.GetCustomer(this.GetCustomerId());
var uidto = new UserInfoDto()
{
Code = ApiCode.Success,
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using IoTSharp.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using IoTSharp.Dtos;
namespace IoTSharp.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthorizedKeysController : ControllerBase
{
private readonly ApplicationDbContext _context;
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger _logger;
private readonly string _customerId;
public AuthorizedKeysController(UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager, ILogger<AuthorizedKeysController> logger, ApplicationDbContext context)
{
_context = context;
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_customerId = this.GetCustomerId();
}
// GET: api/AuthorizedKeys
[HttpGet]
public async Task<ActionResult<IEnumerable<AuthorizedKey>>> GetAuthorizedKeys()
{
return await _context.AuthorizedKeys.JustCustomer(_customerId).ToListAsync();
}
// GET: api/AuthorizedKeys/5
[HttpGet("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult<AuthorizedKey>> GetAuthorizedKey(Guid id)
{
var authorizedKey = await _context.AuthorizedKeys.JustCustomer(_customerId).FirstOrDefaultAsync(ak=>ak.Id== id);
if (authorizedKey == null)
{
return NotFound();
}
return authorizedKey;
}
// PUT: api/AuthorizedKeys/5
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPut("{id}")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<IActionResult> PutAuthorizedKey(Guid id, AuthorizedKey authorizedKey)
{
if (id != authorizedKey.Id)
{
return BadRequest();
}
if (!AuthorizedKeyExists(id))
{
return NotFound();
}
_context.Entry(authorizedKey).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AuthorizedKeyExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
// POST: api/AuthorizedKeys
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesDefaultResponseType]
public async Task<ActionResult<AuthorizedKey>> PostAuthorizedKey(AuthorizedKeyDto dto)
{
var authorizedKey = new AuthorizedKey() { Name = dto.Name, AuthToken = dto.AuthToken };
authorizedKey.Id = Guid.NewGuid();
_context.JustFill(this, authorizedKey);
if (authorizedKey.Tenant == null || authorizedKey.Customer == null)
{
return NotFound(new ApiResult<AuthorizedKey>(ApiCode.NotFoundTenantOrCustomer, $"Not found Tenant or Customer ", authorizedKey));
}
_context.AuthorizedKeys.Add(authorizedKey);
await _context.SaveChangesAsync();
return CreatedAtAction("GetAuthorizedKey", new { id = authorizedKey.Id }, authorizedKey);
}
// DELETE: api/AuthorizedKeys/5
[HttpDelete("{id}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult<AuthorizedKey>> DeleteAuthorizedKey(Guid id)
{
var authorizedKey = await _context.AuthorizedKeys.JustCustomer(_customerId).FirstOrDefaultAsync(ak=>ak.Id== id);
if (authorizedKey == null)
{
return NotFound();
}
_context.AuthorizedKeys.Remove(authorizedKey);
await _context.SaveChangesAsync();
return authorizedKey;
}
private bool AuthorizedKeyExists(Guid id)
{
return _context.AuthorizedKeys.JustCustomer(_customerId).Any(e => e.Id == id);
}
}
}
......@@ -16,6 +16,8 @@ using MQTTnet.Protocol;
using IoTSharp.Extensions;
using MQTTnet.Exceptions;
using MQTTnet.Client.Options;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
namespace IoTSharp.Controllers
{
......@@ -26,11 +28,18 @@ namespace IoTSharp.Controllers
{
private readonly ApplicationDbContext _context;
private readonly IMqttClientOptions _mqtt;
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger _logger;
public DevicesController(ApplicationDbContext context, IMqttClientOptions mqtt)
public DevicesController(UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager, ILogger<DevicesController> logger, ApplicationDbContext context, IMqttClientOptions mqtt)
{
_context = context;
_mqtt = mqtt;
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
/// <summary>
......
......@@ -101,5 +101,8 @@ namespace IoTSharp.Data
public DbSet<AuditLog> AuditLog { get; set; }
public DbSet<RetainedMessage> RetainedMessage { get; set; }
public DbSet<AuthorizedKey> AuthorizedKeys { get; set; }
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Data
{
public class AuthorizedKey: IJustMy
{
[Key]
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; }
public string AuthToken { get; set; }
[Newtonsoft.Json.JsonIgnore]
public Tenant Tenant { get; set; }
[Newtonsoft.Json.JsonIgnore]
public Customer Customer { get; set; }
[Newtonsoft.Json.JsonIgnore]
public List<Device> Devices { get; set; }
}
}
using IoTSharp.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Data
{
public interface IJustMy
{
public Customer Customer { get; set; }
public Tenant Tenant { get; set; }
}
}
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace IoTSharp.Migrations
{
public partial class addAuthorizedKey : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "AuthorizedKeyId",
table: "Device",
nullable: true);
migrationBuilder.AlterColumn<int>(
name: "Id",
table: "AspNetUserClaims",
nullable: false,
oldClrType: typeof(int))
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
migrationBuilder.AlterColumn<int>(
name: "Id",
table: "AspNetRoleClaims",
nullable: false,
oldClrType: typeof(int))
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn);
migrationBuilder.CreateTable(
name: "AuthorizedKeys",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Name = table.Column<string>(nullable: true),
AuthToken = table.Column<string>(nullable: true),
TenantId = table.Column<Guid>(nullable: true),
CustomerId = table.Column<Guid>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AuthorizedKeys", x => x.Id);
table.ForeignKey(
name: "FK_AuthorizedKeys_Customer_CustomerId",
column: x => x.CustomerId,
principalTable: "Customer",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_AuthorizedKeys_Tenant_TenantId",
column: x => x.TenantId,
principalTable: "Tenant",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_Device_AuthorizedKeyId",
table: "Device",
column: "AuthorizedKeyId");
migrationBuilder.CreateIndex(
name: "IX_AuthorizedKeys_CustomerId",
table: "AuthorizedKeys",
column: "CustomerId");
migrationBuilder.CreateIndex(
name: "IX_AuthorizedKeys_TenantId",
table: "AuthorizedKeys",
column: "TenantId");
migrationBuilder.AddForeignKey(
name: "FK_Device_AuthorizedKeys_AuthorizedKeyId",
table: "Device",
column: "AuthorizedKeyId",
principalTable: "AuthorizedKeys",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Device_AuthorizedKeys_AuthorizedKeyId",
table: "Device");
migrationBuilder.DropTable(
name: "AuthorizedKeys");
migrationBuilder.DropIndex(
name: "IX_Device_AuthorizedKeyId",
table: "Device");
migrationBuilder.DropColumn(
name: "AuthorizedKeyId",
table: "Device");
migrationBuilder.AlterColumn<int>(
name: "Id",
table: "AspNetUserClaims",
nullable: false,
oldClrType: typeof(int))
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
migrationBuilder.AlterColumn<int>(
name: "Id",
table: "AspNetRoleClaims",
nullable: false,
oldClrType: typeof(int))
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace IoTSharp.Dtos
{
public class AuthorizedKeyDto
{
public string Name { get; set; }
public string AuthToken { get; set; }
}
}
......@@ -32,5 +32,25 @@ namespace IoTSharp.Extensions
_context.PreparingData<AttributeLatest, AttributeData>(pairs, device, DataSide.ServerSide);
}
}
public static void AfterCreateDevice(this ApplicationDbContext _context, Device device,string username,string password)
{
if (device.Customer == null || device.Tenant == null || string.IsNullOrEmpty(device.Name))
{
throw new Exception("Customer or Tenant or Name is null or empty!");
}
else
{
_context.DeviceIdentities.Add(new DeviceIdentity()
{
Device = device,
IdentityType = IdentityType.DevicePassword,
IdentityId = username,
IdentityValue = password
}) ;
Dictionary<string, object> pairs = new Dictionary<string, object>();
pairs.Add("CreateDateTime", DateTime.Now);
_context.PreparingData<AttributeLatest, AttributeData>(pairs, device, DataSide.ServerSide);
}
}
}
}
using IoTSharp.Data;
using IoTSharp.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
......@@ -12,6 +14,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Claims;
using System.Text;
namespace IoTSharp
......@@ -19,7 +22,41 @@ namespace IoTSharp
public static class IoTSharpExtension
{
public static void JustFill<T>(this ApplicationDbContext _context, ControllerBase controller, T ak) where T : class, IJustMy
{
var cid = controller.User.Claims.First(c => c.Type == IoTSharpClaimTypes.Customer);
var tid = controller. User.Claims.First(c => c.Type == IoTSharpClaimTypes.Tenant);
ak.Tenant = _context.Tenant.Find(new Guid(tid.Value));
ak.Customer = _context.Customer.Find(new Guid(cid.Value));
}
public static IQueryable<T> JustCustomer<T>(this DbSet<T> ts, ControllerBase controller) where T : class, IJustMy
=> JustCustomer(ts, GetCustomerId(controller));
public static IQueryable<T> JustCustomer<T>(this DbSet<T> ts, string _customerId) where T : class, IJustMy
{
return ts.Include(ak => ak.Customer).Where(ak => ak.Customer.Id.ToString() == _customerId);
}
public static IQueryable<T> JustTenant<T>(this DbSet<T> ts, ControllerBase controller) where T : class, IJustMy
=> JustTenant(ts, GetTenantId(controller));
public static IQueryable<T> JustTenant<T>(this DbSet<T> ts, string _tenantId) where T : class, IJustMy
{
return ts.Include(ak => ak.Tenant).Where(ak => ak.Tenant.Id.ToString() == _tenantId);
}
public static Customer GetCustomer(this ApplicationDbContext context, string custid)
=> context.Customer.Include(c => c.Tenant).FirstOrDefault(c => c.Id.ToString() == custid);
public static string GetCustomerId(this ControllerBase controller)
{
string custid = controller.User?.FindFirstValue(IoTSharpClaimTypes.Customer);
return custid;
}
public static string GetTenantId(this ControllerBase controller)
{
string custid = controller.User.FindFirstValue(IoTSharpClaimTypes.Tenant);
return custid;
}
public static IHostBuilder ConfigureIoTSharpHost(this IHostBuilder hostBuilder)
{
hostBuilder.ConfigureServices(services =>
......
......@@ -364,8 +364,37 @@ namespace IoTSharp.Handlers
obj.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.ServerUnavailable;
}
}
else
else if (_dbContextcv.AuthorizedKeys.Any(ak=>ak.AuthToken==obj.Password))
{
var ak = _dbContextcv.AuthorizedKeys.Include(ak => ak.Customer).Include(ak => ak.Tenant).Include(ak => ak.Devices).First(ak => ak.AuthToken == obj.Password);
if (!ak.Devices.Any(dev => dev.Name == obj.Username))
{
var devvalue = new Device() { Name = obj.Username, DeviceType = DeviceType.Device };
devvalue.Tenant = ak.Tenant;
devvalue.Customer = ak.Customer;
_dbContextcv.Device.Add(devvalue);
ak.Devices.Add(devvalue);
_dbContextcv.AfterCreateDevice(devvalue,obj.Username,obj.Password);
_dbContextcv.SaveChanges();
}
var mcp = _dbContextcv.DeviceIdentities.Include(d => d.Device).FirstOrDefault(mc => mc.IdentityType == IdentityType.DevicePassword && mc.IdentityId == obj.Username && mc.IdentityValue == obj.Password);
if (mcp != null)
{
if (!Devices.ContainsKey(e.Context.ClientId))
{
Devices.Add(e.Context.ClientId, mcp.Device);
}
obj.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.Success;
}
else
{
obj.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
}
}
else
{
obj.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
_logger.LogInformation($"Bad username or password {obj.Username},connection {obj.Endpoint} refused");
}
......
......@@ -55,17 +55,24 @@
<PackageReference Include="kimbus" Version="2.0.1" />
<PackageReference Include="LiteDB" Version="5.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.3" />
<PackageReference Include="MQTTnet" Version="3.0.12-rc1" />
<PackageReference Include="MQTTnet.AspNetCore" Version="3.0.12-rc1" />
<PackageReference Include="MQTTnet.Extensions.Rpc" Version="3.0.12-rc1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
<PackageReference Include="NSwag.AspNetCore" Version="13.6.1" />
<PackageReference Include="ProxyKit" Version="2.3.3" />
<PackageReference Include="Silkier" Version="1.0.121" />
<PackageReference Include="Silkier.AspNetCore" Version="1.0.121" />
<PackageReference Include="Silkier.EFCore" Version="1.0.121" />
<PackageReference Include="SilkierQuartz" Version="1.0.21" />
<PackageReference Include="SilkierQuartz" Version="1.0.46" />
<PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.1" />
<PackageReference Include="CoAP.NET.Core" Version="1.1.0" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册