How are OwinContext.Request.Path and PathBase populated?

懵懂的女人 提交于 2019-12-05 17:46:52

问题


I'm writing my own OWIN middleware for OpenID Connect authorization code flow, based on other examples in the Katana Project.

As part of this I have to construct a couple of URIs, eg a Redirect URI and a Return URL.

Other examples in Katana do this by concatenating parts from the current request, for example in CookieAuthenticationHandler

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

My question is what rules govern what ends up in the two path properties:

OwinContext.Request.Path
OwinContext.Request.PathBase

I've tried inspecting these properties as the request passes through different handlers in the pipeline below, for the request:

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

The result:

  • In the mapped handler for /login, the PathBase = "/Client/Login".
  • But when the request gets to the ApplyResponseChallengeAsync method in my QuillCodeFlowHandler on the way back out for the same request, PathBase = "/Client" and Path = "/Login".

So without knowing the "rules" for how these values are populated, then later changed, it is hard to construct URIs using them. If anyone can explain, will be much appreciated.

An extract of my config is:

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

The OWIN specification gives some explanation and Microsoft.Owin.Host.HttpListener.GetPathAndQuery method seems to be where the path variables are set initially.


回答1:


When using the construct

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

This uses

Owin.MapExtensions.Map

which constructs an instance of

Microsoft.Owin.Mapping.MapMiddleware

for the code which needs running.

The behaviour I have seen is explained in the Invoke method of this middleware:

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

Basically the code changes the Path and PathBase before it runs the delegate (await _options.Branch(environment) ), then sets these back to the original values after execution is complete.

Hence the behaviour I had seen is explained.



来源:https://stackoverflow.com/questions/25648722/how-are-owincontext-request-path-and-pathbase-populated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!