Fügen Sie dem Benutzer die Anmeldung des Datenbank nach der Anmeldung nach dem Benutzer Ansprüche hinzuC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Fügen Sie dem Benutzer die Anmeldung des Datenbank nach der Anmeldung nach dem Benutzer Ansprüche hinzu

Post by Anonymous »

Ich habe eine Blazor -Serverside -Anwendung, in der ich Authentifizierung hinzufüge. Postauthentifizierung, überprüfen Sie, ob sich der Benutzer in der Datenbank befindet.

Wenn dies nicht der Fall ist, möchte ich sie hinzufügen. AuthenticationStateProvider < /code> einige Ansprüche aus der Datenbank anhängen. /> In meinen Compenetns ziehe ich das AuthenticationState über einen CascadingParameter
zurück.

Code: Select all

[CascadingParameter]
public Task? AuthState { get; set; }
Das Problem ist, dass bei der Auslösung der Anmeldung von einem Authentifizierungshandler das _initialValueFactory in CascadingValuesource mit dem neuen authentcitaionstate überschreiben. aufgerufen. folgenden Code, um meine Authentifizierung hinzuzufügen < /p>
program.cs

Code: Select all

internal async Task CreateApplication()
{
var builder = WebApplication.CreateBuilder(args);
// ... Some code to set fields

// ...  Adding services

// Add Blazor
_services
.AddRazorComponents()
.AddInteractiveWebAssemblyComponents()
.AddInteractiveServerComponents();
_services.AddRadzenComponents();
_services.AddServerSideBlazor();

AddAuthentication();

var app = builder.Build();

app
.UseStaticFiles()
.UseRouting()
.UseAntiforgery();

app.MapRazorComponents()
.AddInteractiveWebAssemblyRenderMode()
.AddInteractiveServerRenderMode();

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

await app.RunAsync();
}
< /code>
private void AddAuthentication()
{
// Check if authentication is disabled
if (_environment.IsDevelopment())
{
_services.AddAuthentication(nameof(DummyAuthenticationHandler))
.AddScheme(nameof(DummyAuthenticationHandler), _ => {});
}
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;
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post