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

始终输入不带“的凭据”;prompt=login";在IdentityServer4中,identityserver4,openid-connect,Identityserver4,Openid Connect,这与类似,但解决方案是在/authorizeURL中使用prompt=login查询字符串,这很有效,但也允许狡猾的用户删除它。此外,鉴于我没有使用.AddOpenIdConnect()建议使用OnRedirectToIdentityProvider对我不适用 那么,我们如何强制用户始终输入凭据而不依赖查询字符串中的prompt=login 以下是我的基本标识服务器4设置: public void配置服务(IServiceCollection服务) { services.AddMvc(); v

这与类似,但解决方案是在
/authorize
URL中使用
prompt=login
查询字符串,这很有效,但也允许狡猾的用户删除它。此外,鉴于我没有使用
.AddOpenIdConnect()
建议使用
OnRedirectToIdentityProvider
对我不适用

那么,我们如何强制用户始终输入凭据而不依赖查询字符串中的
prompt=login


以下是我的基本标识服务器4设置:

public void配置服务(IServiceCollection服务)
{
services.AddMvc();
var builder=services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.getAPI())
.AddInMemoryClients(Config.GetClients());
AddDeveloperSigningCredential();
}
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
app.UseHttpsRedirection();
app.UseFileServer();
app.UseIdentityServer();
app.UseMvc();
}
其中,我的登录页面只有一个“确定”和“取消”按钮(我不关心哪个用户登录,只是验证是否正确),控制器在验证用户时执行以下操作:

公共异步任务Post(AuthenticateViewModel模型,字符串按钮)
{
var context=await\u interaction.GetAuthorizationContextAsync(model.ReturnUrl);
如果(按钮==“authCancel”)
{
if(上下文!=null)
{
wait_interaction.GrantConsentAsync(上下文、同意响应、拒绝);
返回重定向(model.ReturnUrl);
}
返回重定向(“~/”);
}
if(按钮==“authOk”&&ModelState.IsValid)
{
if(上下文!=null)
{
wait_events.RaiseAsync(新用户登录事件(“提供者”、“用户ID”、“主体ID”、“名称”));
等待HttpContext.SignInAsync(“主题”,“名称”,新的AuthenticationProperties());
返回重定向(model.ReturnUrl);
}
}
返回重定向(“~/”);
}

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

services.AddIdentityServer()...

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

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

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

查看和实施自定义很容易,如下所示:

public类YourCustomAuthorizeRequestValidator:ICustomAuthorizeRequestValidator
{
公共任务ValidateSync(CustomAuthorizationRequestValidationContext上下文)
{
var request=context.Result.ValidatedRequest;
if(string.IsNullOrWhiteSpace(request.Raw[“提示”]))
{
request.Raw.Add(“提示”、“真”);
request.PromptMode=OidcConstants.PromptModes.Login;
}
else if(request.Subject.IsAuthenticated())
{
request.PromptMode=OidcConstants.PromptModes.None;
}
返回Task.CompletedTask;
}
}
然后在Identityserver启动中:

services.AddIdentityServer()
.addCustomAuthorizationRequestValidator();

这很简单,只需覆盖默认的cookie方案,用户将始终必须输入凭据,尽管url遭到黑客攻击。听起来不错。能举个例子吗?谢谢。看起来它是基于cookie过期的。哪些值通常足够?我猜0秒太少了,用户将在
auhorize/callback
上再次注销,10秒允许快速用户在到期前重试。只需选择适合您业务问题领域的合理方法,这是我无法真正建议的。过去,我使用了几分钟的到期时间来满足类似的要求,就像您的要求一样。我尝试了这一点,我可以看到日志中出现以下消息:
CustomScheme未通过身份验证。失败消息:票证过期
,即使过期几分钟。知道为什么吗?它似乎在调用
authorize
时多次出现(可能是为了检查用户是否仍在登录),但不是在用户进行身份验证之后。不过,用许多这样的日志消息填充日志似乎有点不必要。有什么建议吗?尝试10分钟(因为时钟偏移),给cookie一些自定义名称,并检查用户登录时是否保存了正确的cookie。我尝试添加示例中的自定义
ICustomAuthorizerRequestValidator
,以及它是否应该在每个请求上强制登录以
授权
,这不太管用。我调用
authorize
,它第一次要求我登录。第二次,它不要求登录,直接进入
重定向uri
。我尝试对该条件进行注释,但在
/authorize
之后,它再也不会继续。我进入登录屏幕,单击登录,然后再次进入登录屏幕(无限重复)。您可能应该更新代码以使用
string.IsNullOrEmpty()
,而不是
。IsMissing()
,否则这似乎正是我想要的。谢谢:)
IsMissing()
只是
返回字符串的一个方便的包装器但可能是我从Identityserver内部偷来的。。。到时候会变的