Core Identity ASP.NET продолжает возвращать 401, несанкционированные на неудачных попытках входа в систему с пользователC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Core Identity ASP.NET продолжает возвращать 401, несанкционированные на неудачных попытках входа в систему с пользовател

Сообщение Anonymous »

Я использую microsoft.aspnetcore.identity.entityframeworkcore и использую конечные точки, доступные в этой библиотеке (вход и регистр). В стандартном сценарии, если пользователь предоставляет неверный пароль во время входа (сразу после регистра), пользователь может повторно повторно и получить токен доступа/обновления по носителю. , Все конечные точки (кроме тех, которые доступны в пакете и в конечной точке моего пользователя), требуют авторизации на основе политики HasProfIleCopleted , которая проверяет претензию isproFiLecOpleted = true . Это означает, что после входа в систему пользователь должен обновить учетную запись через конечную точку API/Users/Update , предоставляя необходимые данные (имя, фамилия, имя пользователя, номер телефона). Если данные правильно предоставлены, и значение isprofileCopletled установлено на true , пользователь получает полный доступ к API.
После обновления профиля я обновляю токен, который позволяет правильно обрабатывать запросы. Однако проблема возникает, когда пользователь входит в правильный адрес электронной почты, но неверный пароль во время входа в систему - последующие попытки входа в систему приводят к несанкционированной ошибке 401, даже если учетная запись не подлежит механизму блокировки (я Увеличение maxfailedaccessattempts и установить repteconfirmedaccount к false в addIdentityApiendPoints опции и т. Д. И все еще ничего ...)
Эта проблема? Я что -то упустил? Какие шаги я должен предпринять, чтобы правильно справиться с этим сценарием? < /P>
Program.cs:
using Serilog;
using ZlecajGo.API.Extensions;
using ZlecajGo.API.Middlewares;
using ZlecajGo.Application.Extensions;
using ZlecajGo.Domain.Entities;
using ZlecajGo.Infrastructure.Extensions;
using ZlecajGo.Infrastructure.Seeders;

var builder = WebApplication.CreateBuilder(args);

builder.AddPresentation();
builder.Services.AddInfrastructure(builder.Configuration);
builder.Services.AddApplication();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

using var scope = app.Services.CreateScope();
var seeder = scope.ServiceProvider.GetRequiredService();
await seeder.SeedAsync(false);

app.UseSerilogRequestLogging();

app.UseMiddleware();

app.UseHttpsRedirection();

app.MapGroup("/api/identity")
.WithTags("Identity")
.MapIdentityApi();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

Log.Information("API started");

app.Run();
< /code>
AddPresentation Метод:
public static void AddPresentation(this WebApplicationBuilder builder)
{
builder.Services.AddAuthentication();

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.Http,
Scheme = "Bearer"
});

c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "bearerAuth"
}
},
[]
}
});
});

builder.Host.UseSerilog((context, logger) =>
{
logger.ReadFrom.Configuration(context.Configuration);
});

builder.Services.AddScoped();
}
< /code>
AddInfrastructure Метод:
public static void AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
var connectionString = configuration.GetConnectionString("ZlecajGoDb");

services.AddDbContext(options =>
options.UseNpgsql(connectionString)
.EnableSensitiveDataLogging());

services.AddIdentityApiEndpoints()
.AddRoles()
.AddClaimsPrincipalFactory()
.AddEntityFrameworkStores();

services.AddAuthorizationBuilder()
.AddPolicy(PolicyNames.HasProfileCompleted, builder =>
builder.RequireClaim(AppClaimTypes.IsProfileCompleted, "True"));

services.AddScoped();

services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
}
< /code>
My principal factory ZlecajGoUserClaimsPrincipalFactory.cs:
using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using ZlecajGo.Domain.Constants;
using ZlecajGo.Domain.Entities;

namespace ZlecajGo.Infrastructure.Authorization;

