Я создаю эту веб-страницу на Angular с .NET в качестве моего бэкэнда. Все работало просто отлично, но сегодня (внезапно) я получаю несанкционированные ошибки (401). Когда я удаляю свою авторизацию, я получаю внутренние ошибки сервера (что означает, что «User.Identity.Name») не работает. Итак, я предполагаю, что есть проблема с моим JWT
Я попытался удалить заголовки авторизации. Но это дало мне внутреннюю ошибку сервера (500). Работают только те запросы, которые не используют IdentityUser и поэтому [AllowAnonymous]
Я понятия не имею, в чем может быть проблема, поэтому сложно показать какой-то код. Но так как я думаю, что проблема связана с моим JWT, я добавлю некоторый код этого.
Некоторые коды контроллера .NET
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class BierenController : ControllerBase
{
private readonly IBierRepository _bierRepository;
private readonly IGebruikerRepository _gebruikerRepository;
private readonly IBrouwerRepository _brouwerRepository;
public BierenController(IBierRepository bierRepository, IGebruikerRepository gebruikerRepository, IBrouwerRepository brouwerRepository)
{
_bierRepository = bierRepository;
_gebruikerRepository = gebruikerRepository;
_brouwerRepository = brouwerRepository;
}
[HttpGet]
[AllowAnonymous]
public IEnumerable<Bier> GetBieren()
{
return _bierRepository.GetAll().OrderBy(b => b.Naam);
}
[HttpGet("{id}")]
[AllowAnonymous]
public ActionResult<Bier> GetBier(int id)
{
Bier bier = _bierRepository.GetBy(id);
if (bier == null)
return NotFound();
return bier;
}
[HttpPost]
[Authorize(Roles = "Brouwer, Admin")]
public IActionResult PostBier(Bier bier)
{
Brouwer brouwer = _brouwerRepository.GetBy(User.Identity.Name);
brouwer.AddBier(bier);
_brouwerRepository.SaveChanges();
return NoContent();
}
Конфигурация Startup.cs
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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddDbContext<BrouwerContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("BierContext")));
services.AddScoped<IBrouwerRepository, BrouwerRepository>();
services.AddScoped<IBierRepository, BierRepository>();
services.AddScoped<IGebruikerRepository, GebruikerRepository>();
services.AddScoped<IPostRepository, PostRepository>();
services.AddOpenApiDocument(c =>
{
c.Title = "BabAPI";
c.Version = "v1";
c.Description = "De API voor BAB";
c.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT Token", new SwaggerSecurityScheme
{
Type = SwaggerSecuritySchemeType.ApiKey,
Name = "Authorization",
In = SwaggerSecurityApiKeyLocation.Header,
Description = "Copy 'Bearer' + valid JWT token into field" }));
c.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT Token"));
});
services.AddCors(options =>
options.AddPolicy("AllowAllOrigins", builder =>
builder.AllowAnyOrigin()
));
services.AddDefaultIdentity<IdentityUser>(cfg => cfg.User.RequireUniqueEmail = true).AddRoles<IdentityRole>().AddEntityFrameworkStores<BrouwerContext>();
services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
options.User.RequireUniqueEmail = true;
});
services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false; x.SaveToken = true; x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = true
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseMvc();
CreateUserRoles(services).Wait();
app.UseAuthentication();
app.UseSwaggerUi3();
app.UseSwagger();
app.UseCors("AllowAllOrigins");
}
угловой перехватчик аутентификации
export class AuthenticationInterceptor implements HttpInterceptor {
constructor(private authService: AuthenticationService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService.token.length) {
const clonedRequest = req.clone({
headers: req.headers.set('Authorization', `Bearer ${this.authService.token}`)
});
return next.handle(clonedRequest);
}
return next.handle(req);
}
}
.NET Логин / Регистрация / Создание токена
[AllowAnonymous]
[HttpPost]
public async Task<ActionResult<String>> CreateToken(LoginDTO model)
{
var user = await this._userManager.FindByNameAsync(model.GebruikersNaam);
if(user == null)
{
user = await this._userManager.FindByEmailAsync(model.GebruikersNaam);
}
if (user != null)
{
var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, false);
if (result.Succeeded)
{
string token = await GetTokenAsync(user);
return Created("", token);
}
}
return BadRequest();
}
private async Task<string> GetTokenAsync(IdentityUser user)
{
var role = await _userManager.GetRolesAsync(user);
IdentityOptions _options = new IdentityOptions();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[] {
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
new Claim(_options.ClaimsIdentity.RoleClaimType, role.FirstOrDefault())
}),
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256),
Expires = DateTime.Now.AddMinutes(30)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var token = tokenHandler.WriteToken(securityToken);
return token;
}
[AllowAnonymous]
[HttpPost("register")]
public async Task<ActionResult<String>> Register(RegisterDTO model)
{
IdentityUser user = new IdentityUser { UserName = model.GebruikersNaam, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
if (model.Email.ToLower().Equals("admin1@hotmail.com"))
{
Brouwer brouwer = new Brouwer { Naam = model.GebruikersNaam, Email = model.Email };
_brouwerRepository.Add(brouwer);
_brouwerRepository.SaveChanges();
await _userManager.AddToRoleAsync(user, "Admin");
}
else if (model.Email.ToLower().Equals("brouwer1@hotmail.com"))
{
Brouwer brouwer = new Brouwer { Naam = model.GebruikersNaam, Email = model.Email };
_brouwerRepository.Add(brouwer);
_brouwerRepository.SaveChanges();
await _userManager.AddToRoleAsync(user, "Brouwer");
}
else
{
Gebruiker gebruiker = new Gebruiker { Email = model.Email, Gebruikersnaam = model.GebruikersNaam };
_gebruikerRepository.Add(gebruiker);
_gebruikerRepository.SaveChanges();
await _userManager.AddToRoleAsync(user, "User");
}
string token = await GetTokenAsync(user);
return Created("", token);
}
else {
return BadRequest();
}
![Image of the error](https://i.stack.imgur.com/9URph.png)