[Bug]抓贼!原来贼是Cookies!!!!!!
This commit is contained in:
parent
7bf9c2bc71
commit
18b2228e48
@ -1,6 +0,0 @@
|
|||||||
@AGSS_HostAddress = http://localhost:5200
|
|
||||||
|
|
||||||
GET {{AGSS_HostAddress}}/weatherforecast/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
@ -6,16 +6,19 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using AGSS.Models.Entities;
|
using AGSS.Models.Entities;
|
||||||
using AGSS.Utilities;
|
using AGSS.Utilities;
|
||||||
|
using asg_form;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace AGSS.Areas.Identity.Pages.Account
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
{
|
{
|
||||||
@ -111,7 +114,7 @@ namespace AGSS.Areas.Identity.Pages.Account
|
|||||||
ReturnUrl = returnUrl;
|
ReturnUrl = returnUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
|
public async Task<IActionResult> OnPostAsync([FromServices] IOptions<JWTOptions> jwtOptions,string returnUrl = null)
|
||||||
{
|
{
|
||||||
returnUrl ??= Url.Content("~/");
|
returnUrl ??= Url.Content("~/");
|
||||||
|
|
||||||
@ -125,12 +128,20 @@ namespace AGSS.Areas.Identity.Pages.Account
|
|||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User logged in.");
|
_logger.LogInformation("User logged in.");
|
||||||
|
|
||||||
var user = await _userManager.FindByEmailAsync(Input.Email);
|
var user = await _userManager.FindByEmailAsync(Input.Email);
|
||||||
var roles = await _userManager.GetRolesAsync(user);
|
|
||||||
var token = _jwt.GenerateJwtToken(user,roles);
|
|
||||||
|
|
||||||
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}";
|
var claims = new List<Claim>();
|
||||||
|
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
|
||||||
|
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
|
||||||
|
var roles = await _userManager.GetRolesAsync(user);
|
||||||
|
foreach (string role in roles)
|
||||||
|
{
|
||||||
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
||||||
|
}
|
||||||
|
string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value);
|
||||||
|
|
||||||
|
|
||||||
|
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}";
|
||||||
|
|
||||||
return Redirect(frontendCallback);
|
return Redirect(frontendCallback);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -14,12 +15,14 @@ using Microsoft.AspNetCore.Authentication;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using AGSS.Models.Entities;
|
using AGSS.Models.Entities;
|
||||||
using AGSS.Utilities;
|
using AGSS.Utilities;
|
||||||
|
using asg_form;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
using Microsoft.AspNetCore.WebUtilities;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace AGSS.Areas.Identity.Pages.Account
|
namespace AGSS.Areas.Identity.Pages.Account
|
||||||
{
|
{
|
||||||
@ -119,7 +122,7 @@ namespace AGSS.Areas.Identity.Pages.Account
|
|||||||
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
|
public async Task<IActionResult> OnPostAsync([FromServices] IOptions<JWTOptions> jwtOptions,string returnUrl = null)
|
||||||
{
|
{
|
||||||
returnUrl ??= Url.Content("~/");
|
returnUrl ??= Url.Content("~/");
|
||||||
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
|
||||||
@ -135,10 +138,17 @@ namespace AGSS.Areas.Identity.Pages.Account
|
|||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User created a new account with password.");
|
_logger.LogInformation("User created a new account with password.");
|
||||||
|
// var roles = await _userManager.GetRolesAsync(user);
|
||||||
|
var claims = new List<Claim>();
|
||||||
|
claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
|
||||||
|
claims.Add(new Claim(ClaimTypes.Name, user.UserName));
|
||||||
var roles = await _userManager.GetRolesAsync(user);
|
var roles = await _userManager.GetRolesAsync(user);
|
||||||
var token = _jwt.GenerateJwtToken(user,roles);
|
foreach (string role in roles)
|
||||||
|
{
|
||||||
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={token}";
|
claims.Add(new Claim(ClaimTypes.Role, role));
|
||||||
|
}
|
||||||
|
string jwtToken = _jwt.BuildToken(claims, jwtOptions.Value);
|
||||||
|
var frontendCallback = $"{Request.Query["frontendCallback"]}?token={jwtToken}";
|
||||||
|
|
||||||
return Redirect(frontendCallback);
|
return Redirect(frontendCallback);
|
||||||
}
|
}
|
||||||
|
203
AGSS/Controllers/Admin/AdminDictionaryController.cs
Normal file
203
AGSS/Controllers/Admin/AdminDictionaryController.cs
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
using System;
|
||||||
|
using AGSS.Models.Entities;
|
||||||
|
using AGSS.Models.Template;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AGSS.DbSet;
|
||||||
|
|
||||||
|
namespace AGSS.Controllers.Admin
|
||||||
|
{
|
||||||
|
|
||||||
|
[Route("api/v1/[controller]/[action]")]
|
||||||
|
public class AdminDictionaryController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ApplicationDbContext _dbContext;
|
||||||
|
private readonly UserManager<UserModel> _userManager;
|
||||||
|
|
||||||
|
public AdminDictionaryController(ApplicationDbContext dbContext, UserManager<UserModel> userManager)
|
||||||
|
{
|
||||||
|
_dbContext = dbContext;
|
||||||
|
_userManager = userManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> GetParentDictionaries([FromBody] string label)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// 确保 label 不是 null
|
||||||
|
label ??= string.Empty;
|
||||||
|
|
||||||
|
var parentDictionaries = _dbContext.Dictionaries.Where(d => d.ParentId == null && (string.IsNullOrEmpty(label) || d.Label.Contains(label))).ToList();
|
||||||
|
return Ok(new ReturnTemplate(200, "查询成功", parentDictionaries));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> AddParentDictionary([FromBody] DictionaryModel dictionary)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Label和Value", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
dictionary.Uuid = Guid.NewGuid().ToString();
|
||||||
|
dictionary.CreateTime = DateTime.UtcNow;
|
||||||
|
dictionary.CreateUserId = _userManager.GetUserId(User);
|
||||||
|
|
||||||
|
_dbContext.Dictionaries.Add(dictionary);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "添加父级字典成功", dictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> UpdateParentDictionary([FromBody] DictionaryModel dictionary)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid和Label", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId == null);
|
||||||
|
if (existingDictionary == null)
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
existingDictionary.Label = dictionary.Label;
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "更新父级字典成功", existingDictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> DeleteParentDictionary([FromBody] string uuid)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(uuid))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var parentDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId == null);
|
||||||
|
if (parentDictionary == null)
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(404, "未找到指定的父级字典", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbContext.Dictionaries.RemoveRange(_dbContext.Dictionaries.Where(d => d.ParentId == uuid));
|
||||||
|
_dbContext.Dictionaries.Remove(parentDictionary);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "删除父级字典成功", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> CreateChildDictionary([FromBody] DictionaryModel dictionary)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.ParentId) || string.IsNullOrWhiteSpace(dictionary.ParentValue) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供ParentId、ParentValue、Label和Value", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
dictionary.Uuid = Guid.NewGuid().ToString();
|
||||||
|
dictionary.CreateTime = DateTime.UtcNow;
|
||||||
|
dictionary.CreateUserId = _userManager.GetUserId(User);
|
||||||
|
|
||||||
|
_dbContext.Dictionaries.Add(dictionary);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "创建子级字典成功", dictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> UpdateChildDictionary([FromBody] DictionaryModel dictionary)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (dictionary == null || string.IsNullOrWhiteSpace(dictionary.Uuid) || string.IsNullOrWhiteSpace(dictionary.Label) || string.IsNullOrWhiteSpace(dictionary.Value))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid、Label和Value", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == dictionary.Uuid && d.ParentId != null);
|
||||||
|
if (existingDictionary == null)
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
existingDictionary.Label = dictionary.Label;
|
||||||
|
existingDictionary.LabelEn = dictionary.LabelEn;
|
||||||
|
existingDictionary.Remark = dictionary.Remark;
|
||||||
|
existingDictionary.Value = dictionary.Value;
|
||||||
|
existingDictionary.Tag = dictionary.Tag;
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "更新子级字典成功", existingDictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
public async Task<IActionResult> DeleteChildDictionary([FromBody] string uuid)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(uuid))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Uuid", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var childDictionary = _dbContext.Dictionaries.FirstOrDefault(d => d.Uuid == uuid && d.ParentId != null);
|
||||||
|
if (childDictionary == null)
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(404, "未找到指定的子级字典", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbContext.Dictionaries.Remove(childDictionary);
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "删除子级字典成功", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult GetChildDictionaries([FromBody] ChildDictionaryRequest request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(request.Value))
|
||||||
|
{
|
||||||
|
return Ok(new ReturnTemplate(400, "请求参数无效,请提供Value", null));
|
||||||
|
}
|
||||||
|
|
||||||
|
var childDictionaries = _dbContext.Dictionaries
|
||||||
|
.Where(d => d.ParentValue == request.Value &&
|
||||||
|
(request.Tag == null || (!string.IsNullOrEmpty(d.Tag) && d.Tag.Contains("," + request.Tag + ","))))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (request.Tag != null)
|
||||||
|
{
|
||||||
|
childDictionaries = childDictionaries.Where(d => !string.IsNullOrEmpty(d.Tag)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(new ReturnTemplate(200, "查询成功", childDictionaries));
|
||||||
|
}
|
||||||
|
public class ChildDictionaryRequest
|
||||||
|
{
|
||||||
|
public string Value { get; set; }
|
||||||
|
public string Tag { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,11 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using AGSS.Models.DTOs;
|
using AGSS.Models.DTOs;
|
||||||
using AGSS.Models.Entities;
|
using AGSS.Models.Entities;
|
||||||
using AGSS.Models.Template;
|
using AGSS.Models.Template;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@ -11,7 +15,7 @@ namespace AGSS.Controllers.Admin;
|
|||||||
/// 控制器类,用于管理角色相关的操作,包括添加角色、分配角色给用户以及通过角色查询用户。
|
/// 控制器类,用于管理角色相关的操作,包括添加角色、分配角色给用户以及通过角色查询用户。
|
||||||
/// 该控制器仅限具有"Admin"角色的用户访问。
|
/// 该控制器仅限具有"Admin"角色的用户访问。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize]
|
||||||
[Route("api/v1/[controller]/[action]")]
|
[Route("api/v1/[controller]/[action]")]
|
||||||
public class AdminRoleControllers:ControllerBase
|
public class AdminRoleControllers:ControllerBase
|
||||||
{
|
{
|
||||||
@ -44,18 +48,15 @@ public class AdminRoleControllers:ControllerBase
|
|||||||
/// <param name="role">要添加的角色信息</param>
|
/// <param name="role">要添加的角色信息</param>
|
||||||
/// <returns>返回操作结果,包含状态码、消息和数据</returns>
|
/// <returns>返回操作结果,包含状态码、消息和数据</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> AddRole([FromBody] RoleModel role)
|
public async Task<IActionResult> AddRole(string rolename)
|
||||||
{
|
{
|
||||||
if (role == null || string.IsNullOrWhiteSpace(role.Name))
|
|
||||||
{
|
|
||||||
|
|
||||||
return Ok(new ReturnTemplate(400,"创建失败,请提供名字",""));
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = await _roleManager.CreateAsync(role);
|
|
||||||
|
var result = await _roleManager.CreateAsync(new RoleModel(){Id = new Guid().ToString(),Name = rolename,NormalizedName = rolename});
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
return Ok(new ReturnTemplate(200,"创建成功",role));
|
return Ok(new ReturnTemplate(200,"创建成功",""));
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -9,6 +9,7 @@ namespace AGSS.DbSet
|
|||||||
|
|
||||||
public override DbSet<UserModel> Users { get; set; }
|
public override DbSet<UserModel> Users { get; set; }
|
||||||
public override DbSet<RoleModel> Roles { get; set; }
|
public override DbSet<RoleModel> Roles { get; set; }
|
||||||
|
public DbSet<DictionaryModel> Dictionaries { get; set; }
|
||||||
|
|
||||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||||
: base(options)
|
: base(options)
|
||||||
@ -20,6 +21,11 @@ namespace AGSS.DbSet
|
|||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|
||||||
|
|
||||||
|
modelBuilder.Entity<DictionaryModel>()
|
||||||
|
.HasKey(d => d.Uuid); // 假设 Id 是 DictionaryModel 的主键字段
|
||||||
|
|
||||||
|
|
||||||
// 在这里添加额外的配置,如果需要的话
|
// 在这里添加额外的配置,如果需要的话
|
||||||
// 例如:
|
// 例如:
|
||||||
// modelBuilder.Entity<UserModel>().ToTable("CustomUsers");
|
// modelBuilder.Entity<UserModel>().ToTable("CustomUsers");
|
||||||
|
@ -22,6 +22,51 @@ namespace AGSS.Migrations
|
|||||||
|
|
||||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AGSS.Models.Entities.DictionaryModel", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("Uuid")
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreateTime")
|
||||||
|
.HasColumnType("timestamp with time zone");
|
||||||
|
|
||||||
|
b.Property<string>("CreateUserId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Label")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("LabelEn")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ParentId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("ParentValue")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Remark")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Tag")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("text");
|
||||||
|
|
||||||
|
b.HasKey("Uuid");
|
||||||
|
|
||||||
|
b.ToTable("Dictionaries");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b =>
|
modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("Id")
|
b.Property<string>("Id")
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
using AGSS.Models.Entities;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
|
|
||||||
namespace AGSS.Models;
|
|
||||||
|
|
||||||
public class DBContext : DbContext
|
|
||||||
{
|
|
||||||
public DBContext(DbContextOptions<DBContext> options)
|
|
||||||
: base(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
17
AGSS/Models/DTOs/DictionaryDto.cs
Normal file
17
AGSS/Models/DTOs/DictionaryDto.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AGSS.Models.DTOs
|
||||||
|
{
|
||||||
|
public class DictionaryDto
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
public string ParentId { get; set; }
|
||||||
|
public string ParentValue { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public string LabelEn { get; set; }
|
||||||
|
public string Remark { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
public string Tag { get; set; }
|
||||||
|
}
|
||||||
|
}
|
18
AGSS/Models/Entities/DictionaryModel.cs
Normal file
18
AGSS/Models/Entities/DictionaryModel.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
namespace AGSS.Models.Entities
|
||||||
|
{
|
||||||
|
public class DictionaryModel
|
||||||
|
{
|
||||||
|
public string Uuid { get; set; }
|
||||||
|
public string ParentId { get; set; }
|
||||||
|
public string ParentValue { get; set; }
|
||||||
|
public string Label { get; set; }
|
||||||
|
public string LabelEn { get; set; }
|
||||||
|
public string Remark { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
public string Tag { get; set; }
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
public string CreateUserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
9
AGSS/Models/Entities/JwtModel.cs
Normal file
9
AGSS/Models/Entities/JwtModel.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
namespace asg_form
|
||||||
|
{
|
||||||
|
public class JWTOptions
|
||||||
|
{
|
||||||
|
public string SigningKey { get; set; }
|
||||||
|
public int ExpireSeconds { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,7 @@ using AGSS.Models;
|
|||||||
using AGSS.Models.Entities;
|
using AGSS.Models.Entities;
|
||||||
using AGSS.Models.Template;
|
using AGSS.Models.Template;
|
||||||
using AGSS.Utilities;
|
using AGSS.Utilities;
|
||||||
|
using asg_form;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -33,49 +34,48 @@ builder.Services.AddDbContext<ApplicationDbContext>(opt =>
|
|||||||
opt.UseNpgsql(builder.Configuration.GetConnectionString("DBContext")));
|
opt.UseNpgsql(builder.Configuration.GetConnectionString("DBContext")));
|
||||||
|
|
||||||
// Identity 配置
|
// Identity 配置
|
||||||
builder.Services.AddIdentity<UserModel, RoleModel>()
|
builder.Services.AddIdentityCore<UserModel>(options =>
|
||||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
{
|
||||||
.AddDefaultTokenProviders()
|
options.Password.RequireDigit = false;
|
||||||
.AddDefaultUI();
|
options.Password.RequireLowercase = false;
|
||||||
|
options.Password.RequireNonAlphanumeric = false;
|
||||||
|
options.Password.RequireUppercase = false;
|
||||||
|
options.Password.RequiredLength = 6;
|
||||||
|
options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
|
||||||
|
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
|
||||||
|
})
|
||||||
|
.AddRoles<RoleModel>()
|
||||||
|
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
|
.AddDefaultUI()
|
||||||
|
;
|
||||||
|
|
||||||
// 注册 UserService
|
// 注册 UserService
|
||||||
builder.Services.AddScoped<UserService>();
|
// builder.Services.AddScoped<UserService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<Jwt>();
|
builder.Services.AddScoped<Jwt>();
|
||||||
|
|
||||||
builder.Services.AddAuthentication(options =>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.Configure<JWTOptions>(builder.Configuration.GetSection("JWT"));
|
||||||
|
|
||||||
|
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
|
.AddJwtBearer(x =>
|
||||||
{
|
{
|
||||||
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
|
var jwtOpt = builder.Configuration.GetSection("JWT").Get<JWTOptions>();
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt.SigningKey);
|
||||||
})
|
var secKey = new SymmetricSecurityKey(keyBytes);
|
||||||
.AddJwtBearer(options =>
|
x.TokenValidationParameters = new()
|
||||||
{
|
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
{
|
||||||
ValidateIssuer = true,
|
ValidateIssuer = false,
|
||||||
ValidateAudience = true,
|
ValidateAudience = false,
|
||||||
ValidateLifetime = true,
|
ValidateLifetime = true,
|
||||||
ValidateIssuerSigningKey = true,
|
ValidateIssuerSigningKey = true,
|
||||||
ValidIssuer = builder.Configuration["Jwt:Issuer"],
|
IssuerSigningKey = secKey
|
||||||
ValidAudience = builder.Configuration["Jwt:Audience"],
|
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(
|
|
||||||
Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
|
|
||||||
};
|
};
|
||||||
options.Events = new JwtBearerEvents
|
})
|
||||||
{
|
.AddCookie("Identity.External");
|
||||||
OnChallenge = context =>
|
|
||||||
{
|
|
||||||
context.HandleResponse();
|
|
||||||
context.Response.StatusCode = 200;
|
|
||||||
context.Response.ContentType = "application/json";
|
|
||||||
return context.Response.WriteAsJsonAsync(new ReturnTemplate(401, "你提供了一个错误的Token,所以我们无法验证你的身份,唔......", null));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}).AddMicrosoftAccount(microsoftOptions =>
|
|
||||||
{
|
|
||||||
microsoftOptions.ClientId = configuration["Authentication:Microsoft:ClientId"];
|
|
||||||
microsoftOptions.ClientSecret = configuration["Authentication:Microsoft:ClientSecret"];
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,23 +2,19 @@ using System.IdentityModel.Tokens.Jwt;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using AGSS.Models.Entities;
|
using AGSS.Models.Entities;
|
||||||
|
using asg_form;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
|
||||||
namespace AGSS.Utilities;
|
namespace AGSS.Utilities;
|
||||||
|
|
||||||
public class Jwt
|
public class Jwt
|
||||||
{
|
{
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
public Jwt(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string BuildToken(IEnumerable<Claim> claims)
|
public string BuildToken(IEnumerable<Claim> claims, JWTOptions options)
|
||||||
{
|
{
|
||||||
DateTime expires = DateTime.Now.AddDays(int.Parse(_configuration["Jwt:ExpireMinutes"]));
|
DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds);
|
||||||
byte[] keyBytes = Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]);
|
byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey);
|
||||||
var secKey = new SymmetricSecurityKey(keyBytes);
|
var secKey = new SymmetricSecurityKey(keyBytes);
|
||||||
|
|
||||||
var credentials = new SigningCredentials(secKey,
|
var credentials = new SigningCredentials(secKey,
|
||||||
@ -27,18 +23,4 @@ public class Jwt
|
|||||||
signingCredentials: credentials, claims: claims);
|
signingCredentials: credentials, claims: claims);
|
||||||
return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
|
return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GenerateJwtToken(UserModel user,IList<string> roles)
|
|
||||||
{
|
|
||||||
var claims = new List<Claim>();
|
|
||||||
claims.Add(new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()));
|
|
||||||
claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));
|
|
||||||
// var roles = await user.GetRolesAsync(user);
|
|
||||||
foreach (string role in roles)
|
|
||||||
{
|
|
||||||
claims.Add(new Claim(ClaimTypes.Role, role));
|
|
||||||
}
|
|
||||||
string jwtToken = BuildToken(claims);
|
|
||||||
return jwtToken;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -18,7 +18,7 @@
|
|||||||
"ExpireMinutes": "4",
|
"ExpireMinutes": "4",
|
||||||
"Issuer": "https://api.zeronode.cn/api",
|
"Issuer": "https://api.zeronode.cn/api",
|
||||||
"Audience": "https://api.zeronode.cn/api",
|
"Audience": "https://api.zeronode.cn/api",
|
||||||
"Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak"
|
"SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DBContext": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=luolan12323;"
|
"DBContext": "Host=localhost;Port=5432;Database=postgres;Username=postgres;Password=luolan12323;"
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Jwt": {
|
"JWT": {
|
||||||
"ExpireMinutes": "4",
|
"ExpireMinutes": "4",
|
||||||
"Issuer": "https://api.zeronode.cn/api",
|
"Issuer": "https://api.zeronode.cn/api",
|
||||||
"Audience": "https://api.zeronode.cn/api",
|
"Audience": "https://api.zeronode.cn/api",
|
||||||
"Key": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak"
|
"SigningKey": "7wU9bdVfBsX3jITh0w4bgE6fkvLk8pIcZRSUw6r8HQUnXfslYxlx4c4E0ZAIw4Ak"
|
||||||
},
|
},
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DBContext": "Host=1Panel-postgresql-auKB;Port=5432;Database=zeronode;Username=zeronode;Password=luolan12323;"
|
"DBContext": "Host=1Panel-postgresql-auKB;Port=5432;Database=zeronode;Username=zeronode;Password=luolan12323;"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user