Как передать данные из AuthCookie в ClaimsPrincipal в настраиваемом CustomAuthStateProvider?
Мы используем последнюю версию Blazor WebAssembly в сочетании с API-контроллерами. Мы хотим использовать проверку подлинности с помощью форм для проверки входа в систему в Active Directory. Когда проверка прошла успешно, мы создаем AuthCooki. Проблема: мы не знаем, как обрабатывать AuthCookie в пользовательскойAuthenticationStateProvider
:
AuthenticationStateProvider (на стороне клиента):
public class CustomAuthStateProvider : AuthenticationStateProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
// How to get the data from the Authcookie here (SamAccountName or Token) and pass them to the lClaimsPrincipal?
var lClaimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity { /* ??? */});
return Task.FromResult(new AuthenticationState(lClaimsPrincipal));
}
}
Пользователь отправляет свои учетные данные через форму контроллеру. Контроллер проверяет учетные данные по активному каталогу и устанавливает файл cookie аутентификации:
[Route("[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
[HttpPost]
public async Task<AdUser> Login(Credentials pCredentials)
{
// [...] Authentication validation against active directory here here [...]
var lClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, "MySamAccountName"),
};
// set cookie
var lClaimsIdentity = new ClaimsIdentity(lClaims, CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(lClaimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddYears(1),
RedirectUri = this.Request.Host.Value
});
// [...]
}
}
Файл App.razor (на стороне клиента):
<CascadingAuthenticationState>
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<AuthorizeRouteView RouteData="@routeData"
DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</CascadingAuthenticationState>
Зарегистрируйте аутентификацию cookie в startup.cs (на стороне сервера)
public class Startup
{
[...]
public void ConfigureServices(IServiceCollection services)
{
// [...]
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(); // This line is required for the authentication cookie
// [...]
}
}
Index.razor (на стороне клиента)
@code {
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask { get; set; }
private async Task LogUsername()
{
var authState = await authenticationStateTask;
var user = authState.User;
}
}
<AuthorizeView>
<Authorized>
<h1>Hello, @context.User.Identity.Name!</h1>
<p>You can only see this content if you're authenticated.</p>
</Authorized>
<NotAuthorized>
<h1>Authentication Failure!</h1>
<p>You're not signed in.</p>
</NotAuthorized>
</AuthorizeView>
Program.cs (на стороне клиента)
public class Program
{
public static async Task Main(string[] args)
{
// [...]
// authentication / authorization
builder.Services.AddScoped<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddOptions();
builder.Services.AddAuthorizationCore();
// [...]
}
}