Добавить претензии к пользователю из базы данных постC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Добавить претензии к пользователю из базы данных пост

Сообщение Anonymous »

у меня есть приложение Blazor Serverside, где я добавляю аутентификацию. После аутентификации, проверьте, находится ли пользователь в базе данных.

Если это не так, я хочу добавить их.

AuthenticationStateProvider < /code> для добавления некоторых претензий из базы данных.
У меня было вчера, что я работал с OpenID Connectrion.
После этого я добавил DummyAuthenticationHandler и перемещал вещи вокруг. /> В моих Compenetns я поиск AuthenticationState через CascadingParameter
[CascadingParameter]
public Task? AuthState { get; set; }

Проблема заключается в том, что когда вход в систему запускается из аутентификации -handler , он перезаписывает _initialValueFactory в CascadingValuesource с новым AuthencitaionState , и Code INTECTITATERTICATERSTATERPRIDER {});
}
else
{
_services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Authority = _options.Authentication.Authority;
options.ClientId = _options.Authentication.ClientId;
options.ClientSecret = _options.Authentication.ClientSecret;
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.MapInboundClaims = false;
options.TokenValidationParameters.NameClaimType = OAuthClaim.Name;
});
}
_services.AddAuthorization();
_services.AddCascadingAuthenticationState();
_services.AddScoped();
}
< /code>
DummyAuthenticationHandler < /h3>

public class DummyAuthenticationOptions : AuthenticationSchemeOptions;

public class DummyAuthenticationHandler(
IOptionsMonitor options,
ILoggerFactory logger,
UrlEncoder encoder
) : AuthenticationHandler(options, logger, encoder),
IAuthenticationSignOutHandler
{

protected override async Task HandleAuthenticateAsync()
{
await Task.CompletedTask;
var cookie = Request.Cookies.FirstOrDefault(c => c.Key == nameof(DummyAuthenticationHandler));
if (cookie.Value is null)
{
return AuthenticateResult.NoResult();
}

var cookieValue = DecodeFromBase64(cookie.Value);
var claims = JsonSerializer.Deserialize(cookieValue);

var claimsIdentity = new ClaimsIdentity(claims!.Select(c => new Claim(c.Key, c.Value)), Scheme.Name);
var ticket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), Scheme.Name);

return AuthenticateResult.Success(ticket);
}

protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
List claims =
[
new(OAuthClaim.SubjectId, "__404_user_not_found__"),
new(OAuthClaim.Name, "Middle McMiddleware"),
new(OAuthClaim.Email, "git@gud.commit"),
new(OAuthClaim.JsonTokenIdentifier, "GUID_NOT_FOUND_EXCEPTION"),
new(OAuthClaim.AuthenticationMethodsReferences, "pwd"),
new(OAuthClaim.IdentityProvider, "'; DROP TABLE users; '"),
new(OAuthClaim.PreferredUsername, "git@gud.commit"),
new(OAuthClaim.AuthTime, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()),
new(OAuthClaim.GivenName, "Middle"),
new(OAuthClaim.FamilyName, "McMiddleware"),
];

var base64Claims = EncodeToBase64(JsonSerializer.Serialize(claims));

Response.Cookies.Append(
nameof(DummyAuthenticationHandler),
base64Claims,
new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.None,
Path = "/",
Expires = DateTimeOffset.UtcNow.AddDays(1)
}
);

if (properties.RedirectUri is not null)
{
Response.Redirect(properties.RedirectUri);
}

return Task.CompletedTask;
}

public Task SignOutAsync(AuthenticationProperties? properties)
{
Response.Cookies.Delete(nameof(DummyAuthenticationHandler));
if (properties?.RedirectUri is not null)
{
Response.Redirect(properties.RedirectUri);
}
return Task.CompletedTask;
}

private static string EncodeToBase64(string text)
{
var textBytes = Encoding.UTF8.GetBytes(text);
return Convert.ToBase64String(textBytes);
}

private static string DecodeFromBase64(string base64Text)
{
var textBytes = Convert.FromBase64String(base64Text);
return Encoding.UTF8.GetString(textBytes);
}

}

< /code>
CustomAuthenticationStateProvider < /h3>
public class CustomAuthenticationStateProvider(
IDbContextFactory dbFactory
) : ServerAuthenticationStateProvider
{
public override async Task GetAuthenticationStateAsync()
{
var authState = await base.GetAuthenticationStateAsync();
var claimsUser = authState.User;

// Get your custom data - in this case some roles
var dbUser = await UpsertUser(claimsUser);

// add some new identities to the Claims Principal
claimsUser.AddIdentity(new ClaimsIdentity([
new Claim("user_id", dbUser.UserId.ToString()),
]));

// return the modified principal
return new AuthenticationState(claimsUser);
}

private async Task UpsertUser(ClaimsPrincipal claimUser)
{
var subjectId = claimUser.Claims.FirstOrDefault(c => c.Type == OAuthClaim.SubjectId)?.Value;
if (string.IsNullOrEmpty(subjectId))
{
throw new ArgumentException("Subject ID is missing from claims");
}

// Get the user from the database
await using var dbContext = await dbFactory.CreateDbContextAsync();
var user = await dbContext.Users
.AsNoTracking()
.FirstOrDefaultAsync(u => u.SubjectId == subjectId);

if (user == null)
{
user = new User
{
SubjectId = subjectId,
FirstName = claimUser.FindFirstValue(OAuthClaim.GivenName) ?? "Unknown",
LastName = claimUser.FindFirstValue(OAuthClaim.FamilyName) ?? "Unknown",
Email = claimUser.FindFirstValue(OAuthClaim.Email) ?? "Unknown",
};
dbContext.Users.Add(user);
await dbContext.SaveChangesAsync();
dbContext.Entry(user).State = EntityState.Detached;
}

return user;
}
}


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

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

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

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

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

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

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