在IdentityServer4中始终输入不带“ prompt = login”的凭证

时间:2019-05-27 14:24:19

标签: identityserver4 openid-connect

这类似于IdentityServer4 Force User to re-enter credentials,但是那里的解决方案说在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("~/");
}

2 个答案:

答案 0 :(得分:1)

对于所有请求或基于某些客户端设置或http标头,可以选择坚持使用prompt=login

可以很容易地查看default request validator并实现如下所示的自定义:

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>();

答案 1 :(得分:0)

您应该能够通过覆盖AddIdentityServer()在内部注册的默认cookie方案来实现所需的行为:

services.AddIdentityServer()...

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

确保在AddIdentityServer()之后添加替代方案,由于ASP.Net Core DI的工作方式,此处的顺序很重要。