Это похоже на IdentityServer4 заставить пользователя повторно вводить учетные данные, но решение там говорит об использовании prompt=login строки запроса в URL /authorize, которая работает, но также позволяет скрытным пользователям удалить ее. Кроме того, поскольку я не использую .AddOpenIdConnect(), предложение использовать OnRedirectToIdentityProvider не относится ко мне.

Итак, как мы можем заставить пользователя всегда вводить учетные данные, не полагаясь на prompt=login в строке запроса?


Вот моя основная настройка IdentityServer4:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    var builder = services.AddIdentityServer()
        .AddInMemoryIdentityResources(Config.GetIdentityResources())
        .AddInMemoryApiResources(Config.GetApis())
        .AddInMemoryClients(Config.GetClients());

    builder.AddDeveloperSigningCredential();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseFileServer();
    app.UseIdentityServer();
    app.UseMvc();
}

Когда на моей странице входа есть только кнопки «ОК» и «Отмена» (мне все равно, кто из пользователей вошел в систему, только чтобы аутентификация была в порядке или нет), и контроллер выполняет следующие действия при аутентификации пользователя:

public async Task<IActionResult> Post(AuthenticateViewModel model, string button)
{
    var context = await _interaction.GetAuthorizationContextAsync(model.ReturnUrl);

    if (button == "authCancel")
    {
        if (context != null)
        {
            await _interaction.GrantConsentAsync(context, ConsentResponse.Denied);
            return Redirect(model.ReturnUrl);
        }

        return Redirect("~/");
    }

    if (button == "authOk" && ModelState.IsValid)
    {
        if (context != null)
        {
            await _events.RaiseAsync(new UserLoginSuccessEvent("provider", "userId", "subjectId", "name"));
            await HttpContext.SignInAsync("subject", "name", new AuthenticationProperties());
            return Redirect(model.ReturnUrl);
        }
    }

    return Redirect("~/");
}
0
GTHvidsten 27 Май 2019 в 17:24

2 ответа

Лучший ответ

Вариант может заключаться в том, чтобы придерживаться prompt=login для всех запросов или на основе некоторых настроек клиента, или заголовка http.

Легко заглянуть в валидатор запросов по умолчанию и выполните настройку следующим образом:

public class YourCustomAuthorizeRequestValidator:ICustomAuthorizeRequestValidator
{
  public Task ValidateAsync(CustomAuthorizeRequestValidationContext context)
  {
    var request = context.Result.ValidatedRequest;    
    if (string.IsNullOrWhiteSpace(request.Raw["prompted"]))
    {
      request.Raw.Add("prompted", "true");
      request.PromptMode = OidcConstants.PromptModes.Login;
    }
    else if (request.Subject.IsAuthenticated())
    {
      request.PromptMode = OidcConstants.PromptModes.None;
    }
    return Task.CompletedTask;
  }
}

И затем в вашем запуске Identityserver:

services.AddIdentityServer()
  .AddCustomAuthorizeRequestValidator<YourCustomAuthorizeRequestValidator>();
3
d_f 28 Май 2019 в 17:45

Вы должны быть в состоянии достичь желаемого поведения, переопределив схему cookie по умолчанию, которая AddIdentityServer() регистрируется внутри:

services.AddIdentityServer()...

services.AddAuthentication("CustomScheme")
    .AddCookie("CustomScheme", options =>
    {
        options.ExpireTimeSpan = ...;
    });

Обязательно добавьте схему переопределения после AddIdentityServer(), здесь важна последовательность из-за того, как работает ASP.Net Core DI.

0
Vidmantas Blazevicius 27 Май 2019 в 17:10