public class ZlecajGoUserClaimsPrincipalFactory
(
UserManager userManager,
RoleManager roleManager,
IOptions options
)
: UserClaimsPrincipalFactory(userManager, roleManager, options)
{
public override async Task CreateAsync(User user)
{
var id = await GenerateClaimsAsync(user);

if (user.UserName != null)
id.AddClaim(new Claim(AppClaimTypes.UserName, user.UserName));

if (user.FullName != null)
id.AddClaim(new Claim(AppClaimTypes.FullName, user.FullName));

if (user.PhoneNumber != null)
id.AddClaim(new Claim(AppClaimTypes.PhoneNumber, user.PhoneNumber));

if (user.BirthDate != null)
id.AddClaim(new Claim(AppClaimTypes.BirthDate, user.BirthDate.Value.ToString("dd-MM-yyyy")));

id.AddClaim(new Claim(AppClaimTypes.IsProfileCompleted, user.IsProfileCompleted.ToString()));

return new ClaimsPrincipal(id);
}
}
< /code>
Update user endpoint handler UpdateUserCommandHandler.cs:
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using ZlecajGo.Domain.Entities;
using ZlecajGo.Domain.Exceptions;

namespace ZlecajGo.Application.Users.Commands.UpdateUser;

public class UpdateUserCommandHandler
(
ILogger logger,
IUserStore userStore,
IUserContext userContext
)
: IRequestHandler
{
public async Task Handle(UpdateUserCommand request, CancellationToken cancellationToken)
{
var user = userContext.GetCurrentUser();

logger.LogInformation("Updating user with id [{UserId}]", user!.Id);

var dbUser = await userStore.FindByIdAsync(user.Id, cancellationToken)
?? throw new NotFoundException(nameof(User), user.Id);

dbUser.FullName = request.FullName ?? dbUser.FullName;
dbUser.BirthDate = request.BirthDate ?? dbUser.BirthDate;
dbUser.Email = request.Email ?? dbUser.Email;
dbUser.UserName = request.UserName ?? dbUser.UserName;
dbUser.PhoneNumber = request.PhoneNumber ?? dbUser.PhoneNumber;
dbUser.ProfilePictureUrl = request.ProfilePictureUrl ?? dbUser.ProfilePictureUrl;

if (dbUser.IsProfileCompleted == false && dbUser is
{
FullName: not null,
BirthDate: not null,
Email: not null,
UserName: not null,
PhoneNumber: not null
})
{
dbUser.IsProfileCompleted = true;
}

await userStore.UpdateAsync(dbUser, cancellationToken);
}
}
< /code>
UserContext.cs Чтобы получить текущего пользователя:
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using ZlecajGo.Domain.Constants;

namespace ZlecajGo.Application.Users;

public interface IUserContext
{
CurrentUser? GetCurrentUser();
}

public class UserContext(IHttpContextAccessor httpContextAccessor) : IUserContext
{
public CurrentUser? GetCurrentUser()
{
var user = httpContextAccessor.HttpContext?.User;

if (user is null)
throw new InvalidOperationException("User context is not present!");

if (user.Identity is 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 userName = user.FindFirst(c => c.Type == AppClaimTypes.UserName)!.Value;
var fullName = user.FindFirst(c => c.Type == AppClaimTypes.FullName)?.Value;
var phoneNumber = user.FindFirst(c => c.Type == AppClaimTypes.PhoneNumber)?.Value;
var birthDateString = user.FindFirst(c => c.Type == AppClaimTypes.BirthDate)?.Value;
var birthDate = birthDateString is null ? (DateOnly?)null : DateOnly.ParseExact(birthDateString, "dd-MM-yyyy");
var isProfileCompleted = bool.Parse(user.FindFirst(c => c.Type == AppClaimTypes.IsProfileCompleted)!.Value);

return new CurrentUser(userId, email, userName, fullName, phoneNumber, birthDate, isProfileCompleted);
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... n-attempts
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»