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

add role , redefine install api

上级 84bacfac
using IoTSharp.Hub.Data; using IoTSharp.Hub.Data;
using IoTSharp.Hub.Extensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
...@@ -41,27 +44,35 @@ namespace IoTSharp.Hub.Controllers ...@@ -41,27 +44,35 @@ namespace IoTSharp.Hub.Controllers
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public async Task<IActionResult> Login([FromBody] LoginDto model) public async Task<ActionResult<LoginResult>> Login([FromBody] LoginDto model)
{ {
IActionResult actionResult = NoContent();
try try
{ {
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false); var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
if (result.Succeeded) if (result.Succeeded)
{ {
var appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email); var appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);
actionResult = Ok(new { code = 0, msg = "OK", data = GenerateJwtToken(model.Email, appUser) }); var token = await _userManager.GenerateJwtTokenAsync(appUser);
return Ok(new LoginResult()
{
Succeeded= result.Succeeded,
Token = token,
UserName = appUser.UserName,
SignIn = result
});
} }
else else
{ {
actionResult = BadRequest(new { code = -3, msg = "Login Error", data = result });
return Unauthorized(new { code = ApiCode.LoginError, msg = "Unauthorized", data = result });
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
actionResult = BadRequest(new { code = -1, msg = ex.Message, data = ex }); return this.ExceptionRequest(ex);
} }
return actionResult;
} }
/// <summary> /// <summary>
...@@ -71,9 +82,9 @@ namespace IoTSharp.Hub.Controllers ...@@ -71,9 +82,9 @@ namespace IoTSharp.Hub.Controllers
/// <returns ></returns> /// <returns ></returns>
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public async Task<IActionResult> Register([FromBody] RegisterDto model) public async Task<ActionResult<LoginResult>> Register([FromBody] RegisterDto model)
{ {
IActionResult actionResult = NoContent(); ActionResult<LoginResult> actionResult = NoContent();
try try
{ {
var user = new IdentityUser var user = new IdentityUser
...@@ -86,13 +97,14 @@ namespace IoTSharp.Hub.Controllers ...@@ -86,13 +97,14 @@ namespace IoTSharp.Hub.Controllers
{ {
await _signInManager.SignInAsync(user, false); await _signInManager.SignInAsync(user, false);
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email)); await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
var cust = _context.Customer.FirstOrDefault(c => c.Name == model.CustomerName); var customer = _context.Customer.FirstOrDefault(c => c.Name == model.CustomerName);
if (customer != null)
if (cust != null)
{ {
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.GroupSid, cust.Id.ToString())); await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
await _signInManager.UserManager.AddClaimAsync(user, new Claim(IoTSharpClaimTypes.Customer, customer.Id.ToString()));
actionResult = Ok(new { code = 0, msg = "OK", data = GenerateJwtToken(model.Email, user) }); await _signInManager.UserManager.AddClaimAsync(user, new Claim(IoTSharpClaimTypes.Tenant, customer.Tenant.Id.ToString()));
await _signInManager.UserManager.AddToRolesAsync(user, new[] { nameof(UserRole.NormalUser) });
actionResult = CreatedAtAction(nameof(this.Login), new LoginDto() { Email = model.Email, Password = model.Password });
} }
} }
else else
...@@ -109,31 +121,14 @@ namespace IoTSharp.Hub.Controllers ...@@ -109,31 +121,14 @@ namespace IoTSharp.Hub.Controllers
return actionResult; return actionResult;
} }
public class LoginResult
private object GenerateJwtToken(string email, IdentityUser user)
{ {
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtKey"])); public string Token { get; set; }
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); public string UserName { get; set; }
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"])); public Microsoft.AspNetCore.Identity.SignInResult SignIn { get; set; }
public bool Succeeded { get; set; }
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
} }
public class LoginDto public class LoginDto
{ {
[Required] [Required]
......
...@@ -82,7 +82,7 @@ namespace IoTSharp.Hub.Controllers ...@@ -82,7 +82,7 @@ namespace IoTSharp.Hub.Controllers
customer.Tenant= _context.Tenant.Find(customer.Tenant.Id); customer.Tenant= _context.Tenant.Find(customer.Tenant.Id);
_context.Customer.Add(customer); _context.Customer.Add(customer);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
return await GetCustomer(customer.Id); return CreatedAtAction("GetCustomer",customer.Id);
} }
// DELETE: api/Customers/5 // DELETE: api/Customers/5
......
using IoTSharp.Hub.Data; using IoTSharp.Hub.Data;
using IoTSharp.Hub.Extensions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
...@@ -22,109 +23,71 @@ namespace IoTSharp.Hub.Controllers ...@@ -22,109 +23,71 @@ namespace IoTSharp.Hub.Controllers
private readonly UserManager<IdentityUser> _userManager; private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly SignInManager<IdentityUser> _signInManager; private readonly SignInManager<IdentityUser> _signInManager;
private readonly ApplicationDBInitializer _dBInitializer;
public InstallerController( public InstallerController(
UserManager<IdentityUser> userManager, UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager, SignInManager<IdentityUser> signInManager,
IConfiguration configuration, ILogger<AccountController> logger, ApplicationDbContext context IConfiguration configuration, ILogger<AccountController> logger, ApplicationDbContext context
) , ApplicationDBInitializer dBInitializer)
{ {
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
_configuration = configuration; _configuration = configuration;
_logger = logger; _logger = logger;
_context = context; _context = context;
_dBInitializer = dBInitializer;
} }
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpGet]
public IActionResult CheckInstallation() public ActionResult<InstanceDto> Instance()
{ {
int code = -1;
string msg;
bool installed = false;
try try
{ {
installed = !(_context.Tenant.Count() == 0 && _context.Customer.Count() == 0); return base.Ok(GetInstanceDto());
msg = installed ? "Already installed" : "Not Install";
code = 0;
} }
catch (Exception ex) catch (Exception ex)
{ {
msg = ex.Message; return this.ExceptionRequest(ex);
} }
return Ok(new
}
private InstanceDto GetInstanceDto()
{ {
code, return new InstanceDto() { Installed = _context.Relationship.Any(), Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() };
msg,
data = new { installed }
});
} }
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost]
public async Task<IActionResult> Install([FromBody] InstallDto model) public ActionResult<InstanceDto> Install([FromBody] InstallDto model)
{ {
IActionResult actionResult = NoContent(); ActionResult<InstanceDto> actionResult = NoContent();
var tran = _context.Database.BeginTransaction();
try try
{ {
if (_context.Tenant.Count() == 0 && _context.Customer.Count() == 0) if (!_context.Relationship.Any())
{
var tenant = new Tenant() { Id = Guid.NewGuid(), Name = model.TenantName, EMail = model.TenantEMail };
var customer = new Customer() { Id = Guid.NewGuid(), Name = model.CustomerName, Email = model.CustomerEMail };
customer.Tenant = tenant;
tenant.Customers = new List<Customer>();
tenant.Customers.Add(customer);
var user = new IdentityUser
{
Email = model.Email,
UserName = model.Email,
PhoneNumber = model.PhoneNumber
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{ {
_context.Tenant.Add(tenant); _dBInitializer.SeedRole();
_context.Customer.Add(customer); _dBInitializer.SeedUser(model);
await _signInManager.SignInAsync(user, false); actionResult = Ok(GetInstanceDto());
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.GroupSid, customer.Id.ToString()));
var rship = new Relationship();
rship.IdentityUser = _context.Users.Find(user.Id);
rship.Customer = customer;
rship.Tenant = tenant;
_context.Add(rship);
int savechangesresult = _context.SaveChanges();
tran.Commit();
actionResult = Ok(new { code = 0, msg = "OK", data = new { result = savechangesresult >= 0, count = savechangesresult } });
}
else
{
tran.Rollback();
var msg = from e in result.Errors select $"{e.Code}:{e.Description}\r\n";
actionResult = BadRequest(new { code = -3, msg = string.Join(';', msg.ToArray()) });
}
} }
else else
{ {
tran.Rollback(); actionResult= BadRequest(new { code = ApiCode.AlreadyExists, msg = "Already installed", data = GetInstanceDto() });
actionResult = Ok(new { code = 1, msg = "Already installed" });
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
tran.Rollback(); actionResult= this.ExceptionRequest(ex);
actionResult = BadRequest(new { code = -2, msg = ex.Message, data = ex });
_logger.LogError(ex, ex.Message);
} }
return actionResult; return actionResult;
} }
public class InstanceDto
{
public string Version { get; internal set; }
public bool Installed { get; internal set; }
}
public class InstallDto public class InstallDto
{ {
[Required] [Required]
......
...@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http; ...@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using IoTSharp.Hub.Data; using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authorization;
namespace IoTSharp.Hub.Controllers namespace IoTSharp.Hub.Controllers
{ {
...@@ -19,7 +20,8 @@ namespace IoTSharp.Hub.Controllers ...@@ -19,7 +20,8 @@ namespace IoTSharp.Hub.Controllers
{ {
_context = context; _context = context;
} }
[Authorize(Roles =nameof(UserRole.TenantAdmin))]
//[AllowAnonymous]
// GET: api/Tenants // GET: api/Tenants
[HttpGet] [HttpGet]
public async Task<ActionResult<IEnumerable<Tenant>>> GetTenant() public async Task<ActionResult<IEnumerable<Tenant>>> GetTenant()
...@@ -27,7 +29,7 @@ namespace IoTSharp.Hub.Controllers ...@@ -27,7 +29,7 @@ namespace IoTSharp.Hub.Controllers
return await _context.Tenant.ToListAsync(); return await _context.Tenant.ToListAsync();
} }
[Authorize(Roles = nameof(UserRole.NormalUser))]
// GET: api/Tenants/5 // GET: api/Tenants/5
[HttpGet("{id}")] [HttpGet("{id}")]
public async Task<ActionResult<Tenant>> GetTenant(Guid id) public async Task<ActionResult<Tenant>> GetTenant(Guid id)
...@@ -41,7 +43,7 @@ namespace IoTSharp.Hub.Controllers ...@@ -41,7 +43,7 @@ namespace IoTSharp.Hub.Controllers
return tenant; return tenant;
} }
[Authorize(Roles = nameof(UserRole.TenantAdmin))]
// PUT: api/Tenants/5 // PUT: api/Tenants/5
[HttpPut("{id}")] [HttpPut("{id}")]
public async Task<IActionResult> PutTenant(Guid id, Tenant tenant) public async Task<IActionResult> PutTenant(Guid id, Tenant tenant)
...@@ -71,7 +73,7 @@ namespace IoTSharp.Hub.Controllers ...@@ -71,7 +73,7 @@ namespace IoTSharp.Hub.Controllers
return NoContent(); return NoContent();
} }
[Authorize(Roles = nameof(UserRole.SystemAdmin))]
// POST: api/Tenants // POST: api/Tenants
[HttpPost] [HttpPost]
public async Task<ActionResult<Tenant>> PostTenant(Tenant tenant) public async Task<ActionResult<Tenant>> PostTenant(Tenant tenant)
...@@ -81,7 +83,7 @@ namespace IoTSharp.Hub.Controllers ...@@ -81,7 +83,7 @@ namespace IoTSharp.Hub.Controllers
return CreatedAtAction("GetTenant", new { id = tenant.Id }, tenant); return CreatedAtAction("GetTenant", new { id = tenant.Id }, tenant);
} }
[Authorize(Roles = nameof(UserRole.SystemAdmin))]
// DELETE: api/Tenants/5 // DELETE: api/Tenants/5
[HttpDelete("{id}")] [HttpDelete("{id}")]
public async Task<ActionResult<Tenant>> DeleteTenant(Guid id) public async Task<ActionResult<Tenant>> DeleteTenant(Guid id)
......
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using static IoTSharp.Hub.Controllers.InstallerController;
namespace IoTSharp.Hub.Data
{
public class ApplicationDBInitializer
{
private readonly RoleManager<IdentityRole> _role;
private ApplicationDbContext _context;
private ILogger _logger;
private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration;
private readonly SignInManager<IdentityUser> _signInManager;
public ApplicationDBInitializer(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IConfiguration configuration, ILogger<ApplicationDBInitializer> logger,
ApplicationDbContext context, RoleManager<IdentityRole> role
)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
_logger = logger;
_context = context;
_role = role;
}
public void SeedRole()
{
var roles = new IdentityRole[]{new IdentityRole(nameof(UserRole.Anonymous))
, new IdentityRole(nameof(UserRole.NormalUser))
, new IdentityRole(nameof(UserRole.CustomerAdmin))
, new IdentityRole(nameof(UserRole.TenantAdmin))
, new IdentityRole(nameof(UserRole.SystemAdmin)) };
roles.ToList().ForEach(role =>
{
_role.CreateAsync(role);
_role.UpdateNormalizedRoleNameAsync(role);
});
_context.SaveChanges();
}
public void SeedUser(InstallDto model)
{
var tenant = _context.Tenant.FirstOrDefault(t => t.EMail == model.TenantEMail);
var customer = _context.Customer.FirstOrDefault(t => t.Email == model.CustomerEMail);
if (tenant == null && customer == null)
{
tenant = new Tenant() { Id = Guid.NewGuid(), Name = model.TenantName, EMail = model.TenantEMail };
customer = new Customer() { Id = Guid.NewGuid(), Name = model.CustomerName, Email = model.CustomerEMail };
customer.Tenant = tenant;
tenant.Customers = new List<Customer>();
tenant.Customers.Add(customer);
_context.Tenant.Add(tenant);
_context.Customer.Add(customer);
_context.SaveChanges();
}
IdentityUser user = _userManager.FindByEmailAsync(model.Email).GetAwaiter().GetResult();
if (user == null)
{
user = new IdentityUser
{
Email = model.Email,
UserName = model.Email,
PhoneNumber = model.PhoneNumber
};
var result = _userManager.CreateAsync(user, model.Password).GetAwaiter().GetResult();
if (result.Succeeded)
{
_signInManager.SignInAsync(user, false);
_signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
_signInManager.UserManager.AddClaimAsync(user, new Claim(IoTSharpClaimTypes.Customer, customer.Id.ToString()));
_signInManager.UserManager.AddClaimAsync(user, new Claim(IoTSharpClaimTypes.Tenant, tenant.Id.ToString()));
_signInManager.UserManager.AddToRolesAsync(user, new[] {
nameof(UserRole.Anonymous),
nameof(UserRole.NormalUser),
nameof(UserRole.CustomerAdmin),
nameof(UserRole.TenantAdmin),
nameof(UserRole.SystemAdmin)});
}
}
var rship = new Relationship
{
IdentityUser = _context.Users.Find(user.Id),
Customer = _context.Customer.Find(customer.Id),
Tenant = _context.Tenant.Find(tenant.Id)
};
_context.Add(rship);
_context.SaveChanges();
}
}
}
...@@ -24,6 +24,7 @@ namespace IoTSharp.Hub.Data ...@@ -24,6 +24,7 @@ namespace IoTSharp.Hub.Data
{ {
Database.Migrate(); Database.Migrate();
} }
} }
public DatabaseType DatabaseType { get; private set; } public DatabaseType DatabaseType { get; private set; }
...@@ -47,6 +48,7 @@ namespace IoTSharp.Hub.Data ...@@ -47,6 +48,7 @@ namespace IoTSharp.Hub.Data
switch (DatabaseType) switch (DatabaseType)
{ {
case DatabaseType.mssql: case DatabaseType.mssql:
...@@ -65,6 +67,7 @@ namespace IoTSharp.Hub.Data ...@@ -65,6 +67,7 @@ namespace IoTSharp.Hub.Data
} }
} }
private void ForNpgsql(ModelBuilder modelBuilder) private void ForNpgsql(ModelBuilder modelBuilder)
{ {
modelBuilder.Entity<TelemetryData>() modelBuilder.Entity<TelemetryData>()
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace IoTSharp.Hub.Data namespace IoTSharp.Hub.Data
{ {
public static class IoTSharpClaimTypes
{
public const string Customer = "http://schemas.iotsharp.net/ws/2019/01/identity/claims/customer";
public const string Tenant = "http://schemas.iotsharp.net/ws/2019/01/identity/claims/tenant";
}
public enum ApiCode:int
{
Success= 10000,
LoginError=10001,
Exception = 10002,
AlreadyExists = 10003,
}
public enum DataCatalog public enum DataCatalog
{ {
None, None,
...@@ -14,6 +28,15 @@ namespace IoTSharp.Hub.Data ...@@ -14,6 +28,15 @@ namespace IoTSharp.Hub.Data
TelemetryData, TelemetryData,
TelemetryLatest, TelemetryLatest,
}
public enum UserRole
{
Anonymous,
NormalUser,
CustomerAdmin,
TenantAdmin,
SystemAdmin,
} }
public enum DataType public enum DataType
......
// <auto-generated />
using System;
using IoTSharp.Hub.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace IoTSharp.Hub.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20190108071914_AddRole")]
partial class AddRole
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.0-rtm-35687")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("IoTSharp.Hub.Data.Customer", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Address");
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("Email");
b.Property<string>("Name");
b.Property<string>("Phone");
b.Property<string>("Province");
b.Property<string>("Street");
b.Property<Guid?>("TenantId");
b.Property<int>("ZipCode");
b.HasKey("Id");
b.HasIndex("TenantId");
b.ToTable("Customer");
});
modelBuilder.Entity("IoTSharp.Hub.Data.DataStorage", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Catalog");
b.Property<DateTime>("DateTime");
b.Property<string>("KeyName")
.IsRequired();
b.Property<int>("Type");
b.Property<byte[]>("Value_Binary");
b.Property<bool>("Value_Boolean");
b.Property<double>("Value_Double");
b.Property<string>("Value_Json")
.HasColumnType("jsonb");
b.Property<long>("Value_Long");
b.Property<string>("Value_String");
b.Property<string>("Value_XML")
.HasColumnType("xml");
b.HasKey("Id");
b.ToTable("DataStorage");
b.HasDiscriminator<int>("Catalog").HasValue(0);
});
modelBuilder.Entity("IoTSharp.Hub.Data.Device", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("CustomerId");
b.Property<string>("Name");
b.Property<Guid?>("TenantId");
b.Property<string>("Type");
b.HasKey("Id");
b.HasIndex("CustomerId");
b.HasIndex("TenantId");
b.ToTable("Device");
});
modelBuilder.Entity("IoTSharp.Hub.Data.Relationship", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<Guid?>("CustomerId");
b.Property<string>("IdentityUserId");
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("CustomerId");
b.HasIndex("IdentityUserId");
b.HasIndex("TenantId");
b.ToTable("Relationship");
});
modelBuilder.Entity("IoTSharp.Hub.Data.Tenant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Address");
b.Property<string>("City");
b.Property<string>("Country");
b.Property<string>("EMail");
b.Property<string>("Name");
b.Property<string>("Phone");
b.Property<string>("Province");
b.Property<string>("Street");
b.Property<int>("ZipCode");
b.HasKey("Id");
b.ToTable("Tenant");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("IoTSharp.Hub.Data.AttributeData", b =>
{
b.HasBaseType("IoTSharp.Hub.Data.DataStorage");
b.Property<Guid>("DeviceId");
b.HasIndex("DeviceId");
b.HasDiscriminator().HasValue(1);
});
modelBuilder.Entity("IoTSharp.Hub.Data.AttributeLatest", b =>
{
b.HasBaseType("IoTSharp.Hub.Data.DataStorage");
b.Property<Guid>("DeviceId")
.HasColumnName("AttributeLatest_DeviceId");
b.HasIndex("DeviceId");
b.HasDiscriminator().HasValue(2);
});
modelBuilder.Entity("IoTSharp.Hub.Data.TelemetryData", b =>
{
b.HasBaseType("IoTSharp.Hub.Data.DataStorage");
b.Property<Guid>("DeviceId")
.HasColumnName("TelemetryData_DeviceId");
b.HasIndex("DeviceId");
b.HasDiscriminator().HasValue(3);
});
modelBuilder.Entity("IoTSharp.Hub.Data.TelemetryLatest", b =>
{
b.HasBaseType("IoTSharp.Hub.Data.DataStorage");
b.Property<Guid>("DeviceId")
.HasColumnName("TelemetryLatest_DeviceId");
b.HasIndex("DeviceId");
b.HasDiscriminator().HasValue(4);
});
modelBuilder.Entity("IoTSharp.Hub.Data.Customer", b =>
{
b.HasOne("IoTSharp.Hub.Data.Tenant", "Tenant")
.WithMany("Customers")
.HasForeignKey("TenantId");
});
modelBuilder.Entity("IoTSharp.Hub.Data.Device", b =>
{
b.HasOne("IoTSharp.Hub.Data.Customer", "Customer")
.WithMany("Devices")
.HasForeignKey("CustomerId");
b.HasOne("IoTSharp.Hub.Data.Tenant", "Tenant")
.WithMany("Devices")
.HasForeignKey("TenantId");
});
modelBuilder.Entity("IoTSharp.Hub.Data.Relationship", b =>
{
b.HasOne("IoTSharp.Hub.Data.Customer", "Customer")
.WithMany()
.HasForeignKey("CustomerId");
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "IdentityUser")
.WithMany()
.HasForeignKey("IdentityUserId");
b.HasOne("IoTSharp.Hub.Data.Tenant", "Tenant")
.WithMany()
.HasForeignKey("TenantId");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IoTSharp.Hub.Data.AttributeData", b =>
{
b.HasOne("IoTSharp.Hub.Data.Device", "Device")
.WithMany("AttributeData")
.HasForeignKey("DeviceId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IoTSharp.Hub.Data.AttributeLatest", b =>
{
b.HasOne("IoTSharp.Hub.Data.Device", "Device")
.WithMany("AttributeLatest")
.HasForeignKey("DeviceId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IoTSharp.Hub.Data.TelemetryData", b =>
{
b.HasOne("IoTSharp.Hub.Data.Device", "Device")
.WithMany("TelemetryData")
.HasForeignKey("DeviceId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("IoTSharp.Hub.Data.TelemetryLatest", b =>
{
b.HasOne("IoTSharp.Hub.Data.Device", "Device")
.WithMany("TelemetryLatest")
.HasForeignKey("DeviceId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}
using Microsoft.EntityFrameworkCore.Migrations;
namespace IoTSharp.Hub.Migrations
{
public partial class AddRole : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "AspNetUserTokens",
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 128);
migrationBuilder.AlterColumn<string>(
name: "LoginProvider",
table: "AspNetUserTokens",
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 128);
migrationBuilder.AlterColumn<string>(
name: "ProviderKey",
table: "AspNetUserLogins",
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 128);
migrationBuilder.AlterColumn<string>(
name: "LoginProvider",
table: "AspNetUserLogins",
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 128);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "Name",
table: "AspNetUserTokens",
maxLength: 128,
nullable: false,
oldClrType: typeof(string));
migrationBuilder.AlterColumn<string>(
name: "LoginProvider",
table: "AspNetUserTokens",
maxLength: 128,
nullable: false,
oldClrType: typeof(string));
migrationBuilder.AlterColumn<string>(
name: "ProviderKey",
table: "AspNetUserLogins",
maxLength: 128,
nullable: false,
oldClrType: typeof(string));
migrationBuilder.AlterColumn<string>(
name: "LoginProvider",
table: "AspNetUserLogins",
maxLength: 128,
nullable: false,
oldClrType: typeof(string));
}
}
}
...@@ -273,11 +273,9 @@ namespace IoTSharp.Hub.Migrations ...@@ -273,11 +273,9 @@ namespace IoTSharp.Hub.Migrations
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{ {
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider");
.HasMaxLength(128);
b.Property<string>("ProviderKey") b.Property<string>("ProviderKey");
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName"); b.Property<string>("ProviderDisplayName");
...@@ -308,11 +306,9 @@ namespace IoTSharp.Hub.Migrations ...@@ -308,11 +306,9 @@ namespace IoTSharp.Hub.Migrations
{ {
b.Property<string>("UserId"); b.Property<string>("UserId");
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider");
.HasMaxLength(128);
b.Property<string>("Name") b.Property<string>("Name");
.HasMaxLength(128);
b.Property<string>("Value"); b.Property<string>("Value");
......
using System.Threading.Tasks; using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
namespace IoTSharp.Hub.Extensions namespace IoTSharp.Hub.Extensions
{ {
...@@ -8,5 +13,20 @@ namespace IoTSharp.Hub.Extensions ...@@ -8,5 +13,20 @@ namespace IoTSharp.Hub.Extensions
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
public static BadRequestObjectResult ExceptionRequest( this ControllerBase @base,Exception exception)
{
MethodBase mb = new StackTrace(exception).GetFrame(0).GetMethod();
MethodBase cu = new StackTrace(true).GetFrame(0).GetMethod();
return @base.BadRequest(new
{
code = ApiCode.Exception,
msg = exception.Message,
data = new
{
ExceptionMethod = mb.DeclaringType.FullName + "." + mb.Name,
MethodName = cu.Name
}
});
}
} }
} }
\ No newline at end of file
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace IoTSharp.Hub
{
public static class TokenExtension
{
static byte[] symmetricKeyBytes;
static SymmetricSecurityKey symmetricKey;
static SigningCredentials signingCredentials;
static TokenValidationParameters tokenValidationParams;
static TimeSpan _expire;
static string _issuer;
static string _audience;
//Construct our JWT authentication paramaters then inject the parameters into the current TokenBuilder instance
// If injecting an RSA key for signing use this method
// Be weary of common jwt trips: https://trustfoundry.net/jwt-hacking-101/ and https://www.sjoerdlangkemper.nl/2016/09/28/attacking-jwt-authentication/
//public static void ConfigureJwtAuthentication(this IServiceCollection services, RSAParameters rsaParams)
public static void ConfigureJwtAuthentication(this IServiceCollection services, string issuer, string audience, string key, TimeSpan expire)
{
symmetricKeyBytes = Encoding.ASCII.GetBytes(key);
symmetricKey = new SymmetricSecurityKey(symmetricKeyBytes);
signingCredentials = new SigningCredentials(symmetricKey, SecurityAlgorithms.HmacSha256);
_expire = expire;
if (_expire.TotalMinutes < 60) expire = TimeSpan.FromMinutes(60);
_issuer = issuer ?? "iotsharp.net";
_audience = audience ?? _issuer;
tokenValidationParams = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
ValidIssuer = issuer,
ValidAudience = audience,
ValidateLifetime = true,
ValidateAudience = true,
RequireSignedTokens = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)),
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.TokenValidationParameters = tokenValidationParams;
#if PROD || UAT
options.IncludeErrorDetails = false;
#elif DEBUG
options.RequireHttpsMetadata = false;
#endif
});
}
public static async Task<string> GenerateJwtTokenAsync(this UserManager<IdentityUser> manager, IdentityUser user)
{
var roles = await manager.GetRolesAsync(user);
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, user.Email),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id)
};
var lstclaims = await manager.GetClaimsAsync(user);
if (roles != null)
{
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
}
claims.AddRange(lstclaims.Where(c => c.Type == IoTSharpClaimTypes.Tenant || c.Type == IoTSharpClaimTypes.Customer).ToList());
var head = new JwtHeader();
var jwt = new JwtSecurityToken(tokenValidationParams.ValidIssuer, tokenValidationParams.ValidAudience, claims, DateTime.UtcNow, DateTime.Now.AddMinutes(_expire.TotalMinutes), signingCredentials);
jwt.Payload.AddClaims(claims.ToArray());
return new JwtSecurityTokenHandler().WriteToken(jwt);
}
public static JwtSecurityToken GetJwtSecurityToken(this HttpRequest httpRequest)
{
JwtSecurityToken result = null;
var authenticationHeaders = httpRequest.Headers["Authorization"].ToArray();
if ((authenticationHeaders == null) || (authenticationHeaders.Length != 1))
{
result = null;
}
else
{
var jwToken = authenticationHeaders[0].Split(' ')[1];
var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
ClaimsPrincipal principal = null;
SecurityToken securityToken = null;
try
{
principal = jwtSecurityTokenHandler.ValidateToken(jwToken, tokenValidationParams, out securityToken);
}
catch (Exception ex)
{
throw ex;
}
if ((principal != null) && (principal.Claims != null))
{
result = securityToken as JwtSecurityToken;
Trace.WriteLine(result.Audiences.First());
Trace.WriteLine(result.Issuer);
}
}
return result;
}
public static string GetUserId(this JwtSecurityToken jwtSecurityToken)
{
return jwtSecurityToken.Payload["userid"] as string;
}
public static string GetPayloadValue(this JwtSecurityToken jwtSecurityToken, string Key)
{
return jwtSecurityToken.Payload[Key] as string;
}
}
}
...@@ -24,12 +24,9 @@ ...@@ -24,12 +24,9 @@
<None Remove="Migrations\**" /> <None Remove="Migrations\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Network" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="2.2.0" /> <PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.Sqlite" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.SqlServer" Version="2.2.0" />
<PackageReference Include="AspNetCore.HealthChecks.System" Version="2.2.1" /> <PackageReference Include="AspNetCore.HealthChecks.System" Version="2.2.1" />
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="2.2.4" /> <PackageReference Include="AspNetCore.HealthChecks.UI" Version="2.2.10" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" /> <PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="2.2.2" />
<PackageReference Include="IoTSharp.X509Extensions" Version="1.3.3" /> <PackageReference Include="IoTSharp.X509Extensions" Version="1.3.3" />
<PackageReference Include="LiteDB" Version="4.1.4" /> <PackageReference Include="LiteDB" Version="4.1.4" />
...@@ -46,7 +43,7 @@ ...@@ -46,7 +43,7 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
<PackageReference Include="MQTTnet" Version="2.8.5" /> <PackageReference Include="MQTTnet" Version="2.8.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
<PackageReference Include="NSwag.AspNetCore" Version="12.0.7" /> <PackageReference Include="NSwag.AspNetCore" Version="12.0.10" />
<PackageReference Include="QuartzHostedService" Version="0.0.3" /> <PackageReference Include="QuartzHostedService" Version="0.0.3" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
</ItemGroup> </ItemGroup>
......
using IoTSharp.Hub.Data; using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
...@@ -8,10 +10,13 @@ using Microsoft.AspNetCore.Mvc; ...@@ -8,10 +10,13 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NSwag.AspNetCore; using NSwag.AspNetCore;
using System; using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
namespace IoTSharp.Hub namespace IoTSharp.Hub
{ {
...@@ -38,11 +43,19 @@ namespace IoTSharp.Hub ...@@ -38,11 +43,19 @@ namespace IoTSharp.Hub
services.AddIoTSharpHub(Configuration); services.AddIoTSharpHub(Configuration);
services.AddDefaultIdentity<IdentityUser>() services.AddIdentity<IdentityUser, IdentityRole>()
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>(); .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication().AddJwtBearer(); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims
services.ConfigureJwtAuthentication(Configuration["JwtIssuer"], Configuration["JwtAudience"], Configuration["JwtKey"],TimeSpan.FromDays( Convert.ToInt32(Configuration["JwtExpireDays"])));
services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
});
services.Configure<ForwardedHeadersOptions>(options => services.Configure<ForwardedHeadersOptions>(options =>
{ {
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
...@@ -56,7 +69,7 @@ namespace IoTSharp.Hub ...@@ -56,7 +69,7 @@ namespace IoTSharp.Hub
configure.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString(); configure.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString();
configure.Description = description?.Description; configure.Description = description?.Description;
}); });
services.AddTransient<ApplicationDBInitializer>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册