您的位置:首页 > 房产 > 家装 > 在线式crm_上海闵行官网_站内推广_个人网站制作

在线式crm_上海闵行官网_站内推广_个人网站制作

2025/4/21 12:07:58 来源:https://blog.csdn.net/weixin_42067536/article/details/144645416  浏览:    关键词:在线式crm_上海闵行官网_站内推广_个人网站制作
在线式crm_上海闵行官网_站内推广_个人网站制作

文章目录

  • 项目地址
  • 一、Authentication(身份认证)
    • 1.1 配置环境(解决类库包无法引用)
    • 1.2 使用Authentication控制Controller的访问
    • 1.3 获取User的Context
      • 1.3.1 在Application下创建User文件夹
        • 1. 创建`User.cs` record类封装角色信息
        • 2. 创建`UserContext.cs`提供接口给程序使用
        • 3. 注册IUserContext接口到服务里
    • 1.4 添加自己属性在User里
      • 1.4.1 给dbo.AspNetUsers添加字段
      • 1.4.2 添加IdentityController
      • 1.4.3 添加Command和Handler
        • 1. Command
        • 2. handler
  • 二、Authorization(授权)
    • 2.1 添加角色
    • 2.2 根据角色分配功能
      • 2.1.1 简单的授权
    • 2.3 添加权限用户的api
      • 2.3.1 添加管理用户的controller
      • 2.3.2 添加Command 和Handler
        • 1. Command
        • 2.Handler
    • 2.4 删除权限
      • 2.4.1 删除权限的Controller
      • 2.4.2 Command和Handler
        • 1. Command
        • 2. Handler


项目地址

  • 教程作者:
  • 教程地址:
  • 代码仓库地址:
  • 所用到的框架和插件:
dbt 
airflow

一、Authentication(身份认证)

回答“你是谁”的问题

1.1 配置环境(解决类库包无法引用)

  1. Restaurants.Domain层安装
 <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.11" />
  1. Restaurants.Domain层的Entities文件夹下创建User实体
using Microsoft.AspNetCore.Identity;namespace Restaurants.Domain.Entities
{public class User:IdentityUser{}
}
  1. Restaurants.Infrastructure层的Persistence文件夹里DbContext继承改为 IdentityDbContext<User>

在这里插入图片描述

  1. 在Extensions里进行注册
 services.AddIdentityApiEndpoints<User>().AddEntityFrameworkStores<RestaurantsDbContext>();
  1. 在引入AddIdentityApiEndpoints时,一直无法引入,原因是:在类库项目中不能直接引用WebApplicationBuilder、ApplicationBuilder等类,这些类位于Microsoft.ASPNetCore程序集中,但是无法通过Nuget包引用

在这里插入图片描述

  1. 在程序入口注册服务

app.MapGroup("api/identity").MapIdentityApi<User>();
  1. EF将User表写入数据库在类库Restaurants.Infrastructure
add-migration IdentityAdded
update-database
  1. 迁移成功后,数据库里就有了权限表
    在这里插入图片描述
  2. 发送一个post请求,注册一个用户

在这里插入图片描述

1.2 使用Authentication控制Controller的访问

  1. Restaurants.API层的Extensions文件夹 里注册服务

在这里插入图片描述

  1. 在需要添加验证的Controller类上面添加[Authorize],如果类里有不需要验证就可以访问的api,在该controller上添加[AllowAnonymous]

在这里插入图片描述
3. 设置成功后,当访问https://localhost:7044/api/restaurants/1报错401Unauthorized; 但是访问https://localhost:7044/api/restaurants可以获取所有restaurants的列表

1.3 获取User的Context

1.3.1 在Application下创建User文件夹

  • 创建User文件用来管理和获取权限中的User信息
    在这里插入图片描述
1. 创建User.cs record类封装角色信息
  • 将用户的Id, Email , Roles,封装到CurrentUser类里,并且通过IsInRole方法,检查用户的角色集合中是否包含指定的角色。返回true 或者 false
namespace Restaurants.Application.User
{public record CurrentUser(string Id, string Email, IEnumerable<string> Roles){public bool IsInRole(string role) => Roles.Contains(role);}
}
2. 创建UserContext.cs提供接口给程序使用
  • 从当前 HTTP 请求的上下文中获取用户的身份信息(CurrentUser),并提供一个接口 IUserContext 供应用程序使用。
  • 主要逻辑:
    1. 获取IHttpContextAccessor服务httpContextAccessor
    2. 通过httpContextAccessor服务获取到HttpContext的User信息;
    3. 判断user信息,然后获取我们需要的内容;
    4. 将需要内容 new一个CurrentUser类;
    5. 创建一个IUserContext接口,该接口的功能,作用时注册到服务里,这样程序的任何地方只需要获取服务就可以获得CurrentUser的信息;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
