使用 RemoteAuthenticationHandler CallbackPath 与 IApplicationBuilder 路径匹配

spa*_*pan 4 c# asp.net-core-mvc asp.net-core

相关问题

问题

我有一个服务在域的特定路径下运行,例如https://www.example.com/myservicemyservice路径专用于我的服务,其他服务在同一域中具有其他路径。在启动配置中是这样设置的:

app.Map("/myservice", builder =>
{
    builder.UseStaticFiles();
    builder.UseMvcWithDefaultRoute();
});
Run Code Online (Sandbox Code Playgroud)

我正在使用一个实现自定义RemoteAuthenticationHandler. 默认情况下,回调路径会路由到/x-callback浏览器尝试访问https://www.example.com/x-callback的结果。

由于我的服务不处理没有前缀的 url,因此/myservice我得到了404。更改浏览器中的 URL 以/myservice/x-callback手动加载回调,一切正常。

我可以按照启动配置服务中的预期在启动选项中设置处理程序的回调路径。

services.AddSomething(options =>
{
    options.AddThingX((o) =>
    {
        o.CallbackPath = new PathString($"/myservice{o.CallbackPath}");
    });
});
Run Code Online (Sandbox Code Playgroud)

当我设置回调路径时,浏览器会尝试加载/myservice/x-callback. 但是,此 URL 现在返回404。看来回调处理程序的 URL 也已更改。更改浏览器中的 URL 以/myservice/myservice/x-callback按预期加载回调。

远程身份验证处理程序

这是处理程序中处理挑战并使用回调路径的代码。它将回调路径设置为登录 URL 的查询参数。

protected override Task HandleChallengeAsync(AuthenticationProperties properties)
{
    // Add options etc
    // ...
    // ...

    // This defines the login url, with a query parameter for the CallbackPath
    var loginUrl = GetLoginUrl(loginOptions);
    Response.Redirect(loginUrl);

    return Task.CompletedTask;
}

private string GetLoginUrl(MyServiceLoginOptions loginOptions)
{
    // This is where the return url is set. The return url
    // is used after login credentials are verified.
    return $"{Options.LoginPath}" +
            $"?returnUrl={UrlEncoder.Encode(Options.CallbackPath)}" +
            $"&loginOptions={UrlEncoder.Encode(_loginOptionsProtector.Protect(loginOptions))}";
}
Run Code Online (Sandbox Code Playgroud)

登录控制器

用户可以在此处提供凭据并进行验证。验证通过后,将用户重定向到回调路径。

private async Task<ActionResult> ChallengeComplete(LoginStatusRequest request, ChallengeResponse challengeResponse)
{
    // auth logic
    // ...
    // All is fine, the users credentials have been verified. Now
    // we can redirect to the CallbackPath.
    return Ok(Response.Finished(returnUri));
}
Run Code Online (Sandbox Code Playgroud)

请注意 ,我可以进行 URL 重写,但如果可能的话,我想使用“正确”/myservice路径来避免混淆,并可能导致其他服务出现问题(尽管可能性很小)。

问题

如何为回调路径添加前缀,/myservice以便我的应用程序可以处理它,而无需添加重复的前缀?

Kah*_*azi 5

MapMiddleware正在将匹配的路径添加到Request.PathBase,因此您可以在创建返回 url 时使用它

string returnUrl = Context.Request.PathBase + Options.CallbackPath;
Run Code Online (Sandbox Code Playgroud)