owin oauth webapi with a dynamic TokenEndpointPath

2019-08-03 16:10发布

问题:

I've successfully implemented oAuth using OWIN in my WebApi 2 Server with:

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions {
  TokenEndpointPath = new PathString("/api/TokenByPassword"),
  // ...
});

However, I would like the TokenEndpointPath to be dynamic as I will have multiple databases each with their own account records.

I believe I want something like:

TokenEndpointPath = new PathString("/api/{databaseid}/TokenByPassword");

I don't believe OAuthAuthorizationServerOptions supports this and even if it did - how would I get the databaseid ?

I could implement this in my own WebAPI with AttributeRouting, but then what would be the correct OWIN calls to make in that WebAPI to generate the correct BearerToken?

回答1:

I found the answer..

Even though the TokenEndpointPath is specified in the OAuthAuthorizationServerOptions, the OAuthAuthorizationServerProvider has a delegate called OnMatchEndpoint. Inside this delegate, you can access the Request.Uri.AbsolutePath of the call and if it matches your criteria, you can then call MatchesTokenEndpoint() in which case OnGrantResourceOwnerCredentials will get called where you again can gain access the the Request.Uri and pick out the {databaseid} and use the correct database to Grant access.

OWIN is very flexible, but not immediately obvious which calls to make when to do what you want when it is something not quite straightforward.



回答2:

Just to make it clearer, here is the implementation of the function MatchEndpoint of the class that extend OAuthAuthorizationServerProvider, as suggested by David Snipp :

private const string MatchTokenUrlPattern = @"^\/([\d\w]{5})\/token\/?$";
public override async Task MatchEndpoint(OAuthMatchEndpointContext context)
    {
        var url = context.Request.Uri.AbsolutePath;
        if (!string.IsNullOrEmpty(url) && url.Contains("token"))
        {
            var regexMatch = new Regex(MatchTokenUrlPattern).Match(url);
            if (regexMatch.Success)
            {
                context.MatchesTokenEndpoint();
                return;
            }
        }
        await base.MatchEndpoint(context);
    }

Be careful on what you do in there because it is called at every request.



标签: owin