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

add role , redefine install api

上级 84bacfac
using IoTSharp.Hub.Data;
using IoTSharp.Hub.Extensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
......@@ -41,27 +44,35 @@ namespace IoTSharp.Hub.Controllers
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login([FromBody] LoginDto model)
public async Task<ActionResult<LoginResult>> Login([FromBody] LoginDto model)
{
IActionResult actionResult = NoContent();
try
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, false, false);
if (result.Succeeded)
{
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
{
actionResult = BadRequest(new { code = -3, msg = "Login Error", data = result });
return Unauthorized(new { code = ApiCode.LoginError, msg = "Unauthorized", data = result });
}
}
catch (Exception ex)
{
actionResult = BadRequest(new { code = -1, msg = ex.Message, data = ex });
return this.ExceptionRequest(ex);
}
return actionResult;
}
/// <summary>
......@@ -71,9 +82,9 @@ namespace IoTSharp.Hub.Controllers
/// <returns ></returns>
[AllowAnonymous]
[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
{
var user = new IdentityUser
......@@ -86,13 +97,14 @@ namespace IoTSharp.Hub.Controllers
{
await _signInManager.SignInAsync(user, false);
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
var cust = _context.Customer.FirstOrDefault(c => c.Name == model.CustomerName);
if (cust != null)
var customer = _context.Customer.FirstOrDefault(c => c.Name == model.CustomerName);
if (customer != null)
{
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.GroupSid, cust.Id.ToString()));
actionResult = Ok(new { code = 0, msg = "OK", data = GenerateJwtToken(model.Email, user) });
await _signInManager.UserManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, model.Email));
await _signInManager.UserManager.AddClaimAsync(user, new Claim(IoTSharpClaimTypes.Customer, customer.Id.ToString()));
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
......@@ -109,31 +121,14 @@ namespace IoTSharp.Hub.Controllers
return actionResult;
}
private object GenerateJwtToken(string email, IdentityUser user)
public class LoginResult
{
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"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["JwtExpireDays"]));
var token = new JwtSecurityToken(
_configuration["JwtIssuer"],
_configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds
);
return new JwtSecurityTokenHandler().WriteToken(token);
public string Token { get; set; }
public string UserName { get; set; }
public Microsoft.AspNetCore.Identity.SignInResult SignIn { get; set; }
public bool Succeeded { get; set; }
}
public class LoginDto
{
[Required]
......
......@@ -82,7 +82,7 @@ namespace IoTSharp.Hub.Controllers
customer.Tenant= _context.Tenant.Find(customer.Tenant.Id);
_context.Customer.Add(customer);
await _context.SaveChangesAsync();
return await GetCustomer(customer.Id);
return CreatedAtAction("GetCustomer",customer.Id);
}
// DELETE: api/Customers/5
......
using IoTSharp.Hub.Data;
using IoTSharp.Hub.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
......@@ -22,109 +23,71 @@ namespace IoTSharp.Hub.Controllers
private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ApplicationDBInitializer _dBInitializer;
public InstallerController(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IConfiguration configuration, ILogger<AccountController> logger, ApplicationDbContext context
)
, ApplicationDBInitializer dBInitializer)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
_logger = logger;
_context = context;
_dBInitializer = dBInitializer;
}
[AllowAnonymous]
[HttpPost]
public IActionResult CheckInstallation()
[HttpGet]
public ActionResult<InstanceDto> Instance()
{
int code = -1;
string msg;
bool installed = false;
try
{
installed = !(_context.Tenant.Count() == 0 && _context.Customer.Count() == 0);
msg = installed ? "Already installed" : "Not Install";
code = 0;
return base.Ok(GetInstanceDto());
}
catch (Exception ex)
{
msg = ex.Message;
return this.ExceptionRequest(ex);
}
return Ok(new
{
code,
msg,
data = new { installed }
});
}
private InstanceDto GetInstanceDto()
{
return new InstanceDto() { Installed = _context.Relationship.Any(), Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() };
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Install([FromBody] InstallDto model)
public ActionResult<InstanceDto> Install([FromBody] InstallDto model)
{
IActionResult actionResult = NoContent();
var tran = _context.Database.BeginTransaction();
ActionResult<InstanceDto> actionResult = NoContent();
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);
_context.Customer.Add(customer);
await _signInManager.SignInAsync(user, false);
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()) });
}
_dBInitializer.SeedRole();
_dBInitializer.SeedUser(model);
actionResult = Ok(GetInstanceDto());
}
else
{
tran.Rollback();
actionResult = Ok(new { code = 1, msg = "Already installed" });
actionResult= BadRequest(new { code = ApiCode.AlreadyExists, msg = "Already installed", data = GetInstanceDto() });
}
}
catch (Exception ex)
{
tran.Rollback();
actionResult = BadRequest(new { code = -2, msg = ex.Message, data = ex });
_logger.LogError(ex, ex.Message);
actionResult= this.ExceptionRequest(ex);
}
return actionResult;
}
public class InstanceDto
{
public string Version { get; internal set; }
public bool Installed { get; internal set; }
}
public class InstallDto
{
[Required]
......
......@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authorization;
namespace IoTSharp.Hub.Controllers
{
......@@ -19,7 +20,8 @@ namespace IoTSharp.Hub.Controllers
{
_context = context;
}
[Authorize(Roles =nameof(UserRole.TenantAdmin))]
//[AllowAnonymous]
// GET: api/Tenants
[HttpGet]
public async Task<ActionResult<IEnumerable<Tenant>>> GetTenant()
......@@ -27,7 +29,7 @@ namespace IoTSharp.Hub.Controllers
return await _context.Tenant.ToListAsync();
}
[Authorize(Roles = nameof(UserRole.NormalUser))]
// GET: api/Tenants/5
[HttpGet("{id}")]
public async Task<ActionResult<Tenant>> GetTenant(Guid id)
......@@ -41,7 +43,7 @@ namespace IoTSharp.Hub.Controllers
return tenant;
}
[Authorize(Roles = nameof(UserRole.TenantAdmin))]
// PUT: api/Tenants/5
[HttpPut("{id}")]
public async Task<IActionResult> PutTenant(Guid id, Tenant tenant)
......@@ -71,7 +73,7 @@ namespace IoTSharp.Hub.Controllers
return NoContent();
}
[Authorize(Roles = nameof(UserRole.SystemAdmin))]
// POST: api/Tenants
[HttpPost]
public async Task<ActionResult<Tenant>> PostTenant(Tenant tenant)
......@@ -81,7 +83,7 @@ namespace IoTSharp.Hub.Controllers
return CreatedAtAction("GetTenant", new { id = tenant.Id }, tenant);
}
[Authorize(Roles = nameof(UserRole.SystemAdmin))]
// DELETE: api/Tenants/5
[HttpDelete("{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
{
Database.Migrate();
}
}
public DatabaseType DatabaseType { get; private set; }
......@@ -44,8 +45,9 @@ namespace IoTSharp.Hub.Data
modelBuilder.Entity<AttributeLatest>().HasDiscriminator<DataCatalog>(nameof(Data.DataStorage.Catalog));
modelBuilder.Entity<TelemetryData>().HasDiscriminator<DataCatalog>(nameof(Data.DataStorage.Catalog));
modelBuilder.Entity<TelemetryLatest>().HasDiscriminator<DataCatalog>(nameof(Data.DataStorage.Catalog));
switch (DatabaseType)
{
......@@ -65,6 +67,7 @@ namespace IoTSharp.Hub.Data
}
}
private void ForNpgsql(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TelemetryData>()
......
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
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
{
None,
......@@ -14,6 +28,15 @@ namespace IoTSharp.Hub.Data
TelemetryData,
TelemetryLatest,
}
public enum UserRole
{
Anonymous,
NormalUser,
CustomerAdmin,
TenantAdmin,
SystemAdmin,
}
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
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey")
.HasMaxLength(128);
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
......@@ -308,11 +306,9 @@ namespace IoTSharp.Hub.Migrations
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("LoginProvider");
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<string>("Name");
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
{
......@@ -8,5 +13,20 @@ namespace IoTSharp.Hub.Extensions
{
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 @@
<None Remove="Migrations\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Network" 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.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="IoTSharp.X509Extensions" Version="1.3.3" />
<PackageReference Include="LiteDB" Version="4.1.4" />
......@@ -46,7 +43,7 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
<PackageReference Include="MQTTnet" Version="2.8.5" />
<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="System.Text.Encoding.CodePages" Version="4.5.0" />
</ItemGroup>
......
using IoTSharp.Hub.Data;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
......@@ -8,10 +10,13 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NSwag.AspNetCore;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Reflection;
using System.Text;
namespace IoTSharp.Hub
{
......@@ -38,11 +43,19 @@ namespace IoTSharp.Hub
services.AddIoTSharpHub(Configuration);
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication().AddJwtBearer();
services.AddIdentity<IdentityUser, IdentityRole>()
.AddRoles<IdentityRole>()
.AddRoleManager<RoleManager<IdentityRole>>()
.AddDefaultTokenProviders()
.AddEntityFrameworkStores<ApplicationDbContext>();
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 =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
......@@ -56,7 +69,7 @@ namespace IoTSharp.Hub
configure.Version = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString();
configure.Description = description?.Description;
});
services.AddTransient<ApplicationDBInitializer>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
......@@ -84,7 +97,7 @@ namespace IoTSharp.Hub
app.UseCookiePolicy();
app.UseAuthentication();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册