namespace Restaurants.Application.User
{public interface IUserContext{CurrentUser? GetCurrentUser();}public class UserContext : IUserContext{private readonly IHttpContextAccessor httpContextAccessor;public UserContext(IHttpContextAccessor httpContextAccessor){this.httpContextAccessor = httpContextAccessor;}public CurrentUser? GetCurrentUser(){var user = httpContextAccessor?.HttpContext?.User;if (user == null){throw new InvalidOperationException("User context is not present");}if (user.Identity == null || !user.Identity.IsAuthenticated){return null;}var userId = user.FindFirst(c => c.Type == ClaimTypes.NameIdentifier)!.Value;var email = user.FindFirst(c => c.Type == ClaimTypes.Email)!.Value;var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role)!.Select(c => c.Value);return new CurrentUser(userId, email, roles);}}
}
3. 注册IUserContext接口到服务里
  • 在Application的Extensions文件里注册 IUserContext的接口

在这里插入图片描述

1.4 添加自己属性在User里

1.4.1 给dbo.AspNetUsers添加字段

  • 现在我们的User使用的Identity自己定义,如果我们需要给User添加例如生日,国籍,等其他信息,就需要扩展
  1. Domian的Entities(Model)层里创建User.cs,表示自定义的User,继承IdentityUser的接口
using Microsoft.AspNetCore.Identity;namespace Restaurants.Domain.Entities
{public class User:IdentityUser{public DateOnly? DateOfBirth { get; set; }public string? Nationality { get; set; }}
}
  1. 在Infrustructure层执行迁移,添加的字段加入到表里

1.4.2 添加IdentityController

  • 创建IdentitiesController.cs控制器,用来处理IdentityUser的增删改查
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Restaurants.Application.Users.Commands.UpdateUserDetials;namespace Restaurants.API.Controllers
{[ApiController][Route("api/identity")]public class IdentitiesController: ControllerBase{private readonly IMediator mediator;public IdentitiesController(IMediator mediator){this.mediator = mediator;}[HttpPatch("user")][Authorize]public async Task<ActionResult> UpdateUserDetails(UpdateUserDetailsCommand command){await mediator.Send(command);return NoContent();}}
}

1.4.3 添加Command和Handler

在这里插入图片描述

1. Command
  • 添加UpdateUserDetailsCommand.cs文件,表示需要更新需要传递的属性
using MediatR;namespace Restaurants.Application.Users.Commands.UpdateUserDetials
{public class UpdateUserDetailsCommand : IRequest{public DateOnly? DateOfBirth { get; set; }public string? Nationality { get; set; }public UpdateUserDetailsCommand(DateOnly dateOfBirth, string nationality){DateOfBirth = dateOfBirth;Nationality = nationality;}}
}
2. handler
  • 创建UpdateUserDetailsCommandHandler.cs 需要注意的是:
    1. 获取的是private readonly IUserStore<User> userStore;服务;
    2. IUserStore<User> userStore里获取当前登录的用户信息;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Restaurants.Domain.Entities;
using Restaurants.Domain.Exceptions;namespace Restaurants.Application.Users.Commands.UpdateUserDetials
{public class UpdateUserDetailsCommandHandler : IRequestHandler<UpdateUserDetailsCommand>{private readonly ILogger<UpdateUserDetailsCommandHandler> logger;private readonly IUserContext userContext;//是 ASP.NET Core Identity 提供的一个接口,定义了用于管理用户实体的基础存储操作。它是实现用户数据存储和管理的核心接口之一private readonly IUserStore<User> userStore;public UpdateUserDetailsCommandHandler(ILogger<UpdateUserDetailsCommandHandler> logger,IUserContext userContext,IUserStore<User> userStore){this.logger = logger;this.userContext = userContext;this.userStore = userStore;}public async Task Handle(UpdateUserDetailsCommand request, CancellationToken cancellationToken){logger.LogInformation("Update user details command handler");//1.获取当前用户var user = userContext.GetCurrentUser();//2.根据用户Id查找用户var dbUser = await userStore.FindByIdAsync(user!.Id, cancellationToken);if (dbUser == null){throw new NotFoundException("User not found");}//3.更新用户信息dbUser.DateOfBirth = request.DateOfBirth;dbUser.Nationality = request.Nationality;//4.更新数据库await userStore.UpdateAsync(dbUser, cancellationToken);}}
}

二、Authorization(授权)

回答“回答的是“你能做什么”的问题”

2.1 添加角色

  1. 在餐厅系统里,我们需要添加三个不同的角色:用户,餐厅老板,以及管理员
  • 在Domain里创建Constants文件夹存放常量
  1. 将三个角色通过Seed添加到dbo.AspNetRoles表里

  2. 添加成功后,

在这里插入图片描述
4. 通过注册接口,将三个角色注册https://localhost:7044/api/identity/register

{"email":"user1@test.com","password":"Password1!"
}
  1. 给每个用户分配权限在AspNetUserRoles表,手动插入
  insert into AspNetUserRoles(UserId,RoleId)VALUES('aa18d542-ec4c-4d53-a709-f087a0218ee9','23fa674e-405b-4c5d-928f-d2aa3bfdd9f6'),('30ad7ebe-6fb6-45fc-9ca4-d09c83df78e8','f7df975a-48dc-44b9-b047-619528fea585'),('6cd69086-109f-4071-bc10-b528056a76f0','7bc860f9-b469-4df1-bc3f-ac7e1a459681')

2.2 根据角色分配功能

2.1.1 简单的授权

  1. 创建CreateRestaurant控制器上分配,只有Owner权限的人才可以访问该Api

  2. 登录之后,创建一个restaurants,发送请求

{"Name": "Tasty Tests3","Description": "A cozy restaurant serving a variety of delicious dishes.","Category": "Indian","HasDelivery": true,"ContactEmail": "info@test.com","ContactNumber": "555-1234","City": "New York","Street": "123 Main Street","PostalCode": "10-010"
}
  1. 此时,还是403,因为我们没有给服务添加Roles的给功能,在Infrastructure/Extensions/ServiceCollectionExtensions.cs里,注册服务
    在这里插入图片描述

2.3 添加权限用户的api

2.3.1 添加管理用户的controller

``

    [HttpPost("userRole")][Authorize(Roles = UserRoles.Admin)]public async Task<IActionResult> AssignUserRole(AssignUserRoleCommand command){await mediator.Send(command);return NoContent();}

2.3.2 添加Command 和Handler

1. Command

AssignUserRoleCommand.cs

using MediatR;
namespace Restaurants.Application.Users.Commands.AssignUserRole;
public class AssignUserRoleCommand : IRequest
{public string UserEmail { get; set; } = default!;public string RoleName { get; set; } = default!;
}
2.Handler

AssignUserRoleCommandHandler.cs

using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Restaurants.Domain.Entities;
using Restaurants.Domain.Exceptions;
namespace Restaurants.Application.Users.Commands.AssignUserRole;
public class AssignUserRoleCommandHandler(ILogger<AssignUserRoleCommandHandler> logger,UserManager<User> userManager,RoleManager<IdentityRole> roleManager) : IRequestHandler<AssignUserRoleCommand>
{public async Task Handle(AssignUserRoleCommand request, CancellationToken cancellationToken){logger.LogInformation("Assigning user role: {@Request}", request);var user = await userManager.FindByEmailAsync(request.UserEmail)?? throw new NotFoundException(nameof(User), request.UserEmail);var role = await roleManager.FindByNameAsync(request.RoleName)?? throw new NotFoundException(nameof(IdentityRole), request.RoleName);await userManager.AddToRoleAsync(user, role.Name!);}
}

2.4 删除权限

2.4.1 删除权限的Controller

  • Restaurants.API/Controllers/IdentityController.cs
    [HttpDelete("userRole")][Authorize(Roles = UserRoles.Admin)]public async Task<IActionResult> UnassignUserRole(UnassignUserRoleCommand command){await mediator.Send(command);return NoContent();}

2.4.2 Command和Handler

1. Command
  • Restaurants.Application/Users/Commands/UnassignUserRole/UnassignUserRoleCommand.cs
using MediatR;
namespace Restaurants.Application.Users.Commands.UnassignUserRole;
public class UnassignUserRoleCommand : IRequest
{public string UserEmail { get; set; } = default!;public string RoleName { get; set; } = default!;
}
2. Handler
  • Restaurants.Application/Users/Commands/UnassignUserRole/UnassignUserRoleCommandHandler.cs
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Restaurants.Application.Users.Commands.AssignUserRole;
using Restaurants.Domain.Entities;
using Restaurants.Domain.Exceptions;
namespace Restaurants.Application.Users.Commands.UnassignUserRole;
public class UnassignUserRoleCommandHandler(ILogger<UnassignUserRoleCommandHandler> logger,UserManager<User> userManager,RoleManager<IdentityRole> roleManager) : IRequestHandler<UnassignUserRoleCommand>
{public async Task Handle(UnassignUserRoleCommand request, CancellationToken cancellationToken){logger.LogInformation("Unassigning user role: {@Request}", request);var user = await userManager.FindByEmailAsync(request.UserEmail)?? throw new NotFoundException(nameof(User), request.UserEmail);var role = await roleManager.FindByNameAsync(request.RoleName)?? throw new NotFoundException(nameof(IdentityRole), request.RoleName);await userManager.RemoveFromRoleAsync(user, role.Name!);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com