如何填充OwinContext.Request.Path和PathBase?

时间:2014-09-03 15:54:14

标签: owin katana openid-connect

我正在根据Katana项目中的其他示例为OpenID Connect授权代码流编写自己的OWIN中间件。

作为其中的一部分,我必须构建一些URI,例如重定向URI和返回URL。

Katana中的其他示例通过连接当前请求中的部分来完成此操作,例如在CookieAuthenticationHandler中

loginUri =
    Request.Scheme +
    Uri.SchemeDelimiter +
    Request.Host +
    Request.PathBase +
    Options.LoginPath +
    new QueryString(Options.ReturnUrlParameter, currentUri);

我的问题是什么规则管理两个路径属性中的最终结果:

OwinContext.Request.Path
OwinContext.Request.PathBase

我已经尝试检查这些属性,因为请求通过下面管道中的不同处理程序,请求:

"https://localhost/Client/login" // Where Client is a virtual directory in IIS

结果:

  • 在/ login的映射处理程序中,PathBase =“/ Client / Login”。
  • 当请求在返回同一请求的路上到达QuillCodeFlowHandler中的ApplyResponseChallengeAsync方法时,PathBase =“/ Client”和Path =“/ Login”。

因此,如果不知道如何填充这些值的“规则”,然后更改,则很难使用它们构造URI。如果有人能解释,将不胜感激。

我的配置摘录是:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
    LoginPath = new PathString("/Login")
});

app.UseQuillCodeFlowAuthentication(new QuillCodeFlowOptions());

app.Map("/login", map =>
{
   map.Run(async ctx =>
   {
     if (ctx.Authentication.User == null ||
     !ctx.Authentication.User.Identity.IsAuthenticated)
     {                        
       var authenticationProperties = new AuthenticationProperties();
       [...]
       ctx.Authentication.Challenge(authenticationProperties,
                                    QuillCodeFlowDefaults.AuthenticationType);  

OWIN specification给出了一些解释,Microsoft.Owin.Host.HttpListener.GetPathAndQuery方法似乎是最初设置路径变量的地方。

1 个答案:

答案 0 :(得分:5)

使用构造时

app.Map("/login", map => [...]

这使用

Owin.MapExtensions.Map

构造

的实例
Microsoft.Owin.Mapping.MapMiddleware

表示需要运行的代码。

我看到的行为在此中间件的Invoke方法中进行了解释:

public async Task Invoke(IDictionary<string, object> environment)
{
    IOwinContext context = new OwinContext(environment);

    PathString path = context.Request.Path;

    PathString remainingPath;
    if (path.StartsWithSegments(_options.PathMatch, out remainingPath))
    {
        // Update the path
        PathString pathBase = context.Request.PathBase;
        context.Request.PathBase = pathBase + _options.PathMatch;
        context.Request.Path = remainingPath;

        await _options.Branch(environment);

        context.Request.PathBase = pathBase;
        context.Request.Path = path;
    }
    else
    {
        await _next(environment);
    }
}

基本上代码在运行委托之前更改Path和PathBase (等待_options.Branch(环境)),然后在执行后将这些值设置回原始值已经完成了。

因此解释了我所看到的行为。