c# - 添加查询字符串参数重定向至 IdP

标签 c# asp.net-core asp.net-core-mvc identityserver4 openid-connect

我正在使用 IdentityServer4 并配置了 OpenId Connect 提供程序。我想要做的是将用户名作为查询字符串的一部分传递给提供者,以便提供者预先填写用户名字段。我同时拥有 ADFS 和 Azure AD 提供程序,并且希望此功能能够同时使用。这可能吗?如果可能的话,如何实现?

ExternalControllerChallenge 方法中,我添加了我认为应该有效的内容,但它没有执行任何操作:

[HttpGet]
public async Task<IActionResult> Challenge(string provider, string returnUrl, string user)
{
    if (string.IsNullOrEmpty(returnUrl)) returnUrl = "~/";
    if (Url.IsLocalUrl(returnUrl) == false && _interaction.IsValidReturnUrl(returnUrl) == false)
    {
        throw new Exception("invalid return URL");
    }
    if (AccountOptions.WindowsAuthenticationSchemeName == provider)
    {
        return await ProcessWindowsLoginAsync(returnUrl);
    }
    else
    {
        var props = new AuthenticationProperties
        {
            RedirectUri = Url.Action(nameof(Callback)),
            Items =
            {
                { "returnUrl", returnUrl },
                { "scheme", provider },
                { "login_hint", user }
            }
        };
        return Challenge(props, provider);
    }
}

最佳答案

您可以使用 OnRedirectToIdentityProvider 实现您想要的目标OpenIdConnectEvents的属性(property)类:

Invoked before redirecting to the identity provider to authenticate. This can be used to set ProtocolMessage.State that will be persisted through the authentication process. The ProtocolMessage can also be used to add or customize parameters sent to the identity provider.

您可以通过 AddOpenIdConnect 连接到此过程。函数,在 Startup.ConfigureServices 中使用 services.AddAuthentication 时调用。以下是符合您要求的示例:

services
    .AddAuthentication(...)
    .AddOpenIdConnect(options =>
    {
        ...

        options.Events = new OpenIdConnectEvents
        {
            OnRedirectToIdentityProvider = ctx =>
            {
                if (ctx.HttpContext.Request.Query.TryGetValue("user", out var stringValues))
                    ctx.ProtocolMessage.LoginHint = stringValues[0];

                return Task.CompletedTask;
            }
        };
    });

其中大部分只是用于添加身份验证、OIDC 以及为上述事件注册事件处理程序的样板代码。最有趣的部分是:

if (ctx.HttpContext.Request.Query.TryGetValue("user", out var stringValues))
    ctx.ProtocolMessage.LoginHint = stringValues[0];

当问题中的 Challenge 操作从查询字符串参数获取 user 时,上面的代码会读出 user 查询字符串请求中的参数(可能有多个,这就是为什么我们这里有 StringValues)并将其设置为 LoginHint 属性(如果找到)。

注意:我已经用 https://demo.identityserver.io 对此进行了测试(当然,这是有效的)。

关于c# - 添加查询字符串参数重定向至 IdP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52297761/

相关文章:

asp.net - 使用 ASP.NET 5 中的默认 DI 容器一次性注册所有服务,类似于 Autofac

c# - 无法解释的变量增加

c# - WPF 中的 ValidationRule 与行为

c# - 可移植类库中的 Type.IsEnum 属性

c# - ASP.NET Core SignalR 使用 Azure AD 返回 401 Unauthorized

asp.net-web-api - 如何从 System.Web.Http.ModelBinding.IModelBinder 传递结果模型对象。绑定(bind)模型?

asp.net-core-mvc - global.json 和 src 文件夹有多重要?

c# - Guid.ToByteArray() 是跨平台的吗?

c# - SQL Server CE 回滚不会撤消删除

c# - SQL错误: Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths. Entity Framework 核心