matthewrosse / LeanOAuth

OAuth1.0a implementation for modern .NET
MIT License
1 stars 0 forks source link

Add example of calculating URL HostName on the fly #1

Open admalledd opened 3 months ago

admalledd commented 3 months ago

Some services don't know what DNS/HostName URL they live under (load balancing, DNS wildcard fun, etc etc). For these things, most URIs have to be calculated on the fly per-request. Note that while the request is often used to figure out which hostname/base-URI to use it is often that said base is validated in some way so that hostname injection isn't plausible. For example on my use case: we always know the TLD, its the sub domain wildcard. IE *.login.foo.example.com

I see in code you have as part of DI package:

            // inside a spb.AddScoped() lambda factory-method, such that new instances are got every time
            var optionsMonitor = sp.GetRequiredService<IOptionsMonitor<TOptions>>();
            var options = optionsMonitor.Get(authenticationScheme);

So I think a quick example with a subclassed OAuth10AOptions.... except, you have a new() constraint on that, and I haven't had a chance before how to puzzle out injecting something like HTTPContext.Request.Headers (or other such) scope-based helper to identify tenant-ID/settings dynamically.

matthewrosse commented 3 months ago

I'm not sure whether I understand your issue correctly. Do you mean that the request_token/access_token/user information endpoint URLs change? Like, is it sometimes https://one.login.foo.example.com/request_token and sometimes https://two.login.foo.example.com/request_token?

Could you provide an example, so we're on the same page? I'm also curious how (or if) Microsoft handles your situation in their OAuth2.0 implementation.

admalledd commented 3 months ago

Correct, that the hostname wildcard in our case is a client/platform identifier for a sort-of-multi-tenant system.

So we would have:

basically, the idea is "Something we inspect out of the HttpContext (often Request.HostName) drives which user-store/database to check with, and can change/set the auth scope/identity differently". The calling applications/tools/browsers/services don't need to care or do anything special, just use the different URL.

As for the OAuth2.0, not sure since we use a 3rd party self-hosted service to handle all that auth (Ping Federate).

Though, an rough example for an EFContext:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddDbContext<TenantEFContext>((serviceProvider, options) =>
    {
        var httpContext = serviceProvider.GetService<IHttpContextAccessor>().HttpContext;
        var tenantLocator = serviceProvider.GetService<TenantLocatorService>();
        var connection = tenantLocator.GetConnectionByHttpContext(httpContext); //magic service+method: decide from request which tenant this is. 
        options.UseSqlServer(connection);
    });