Как передать данные из 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();

        // [...]
    }
}

0 ответов

Другие вопросы по тегам