Я хотел бы использовать JWT с ASP.NET Core 2.1 с MSSQL.Я нашел полезный код для моей цели в Интернете.Позвольте мне поделиться подробностями об этом проекте.Работает нормально, но использует структуру IdentityUser (класс Microsoft.AspNetCore.Identity). Я бы хотел использовать Модель моей пользовательской пользовательской таблицы вместо класса Identity. Потому что в соответствии с найденным примером: мы создаем файл Migration.cs, а затем обновляем базу данных с записью «update-базы данных »в консоли диспетчера пакетов.Это действие создает множество таблиц в базе данных MSSQL: AspNetRoleClaims, AspNetRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserRoles, AspNetUsers, AspNetUserTokens.Я не хочу их использовать.
Я создал каталог с именем'Данные'.И я создал файл ApplicationDbContext.cs
в этом каталоге.
Вот файл ApplicationDbContext.cs
:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace JwtAuthentication.Data
{
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
#region Seed Data
builder.Entity<IdentityRole>().HasData
(
new { Id = "1", Name = "Admin", NormalizedName = "ADMIN"},
new { Id = "2", Name = "Customer", NormalizedName = "CUSTOMER" }
);
#endregion
}
}
}
Я создал еще один каталог с именем ViewModels
в корневом каталоге.И я создал LoginViewModel.cs
и RegisterViewModel.cs
файлы в этом каталоге ViewModels
.
Вот файл LoginViewModel.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace JwtAuthentication.ViewModels
{
public class LoginViewModel
{
public string Username { get; set; }
public string Password { get; set; }
}
}
Вот файл RegisterViewModel.cs
:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace JwtAuthentication.ViewModels
{
public class RegisterViewModel
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
}
Вот файл appsettings.json
:
{
"ConnectionStrings": {
"DefaultConnection": "data source=****;initial catalog=myTestDatabase;persist security info=True;user id=sa;password=*****;MultipleActiveResultSets=True"
},
"Jwt": {
"Site": "http://www.security.org",
"SigningKey": "HelpMeHelpMeHelpMeHelpMeHelpMe",
"ExpiryInMinutes": "60"
},
"Logging":
{
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
И я создал файл контроллера: AuthController.cs
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;
using JwtAuthentication.ViewModels;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace JwtAuthentication.Controllers
{
public class AuthController : Controller
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IConfiguration _configuration;
public AuthController(UserManager<IdentityUser> userManager, IConfiguration configuration)
{
_userManager = userManager;
_configuration = configuration;
}
//public IActionResult Index()
//{
// return View();
//}
[Route("login")]
[HttpPost]
public async Task<ActionResult> Login([FromBody] LoginViewModel model)
{
var user = await _userManager.FindByNameAsync(model.Username);
if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
{
#region if scope
var claim = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName)
};
var signinKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SigningKey"]));
int expiryInMinutes = Convert.ToInt32(_configuration["Jwt:ExpiryInMinutes"]);
var token = new JwtSecurityToken(
issuer: _configuration["Jwt:Site"],
audience: _configuration["Jwt:Site"],
expires: DateTime.UtcNow.AddMinutes(expiryInMinutes),
signingCredentials: new SigningCredentials(signinKey, SecurityAlgorithms.HmacSha256)
);
return Ok(
new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
}
);
#endregion
}
return Unauthorized();
}
[Route("register")]
[HttpPost]
public async Task<ActionResult> InsertUser([FromBody] RegisterViewModel model)
{
var user = new IdentityUser
{
Email = model.Email,
UserName = model.Email,
SecurityStamp = Guid.NewGuid().ToString()
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, "Customer");
}
return Ok(new { Username = user.UserName });
}
}
}
Вот это Startup.cs
file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JwtAuthentication.Data;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
namespace JwtAuthentication
{
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.AddDbContext<ApplicationDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>(
option =>
{
option.Password.RequireDigit = false;
option.Password.RequiredLength = 6;
option.Password.RequireNonAlphanumeric = false;
option.Password.RequireUppercase = false;
option.Password.RequireLowercase = false;
}
).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
services.AddAuthentication(
option => {
option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
option.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}
).AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = true;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["Jwt:Site"],
ValidIssuer = Configuration["Jwt:Site"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SigningKey"]))
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}
}
}
Вот файл ValuesController.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace JwtAuthentication.Controllers
{
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
Я бы хотел использовать модель моей пользовательской пользовательской таблицы вместо класса Identity.Я пытался использовать модель MyUserTable.Но я не мог закончить это.