Claim
这个登机牌每一个信息就是claim
机票和登机牌是各司其职的。
添加
var claims = new[] { // sub new Claim(JwtRegisteredClaimNames.Sub, "fake_user_id"), new Claim(ClaimTypes.Role,"Admin") };
修改action
[Authorize(Roles = "Admin")]
-----------------------------------------------------------------------------
添加引用:Microsoft.AspNetCore.Identity.EntityFrameworkCore
修改dbContext:
public class AppDbContext : IdentityDbContext<IdentityUser> //DbContext
修改startup.cs
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; }
}
执行 add-migration idenittyMigration
update-database
添加identity的相关表(用户表,角色表,登陆表)如下图:
最后放一下完整的authenticatecontroller和startup.cs
using FakeXiecheng.API.Dtos; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace FakeXiecheng.API.Controllers { [Route("auth")] [ApiController] [AllowAnonymous]// 任何人都可以访问 public class AuthenticateController : ControllerBase { private readonly IConfiguration _iconfiguration; private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager; public AuthenticateController( IConfiguration configuration, UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager) { _iconfiguration = configuration; _userManager = userManager; _signInManager = signInManager; } [HttpPost("login")] public async Task<IActionResult> login([FromBody] LoginDto loginDto) { // 1验证用户名密码 var loginResult = await _signInManager.PasswordSignInAsync( loginDto.Email, loginDto.Password, false, false ); if (!loginResult.Succeeded) { return BadRequest(); } var user = await _userManager.FindByIdAsync(loginDto.Email); // 2创建jwt // header var signingAlgorithm = SecurityAlgorithms.HmacSha256; // payload var claims = new List<Claim> { // sub new Claim(JwtRegisteredClaimNames.Sub, user.Id), //new Claim(ClaimTypes.Role,"Admin") }; // 增加角色 var roleNames = await _userManager.GetRolesAsync(user); foreach (var roleName in roleNames) { var roleClaim = new Claim(ClaimTypes.Role, roleName); claims.Add(roleClaim); } // signiture var secretByte = Encoding.UTF8.GetBytes(_iconfiguration["Authentication:Secretkey"]); var signingKey = new SymmetricSecurityKey(secretByte); var signingCredentials = new SigningCredentials(signingKey, signingAlgorithm); var token = new JwtSecurityToken( issuer: _iconfiguration["Authentication:Issuer"], audience: _iconfiguration["Authentication:Audience"], claims, notBefore: DateTime.UtcNow, expires: DateTime.UtcNow.AddDays(1), signingCredentials ); var tokenStr = new JwtSecurityTokenHandler().WriteToken(token); // 3..return token return Ok(tokenStr); } [AllowAnonymous] [HttpPost("register")] public async Task<IActionResult> Resgister([FromBody] RegisterDto registerDto) { // 1.使用用户名创建用户对象 var user = new IdentityUser() { UserName = registerDto.Email, Email = registerDto.Email }; // 2.hash密码,保存用户 var result = await _userManager.CreateAsync(user); if (!result.Succeeded) { return BadRequest(); } // 3.return return Ok(); } } }
namespace FakeXiecheng.API { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<AppDbContext>(); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { var secretByte = Encoding.UTF8.GetBytes(Configuration["Authentication:Secretkey"]); options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidIssuer = Configuration["Authentication:Issuer"], ValidateAudience = true, ValidAudience = Configuration["Authentication:Audience"], ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(secretByte) }; }); services.AddControllers(setupAction => { setupAction.ReturnHttpNotAcceptable = true; }) .AddNewtonsoftJson(setupAction => { setupAction.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }) .AddXmlDataContractSerializerFormatters() .ConfigureApiBehaviorOptions(setupAction => { setupAction.InvalidModelStateResponseFactory = context => { var problemDetail = new ValidationProblemDetails(context.ModelState) { Type = "", Title = "数据验证失败", Status = StatusCodes.Status402PaymentRequired, Detail = "请看详细信息", Instance = context.HttpContext.Request.Path }; problemDetail.Extensions.Add("traceId", context.HttpContext.TraceIdentifier); return new UnprocessableEntityObjectResult(problemDetail) { ContentTypes = { "application/problem+json" } }; }; }) ; services.AddTransient<ITouristRouteRepository, TouristRouteRepository>(); services.AddDbContext<AppDbContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("delfault")); }); // 加载automapper的pofile的文件 services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 你在那 app.UseRouting(); // 你是谁 app.UseAuthentication(); // 你可以干什么 app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }